Contents
PonderTalk Syntax
PonderTalk is the high-level language, based on Smalltalk, that is used to control and interact with the Ponder2 SMC. Ponder2 managed objects are very similar to Smalltalk classes insofar as they can be created (in our case imported), instantiated and can be sent messages which return replies. The main difference being that Managed Object are written in Java and instances of managed Objects may be held in a remote SMC, messages are sent correctly regardless of the location of the Managed Object.
Smalltalk |
Description |
|
Managed Object |
Class |
Ponder2 Managed Objects are the equivalent of Smalltalk Classes |
Managed Objects written in Java |
Class Objects written in Smalltalk |
Managed Objects are "imported" into an SMC. The Smalltalk syntax to create new Classes has not been included in PonderTalk |
Managed Objects may be local or remote |
Class instances are always local |
It is not necessary to know whether a Managed Object is local or remote, Ponder2 is a transparent, distributed system |
The Language
PonderTalk statements are like sentences separated by a "." PonderTalk statements may either be an assignment to a temporary variable or may send a command to a Managed Object. The basic syntax is:
1 var := something.
2 managed_object command.
All commands return a value so we can have:
1 // Create a new domain, assign it to 'var1' and 'var2'
2 var1 := var2 := newdomain create.
3
4 // Put 'clock' into the new domain and call it myobj
5 var1 at: "myobj" put: clock.
6
7 // Get myobj from the new domain, using var2, and assign it to var3
8 var3 := var2 at: "myobj".
9
10 // Perform some operation on the clock object
11 var3 sendTime
Commands have three forms, one with no arguments, one with one argument and one with one or more arguments. These three forms are UnaryMessages, BinaryMessages and KeywordMessages.
UnaryMessages
Unary messages are simply commands in the form of a word sent to a Managed Object. A unary message has no associated data with it.
Examples of Unary messages include
1 // Activate a policy
2 root/policy/pol1 activate.
3
4 // Create a new domain
5 root/factory/domain create.
Binary Messages
Binary messages comprise one or more symbols with a single argument. It is entirely up to the object receiving the binary message what it does with it.
Examples of Binary messages include
1 "String1" + "String2".
2
3 // Some binary messages can look bizzare
4 // The following is the binary operation "%^&$%"
5 root/dom/myobj %^&$% root/someotherobj.
Keyword Messages
Keyword messages are more like traditional method or function calls except that all arguments are named arguments. e.g. the following adds an object to a domain, giving it the name myObj
1 /root/dom1 at: "myObj" put: newObject.
This can be read as calling the method dom1.at_put_("myObj", newObject)
Precedence
Unary messages take precedence over binary messages which take precedence over keyword messages. Assignment has the lowest precedence. If there are equal precident message types then the precidence rule is left to right. Parentheses can be used to overide presidence and to separate keywords from different commands getting mixed together. The following table show examples of statements involving a mixture of commands. Each statement is repeated with parentheses showing the same statement taking precedence into account.
As written |
Meaning |
Description |
myObj command1 command2 |
(myObj command1) command2 |
The return value of the unary message myObj command1 is sent the unary message command2 |
myObj ucmd1 + "hello" |
(myObj ucmd1) + "hello" |
The return value of the unary message myObj ucmd1 is sent the binary message + "hello" |
myObj + "hello" length |
myObj + ("hello" length) |
The unary message length is sent to the string, the result of that is sent as part of the binary message + to myObj |
myObj cmnd1 key1: arg1 key2: arg2 |
(myObj cmnd1) key1: arg1 key2: arg2 |
The result of sending cmnd1 to myObj is send the keyword message key1:key2: with the arguments arg1 and arg2 |
myObj at: "name" length put: obj |
myObj at: ("name" length) put: obj |
The result of "name" length becomes the first argument in the keyword message at:put: |
myObj + 3 * 5 |
(myObj + 3) * 5 |
Left to right if equal precidence, all binary operators are equal |
myObj at: "fred" put: newObj at: "fred" |
??? |
Seen as operation at:put:at:, probably not what is wanted but could be valid |
Special Types
In addition to managed objects being treated as PonderTalk objects and being used as arguments and receivers of messages, there are several built in object types.
Blocks
Blocks are sections of one or more statements with an optional set of arguments that may be executed later, rather like a stored procedure. Blocks take the following form:
1 [ :arg1 :arg2 | statement1. statement2 ]
Blocks are typically executed by sending them the unary message value if there are no arguments to be filled in If there are arguments than keyword messages are used, they take the form value:, value:value: or value:value:value: etc, one keyword for each argument in the block. There are other ways to execute a block but these are included in the block documentation. For example the following would print "Hello, World!"
1 a := [ root print: "Hello, World!" ].
2 a value
3
4 Hello, World!
Further Reading
Now that you have learnt the syntax, you can see the basic types that PonderTalk makes available.
