doc: add statement separators and one-line message handler support

This commit is contained in:
2024-11-08 18:53:19 +00:00
parent 631b19e051
commit 0603b2f52a

View File

@@ -48,51 +48,36 @@ class Person
compatibility with lambdas. compatibility with lambdas.
**/ **/
- init(name:name age:age) - init(name:name age:age)
self.name = name self::name = name.
self.age = age self::age = age.
end
- test(param:data _:extra) - test(param:data _:extra) | cout put:'Received {data}, {extra}'.
cout put:'Received {data}, {extra}'
end
- name - name | ^self::name.
^self.name
end
- age - age | ^self::age.
^self.age
end
- ageInMonths - ageInMonths | ^self::age * 12.
^self.age * 12
end
- setName:name - setName:name | self::name = name.
self.name = name
end
- setAge:age - setAge:age | self::age = age.
self.age = age
end
- setAge:age inUnit:units - setAge:age inUnit:units
match units in match units in
#years => self.age = age, #years => self::age = age,
#months => self.age = age / 12, #months => self::age = age / 12,
#days => self.age = age / 365, #days => self::age = age / 365,
_ => self.age = 0, _ => self::age = 0,
end end.
end
- getAgeInUnit:units - getAgeInUnit:units
^match units in ^match units in
#years => self.age, #years => self::age,
#months => self.age / 12, #months => self::age / 12,
#days => self.age / 365, #days => self::age / 365,
_ => 0, _ => 0,
end end.
end
/* Properties are defined using the $ symbol. /* Properties are defined using the $ symbol.
They accomplish two things: They accomplish two things:
@@ -120,16 +105,14 @@ class Person
*/ */
$ exampleProperty $ exampleProperty
get => self.val, get => self.val,
set => self.val = value set => self.val = value.
end
/* Without the lambda synthesis, the property would look like this: /* Without the lambda synthesis, the property would look like this:
Note that this is the only time it is legal to access private fields Note that this is the only time it is legal to access private fields
via `self` from a lambda. */ via `self` from a lambda. */
$ exampleProperty $ exampleProperty
get => [ ^self.val ], get => [ ^self.val ],
set => [ :x | self.val = x ] set => [ :x | self.val = x ].
end
/* The `get` element of a property doesn't have to be a lambda, it can /* The `get` element of a property doesn't have to be a lambda, it can
be any value. When the property is accessed, the value provided will be any value. When the property is accessed, the value provided will
@@ -138,8 +121,7 @@ class Person
If either the `set` or `get` elements are not provided, the property If either the `set` or `get` elements are not provided, the property
becomes read-only or write-only respectively */ becomes read-only or write-only respectively */
$ exampleProperty2 $ exampleProperty2
get => 42 get => 42.
end
/* A property can also be configured to act just like a regular variable, /* A property can also be configured to act just like a regular variable,
by setting the getter and setters to default implementations. by setting the getter and setters to default implementations.
@@ -158,8 +140,8 @@ class Person
$ exampleProperty4 (get) $ exampleProperty4 (get)
end end
p1 = Person new(name:'John Doe' age:34) p1 = Person new(name:'John Doe' age:34).
p1 setAge:100 inUnit:#months p1 setAge:100 inUnit:#months.
/** /**
@@ -167,13 +149,13 @@ p1 setAge:100 inUnit:#months
still required. this is part of the reason why unlabeled parameters are still required. this is part of the reason why unlabeled parameters are
weird and not recommended. weird and not recommended.
**/ **/
p1 test(param:'Hello' :'World') p1 test(param:'Hello' :'World').
/******************************************************************************/ /******************************************************************************/
i = 0 i = 0.
while i < 100 do while i < 100 do
cout put:'Count is {i}' cout put:'Count is {i}'.
i += 2 i += 2
end end
@@ -185,7 +167,7 @@ end
a lambda's parameters are *always* unlabeled, and the underscore (_) before a lambda's parameters are *always* unlabeled, and the underscore (_) before
the label colon (:) is unnecessary. the label colon (:) is unnecessary.
**/ **/
0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ] 0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ].
/******************************************************************************/ /******************************************************************************/
@@ -206,14 +188,14 @@ end
safe for a method to return a lambda that references variables in its safe for a method to return a lambda that references variables in its
local context. local context.
**/ **/
q = 32 q = 32.
l = [ cout put:'Value of q is {q}' ] /* value of `q` is captured here */ l = [ cout put:'Value of q is {q}' ]. /* value of `q` is captured here */
q = 64 q = 64.
_ = l call /* prints 'Value of q is 32' */ _ = l call. /* prints 'Value of q is 32' */
/******************************************************************************/ /******************************************************************************/
j = 32 j = 32.
/** /**
expressions are terminated with a newline. expressions are terminated with a newline.
@@ -229,7 +211,7 @@ j = 32
i < j i < j
if:[ cout put:'True!' ] if:[ cout put:'True!' ]
else:[ cout put:'False!' ] else:[ cout put:'False!' ].
if i < j then if i < j then
cout put:'True!' cout put:'True!'
@@ -237,21 +219,21 @@ end
/******************************************************************************/ /******************************************************************************/
pkg = {} pkg = {}.
/** /**
Packages can be indexed via integer or string. If a package is index with a Packages can be indexed via integer or string. If a package is index with a
variable, the value of the variable is used as the index. variable, the value of the variable is used as the index.
**/ **/
pkg[0] = 16 pkg[0] = 16.
/* All of these accesses are equivalent */ /* All of these accesses are equivalent */
pkg['x'] = 32 pkg['x'] = 32.
pkg.x = 32 pkg->x = 32.
index = 'x' index = 'x'.
pkg[index] = 32 pkg[index] = 32.
/** /**
this syntax, and the pkg.* instructions that it translates to, is this syntax, and the pkg.* instructions that it translates to, is
@@ -270,15 +252,15 @@ pkg[index] = 32
/******************************************************************************/ /******************************************************************************/
/* integer constants can be written in all sorts of interesting formats */ /* integer constants can be written in all sorts of interesting formats */
i = 100 i = 100.
i = 0x100 i = 0x100.
i = 0200 i = 0200.
i = 0b1010101 i = 0b1010101.
i = 1_000_000_000 i = 1_000_000_000.
/* tuples can be used to create a set of values */ /* tuples can be used to create a set of values */
tuple = (32, 'a string') tuple = (32, 'a string').
/** /**
they are similar to packages, except they only support consecutive integer they are similar to packages, except they only support consecutive integer
@@ -308,12 +290,12 @@ end
it can only appear on the left of an assignment, and anything it can only appear on the left of an assignment, and anything
assigned to it is discarded. assigned to it is discarded.
*/ */
_ = 3 * 2 _ = 3 * 2.
/* it is mostly used with pattern-matching and destructuring. */ /* it is mostly used with pattern-matching and destructuring. */
a = (32, 64) a = (32, 64).
(_, v) = a (_, v) = a.
/* v is now equal to 64 */ /* v is now equal to 64 */
@@ -360,7 +342,7 @@ end
onError:[ :err | onError:[ :err |
cout put:'Unknown error occurred ({err msg})' cout put:'Unknown error occurred ({err msg})'
]; ];
call call.
/** /**
this example doesn't meet any of the conditions required for implicit this example doesn't meet any of the conditions required for implicit
@@ -375,7 +357,7 @@ end
v = 5 v = 5
squared squared
squared squared
squared squared.
/** /**
below are some examples of throwing errors. when an error is thrown, below are some examples of throwing errors. when an error is thrown,
@@ -397,22 +379,22 @@ v = 5
**/ **/
/* example 1) */ /* example 1) */
throw 'an error occurred') throw 'an error occurred'.
/* example 2) */ /* example 2) */
throw { i => 32, s => 'error' } throw { i => 32, s => 'error' }.
/******************************************************************************/ /******************************************************************************/
x = 32 x = 32
/* a whole bunch of ways of doing conditionals using lambdas and messages */ /* a whole bunch of ways of doing conditionals using lambdas and messages */
[ cout put:'Hello, world!' ] if:x > 10 [ cout put:'Hello, world!' ] if:x > 10.
[ cout put:'Hello, world!' ] unless:x <= 10 [ cout put:'Hello, world!' ] unless:x <= 10.
/* and the equivalent 'fancy' syntax */ /* and the equivalent 'fancy' syntax */
cout put:'Hello, world!' if x > 10 cout put:'Hello, world!' if x > 10.
cout put:'Hello, world!' unless x <= 10 cout put:'Hello, world!' unless x <= 10.
/** /**
NOTE that keywords (if, end, try, and so on) can still be used as message NOTE that keywords (if, end, try, and so on) can still be used as message
@@ -457,10 +439,10 @@ cout put:'Hello, world!' unless x <= 10
p1 p1
setAge:2 squared squared + 4 squared multiply(by:2 add:4 + 1 * 3) setAge:2 squared squared + 4 squared multiply(by:2 add:4 + 1 * 3)
in:'mon' + 'ths' in:'mon' + 'ths'.
(p1 (p1
setAge:(((2 squared) squared) + ((4 squared) multiply(by:2 add:(4 + (1 * 3))))) setAge:(((2 squared) squared) + ((4 squared) multiply(by:2 add:(4 + (1 * 3)))))
in:('mon' + 'ths')) in:('mon' + 'ths')).
/******************************************************************************/ /******************************************************************************/
@@ -473,8 +455,8 @@ p1
the first one uses fancy list/package comprehension syntax. the first one uses fancy list/package comprehension syntax.
the second one uses pure message/lambda syntax. the second one uses pure message/lambda syntax.
**/ **/
data = { x + 1 for x in 0 to:100 if (x % 2) == 0 } data = { x + 1 for x in 0 to:100 if (x % 2) == 0 }.
data = (0 to: 100) select:[ :x | ^(x % 2) == 0 ] collect:[ :x | ^x + 1 ] data = (0 to: 100) select:[ :x | ^(x % 2) == 0 ] collect:[ :x | ^x + 1 ].
/** /**
for a package comprehension that follows this template: for a package comprehension that follows this template:
@@ -501,9 +483,9 @@ data = (0 to: 100) select:[ :x | ^(x % 2) == 0 ] collect:[ :x | ^x + 1 ]
collection literal, and then uses -map: to create a second package by collection literal, and then uses -map: to create a second package by
doubling each of the numbers in the fist package. doubling each of the numbers in the fist package.
**/ **/
pkg1 = { 1, 2, 3, 4, 5 } pkg1 = { 1, 2, 3, 4, 5 }.
pkg2 = { x * 2 for x in pkg1 } pkg2 = { x * 2 for x in pkg1 }.
pkg2 = pkg1 map:[ :x | ^x * 2 ] pkg2 = pkg1 map:[ :x | ^x * 2 ].
/******************************************************************************/ /******************************************************************************/
@@ -514,15 +496,15 @@ pkg2 = pkg1 map:[ :x | ^x * 2 ]
**/ **/
age = Person new(name:'John Doe' age:34); age = Person new(name:'John Doe' age:34);
setAge:144 inUnit:TimeUnit.MONTHS; setAge:144 inUnit:#months;
ageInMonths ageInMonths.
-- age now has the value 144 -- age now has the value 144
-- the same behaviour can be achieved by using do..end -- the same behaviour can be achieved by using do..end
age = do age = do
x = Person new(name:'John Doe' age:34) x = Person new(name:'John Doe' age:34).
x setAge:144 inUnit:TimeUnit.MONTHS x setAge:144 inUnit:#months.
x ageInMonths x ageInMonths
end end
@@ -545,17 +527,17 @@ end
**/ **/
p1 = Person new(name:'John Doe' age:34); p1 = Person new(name:'John Doe' age:34);
setAge:100 inUnit:TimeUnit.MONTHS; setAge:100 inUnit:#months;
yourself yourself.
/* p1 now contains the Person object */ /* p1 now contains the Person object */
/* again, with do..end */ /* again, with do..end */
p1 = do p1 = do
x = Person new(name:'John Doe' age:34) x = Person new(name:'John Doe' age:34).
x setAge:100 inUnit:TimeUnit.MONTHS x setAge:100 inUnit:#months.
x x
end end.
/******************************************************************************/ /******************************************************************************/
@@ -570,10 +552,10 @@ end
the block as a whole evaluates to. also, the result of the last expression the block as a whole evaluates to. also, the result of the last expression
evaluated in a block will be taken as its overall value. */ evaluated in a block will be taken as its overall value. */
val = do val = do
x = 3 x = 3.
y = 2 y = 2.
x * y x * y
end end.
/* after this statement is executed, `val` will be equal to 6. */ /* after this statement is executed, `val` will be equal to 6. */