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.
**/
- init(name:name age:age)
self.name = name
self.age = age
end
self::name = name.
self::age = age.
- test(param:data _:extra)
cout put:'Received {data}, {extra}'
end
- test(param:data _:extra) | cout put:'Received {data}, {extra}'.
- name
^self.name
end
- name | ^self::name.
- age
^self.age
end
- age | ^self::age.
- ageInMonths
^self.age * 12
end
- ageInMonths | ^self::age * 12.
- setName:name
self.name = name
end
- setName:name | self::name = name.
- setAge:age
self.age = age
end
- setAge:age | self::age = age.
- setAge:age inUnit:units
match units in
#years => self.age = age,
#months => self.age = age / 12,
#days => self.age = age / 365,
_ => self.age = 0,
end
end
#years => self::age = age,
#months => self::age = age / 12,
#days => self::age = age / 365,
_ => self::age = 0,
end.
- getAgeInUnit:units
^match units in
#years => self.age,
#months => self.age / 12,
#days => self.age / 365,
#years => self::age,
#months => self::age / 12,
#days => self::age / 365,
_ => 0,
end
end
end.
/* Properties are defined using the $ symbol.
They accomplish two things:
@@ -120,16 +105,14 @@ class Person
*/
$ exampleProperty
get => self.val,
set => self.val = value
end
set => self.val = value.
/* Without the lambda synthesis, the property would look like this:
Note that this is the only time it is legal to access private fields
via `self` from a lambda. */
$ exampleProperty
get => [ ^self.val ],
set => [ :x | self.val = x ]
end
set => [ :x | self.val = x ].
/* 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
@@ -138,8 +121,7 @@ class Person
If either the `set` or `get` elements are not provided, the property
becomes read-only or write-only respectively */
$ exampleProperty2
get => 42
end
get => 42.
/* A property can also be configured to act just like a regular variable,
by setting the getter and setters to default implementations.
@@ -158,8 +140,8 @@ class Person
$ exampleProperty4 (get)
end
p1 = Person new(name:'John Doe' age:34)
p1 setAge:100 inUnit:#months
p1 = Person new(name:'John Doe' age:34).
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
weird and not recommended.
**/
p1 test(param:'Hello' :'World')
p1 test(param:'Hello' :'World').
/******************************************************************************/
i = 0
i = 0.
while i < 100 do
cout put:'Count is {i}'
cout put:'Count is {i}'.
i += 2
end
@@ -185,7 +167,7 @@ end
a lambda's parameters are *always* unlabeled, and the underscore (_) before
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
local context.
**/
q = 32
l = [ cout put:'Value of q is {q}' ] /* value of `q` is captured here */
q = 64
_ = l call /* prints 'Value of q is 32' */
q = 32.
l = [ cout put:'Value of q is {q}' ]. /* value of `q` is captured here */
q = 64.
_ = l call. /* prints 'Value of q is 32' */
/******************************************************************************/
j = 32
j = 32.
/**
expressions are terminated with a newline.
@@ -229,7 +211,7 @@ j = 32
i < j
if:[ cout put:'True!' ]
else:[ cout put:'False!' ]
else:[ cout put:'False!' ].
if i < j then
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
variable, the value of the variable is used as the index.
**/
pkg[0] = 16
pkg[0] = 16.
/* All of these accesses are equivalent */
pkg['x'] = 32
pkg.x = 32
pkg['x'] = 32.
pkg->x = 32.
index = 'x'
pkg[index] = 32
index = 'x'.
pkg[index] = 32.
/**
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 */
i = 100
i = 0x100
i = 0200
i = 0b1010101
i = 1_000_000_000
i = 100.
i = 0x100.
i = 0200.
i = 0b1010101.
i = 1_000_000_000.
/* 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
@@ -308,12 +290,12 @@ end
it can only appear on the left of an assignment, and anything
assigned to it is discarded.
*/
_ = 3 * 2
_ = 3 * 2.
/* it is mostly used with pattern-matching and destructuring. */
a = (32, 64)
(_, v) = a
a = (32, 64).
(_, v) = a.
/* v is now equal to 64 */
@@ -360,7 +342,7 @@ end
onError:[ :err |
cout put:'Unknown error occurred ({err msg})'
];
call
call.
/**
this example doesn't meet any of the conditions required for implicit
@@ -375,7 +357,7 @@ end
v = 5
squared
squared
squared
squared.
/**
below are some examples of throwing errors. when an error is thrown,
@@ -397,22 +379,22 @@ v = 5
**/
/* example 1) */
throw 'an error occurred')
throw 'an error occurred'.
/* example 2) */
throw { i => 32, s => 'error' }
throw { i => 32, s => 'error' }.
/******************************************************************************/
x = 32
/* a whole bunch of ways of doing conditionals using lambdas and messages */
[ cout put:'Hello, world!' ] if:x > 10
[ cout put:'Hello, world!' ] unless:x <= 10
[ cout put:'Hello, world!' ] if:x > 10.
[ cout put:'Hello, world!' ] unless:x <= 10.
/* and the equivalent 'fancy' syntax */
cout put:'Hello, world!' if x > 10
cout put:'Hello, world!' unless x <= 10
cout put:'Hello, world!' if x > 10.
cout put:'Hello, world!' unless x <= 10.
/**
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
setAge:2 squared squared + 4 squared multiply(by:2 add:4 + 1 * 3)
in:'mon' + 'ths'
in:'mon' + 'ths'.
(p1
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 second one uses pure message/lambda syntax.
**/
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 = { 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 ].
/**
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
doubling each of the numbers in the fist package.
**/
pkg1 = { 1, 2, 3, 4, 5 }
pkg2 = { x * 2 for x in pkg1 }
pkg2 = pkg1 map:[ :x | ^x * 2 ]
pkg1 = { 1, 2, 3, 4, 5 }.
pkg2 = { x * 2 for x in pkg1 }.
pkg2 = pkg1 map:[ :x | ^x * 2 ].
/******************************************************************************/
@@ -514,15 +496,15 @@ pkg2 = pkg1 map:[ :x | ^x * 2 ]
**/
age = Person new(name:'John Doe' age:34);
setAge:144 inUnit:TimeUnit.MONTHS;
ageInMonths
setAge:144 inUnit:#months;
ageInMonths.
-- age now has the value 144
-- the same behaviour can be achieved by using do..end
age = do
x = Person new(name:'John Doe' age:34)
x setAge:144 inUnit:TimeUnit.MONTHS
x = Person new(name:'John Doe' age:34).
x setAge:144 inUnit:#months.
x ageInMonths
end
@@ -545,17 +527,17 @@ end
**/
p1 = Person new(name:'John Doe' age:34);
setAge:100 inUnit:TimeUnit.MONTHS;
yourself
setAge:100 inUnit:#months;
yourself.
/* p1 now contains the Person object */
/* again, with do..end */
p1 = do
x = Person new(name:'John Doe' age:34)
x setAge:100 inUnit:TimeUnit.MONTHS
x = Person new(name:'John Doe' age:34).
x setAge:100 inUnit:#months.
x
end
end.
/******************************************************************************/
@@ -570,10 +552,10 @@ end
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. */
val = do
x = 3
y = 2
x = 3.
y = 2.
x * y
end
end.
/* after this statement is executed, `val` will be equal to 6. */