doc: add statement separators and one-line message handler support
This commit is contained in:
@@ -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. */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user