From de1aa54fc0199e260154132efef6edc4b89e9b6b Mon Sep 17 00:00:00 2001 From: Max Wash Date: Tue, 5 Nov 2024 13:21:25 +0000 Subject: [PATCH] doc: re-design property syntax --- doc/sample/Person.im | 77 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/doc/sample/Person.im b/doc/sample/Person.im index 9c0b22d..3639ec9 100755 --- a/doc/sample/Person.im +++ b/doc/sample/Person.im @@ -94,11 +94,68 @@ class Person end end + /* Properties are defined using the $ symbol. + They accomplish two things: + 1) they make it easy to synthesize the -get: and -put:at: messages + that the package dot syntax requires. + 2) they allow you to implement getters and setters that are used + when someone attempts to access your object's data. + + The contents of a property looks a bit like a package, but it has a few + special rules: + 1) every value must have an associated key; and + 2) the only keys that can be used are `get` and `set` (this is the only + instance where reserved keywords can be used as keys in a package). + + In this case, the getter has been set to a variable. To facilitate this + functionality, the compiler converts this to a lambda of the form + [ ^self.val ] + that will be evaluated when the getter is invoked + + Similarly, the compiler synthesizes a lambda for the setter as well. + Here, the expression + self.val = value + is converted to the lambda + [ :x | self.val = x ] + */ $ exampleProperty - - get - ^42 - end + get => self.val, + set => self.val = value end + + /* 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 + + /* 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 returned. + + If either the `set` or `get` elements are not provided, the property + becomes read-only or write-only respectively */ + $ exampleProperty2 + get => 42 + end + + /* A property can also be configured to act just like a regular variable, + by setting the getter and setters to default implementations. + + The default getter will return the value of a private member variable + named by prepending two underscores to the property name + (__exampleProperty3 in this case). + + Similarly, the default setter will set the value of a private member + variable named by prepending two underscores to the property name + (__exampleProperty3 in this case) to the value provided to the setter. */ + $ exampleProperty3 (get, set) + + /* Just like in the earlier examples, either `get` or `set` can be omitted + to create a write-only or read-only property respectively */ + $ exampleProperty4 (get) end p1 = Person new(name:'John Doe' age:34) @@ -180,21 +237,21 @@ end /******************************************************************************/ -package = {} +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. **/ -package[0] = 16 +pkg[0] = 16 /* All of these accesses are equivalent */ -package['x'] = 32 -package.x = 32 +pkg['x'] = 32 +pkg.x = 32 index = 'x' -package[index] = 32 +pkg[index] = 32 /** this syntax, and the pkg.* instructions that it translates to, is @@ -238,8 +295,8 @@ end /** any object can be the target of a for-loop, as long as it meets one of the following criteria: - a) is an Iterator object-- or - b) implements the Iterator protocol-- or + a) is an Iterator object; or + b) implements the Iterator protocol; or c) understands the -iterator message, and returns an object that itself conforms to a) or b) **/