Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
complexvalues [2019/01/04 16:20] christian [Using Values] |
complexvalues [2022/03/06 08:57] (current) christian [Values] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Complex | + | ===== Values ===== |
The Values package is my base library for almost everything I do. It provides Values (as opposed to Objects) which are simple, immutable objects. Values can only be created but never modified. This allows for a functional programming style and simplyfies systems, since much less state has to be maintained. Especially I like to see all structure and details (of complex values) at a glance and the ease of creating test values. | The Values package is my base library for almost everything I do. It provides Values (as opposed to Objects) which are simple, immutable objects. Values can only be created but never modified. This allows for a functional programming style and simplyfies systems, since much less state has to be maintained. Especially I like to see all structure and details (of complex values) at a glance and the ease of creating test values. | ||
+ | Features: | ||
+ | * Values as known in the functional world: **immutable** and consisting only of values or primitive types. Values do not have an identity and are equal when their elements are equal. A Value always forms a simple tree without loops or references. Instead of mutating objects, values are copied with new elements. Values are created with a constructor taking all elements as arguments. | ||
+ | * **Literal**: | ||
+ | * **Defaults**: | ||
+ | * **Named Values**: some instances of a value class may be well known and should be use in the code instead of the generic constructor. This feature should be used with caution, since changes will break code using obsolete instances. Currently, only '' | ||
==== Motivation ==== | ==== Motivation ==== | ||
Line 38: | Line 43: | ||
</ | </ | ||
- | And you can do: | + | With it you can: |
* create a value with <code smalltalk> | * create a value with <code smalltalk> | ||
- | * ask it for its parts <code smalltalk> | + | * ask for its parts <code smalltalk> |
- | * print the instance | + | * print it as code <code smalltalk> |
+ | ' | ||
name: '' | name: '' | ||
sex: #male | sex: #male | ||
birthday: (Date d: 25 m: 6 y: 1960)' "</ | birthday: (Date d: 25 m: 6 y: 1960)' "</ | ||
* get the value from its code <code smalltalk> | * get the value from its code <code smalltalk> | ||
+ | * add fancy access methods like <code smalltalk> | ||
+ | weekdayAtBirth | ||
+ | ^self birthday weekday | ||
+ | </ | ||
Line 75: | Line 85: | ||
The variables are set all at once by an initalizing method which has all initial values as parameters. | The variables are set all at once by an initalizing method which has all initial values as parameters. | ||
The object becomes immutable after initialization and all instance variables are effectively constants. | The object becomes immutable after initialization and all instance variables are effectively constants. | ||
+ | |||
+ | The parameter names are the concatenated name and its class. This prevents name clashes, is systematic and still readable. | ||
<code smalltalk> | <code smalltalk> | ||
- | Person>> | + | Person>> |
- | name := aString. | + | name := nameString. |
- | sex := aSymbol. | + | sex := sexSymbol. |
- | birthday := aDate. | + | birthday := birthdayDate. |
self beImmutable | self beImmutable | ||
</ | </ | ||
Line 87: | Line 99: | ||
<code smalltalk> | <code smalltalk> | ||
- | Person class>> | + | Person class>> |
| inst | | | inst | | ||
inst := self new. | inst := self new. | ||
- | inst initializeName: | + | inst initializeName: |
^inst | ^inst | ||
</ | </ | ||
- | Every value class has an # | + | Every value class has an # |
<code smalltalk> | <code smalltalk> | ||
Line 110: | Line 122: | ||
< | < | ||
< | < | ||
- | < | + | < |
</ | </ | ||
=== Defaults === | === Defaults === | ||
- | The simple values above are not very interesting. But when you define defaults for some of the variables, Values become more useful | + | The simple values above are not very interesting. But when you define defaults for some of the variables, Values become more useful. Lets add a nickname to the specification: |
+ | |||
+ | <code smalltalk> | ||
+ | Person class>> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | After generating code with: | ||
+ | <code smalltalk> | ||
+ | our example responds to #nickname : | ||
+ | |||
+ | <code smalltalk> | ||
+ | Person example nickname | ||
+ | </ | ||
+ | |||
+ | and there is a new constructor available: | ||
+ | <code smalltalk> | ||
+ | Person class>> | ||
+ | </ | ||
+ | |||
+ | Now you can specify a nickname: | ||
+ | <code smalltalk> | ||
+ | Person name: ' | ||
+ | </ | ||
+ | |||
+ | If you use the same parameter as the default, it is ignored | ||
+ | <code smalltalk> | ||
+ | Person name: ' | ||
+ | </ | ||
+ | because it is equal to | ||
+ | <code smalltalk> | ||
+ | Person name: ' | ||
+ | </ | ||
==== Get it ==== | ==== Get it ==== |