PonderTalk is Ponder2's Object Language for configuration and control of the Ponder2 system. Ponder2 has Managed Objects and supports the sending of messages to those objects. This language is a stripped down version of the Smalltalk syntax which has already done the hard work of designing a language for just such a job.
A PonderTalk statement generally comprises a reference to a Managed Object followed by zero, one or more messages to be sent to it. Messages may be simple commands or may contain data to be processed. All message interactions return a result that may be used later on. Ponder2 statements are separated by a full-stop (period) character, like sentences. The final statement does not need one.
Managed objects are referred to by name using the domain hierarchy with the word root denoting the top-most domain.
The first line in the example below simply returns the object itself and is often used this way as a message argument.
1 object. 2 object message. 3 object message
Messages may be sent to the result of a previous message interaction according to precedence rules given below. Parentheses may also be used to give explicit precedence. The following two statements are synonymous, message2 is sent to the object returned by sending message1 to object:
1 object message1 message2. 2 (object message1) message2
Many messages may be sent to the same object by cascading them; cascaded messages are separated by a semi-colon. Here we see an object receiving three messages, one after another. The results of the first two messages are discarded, the whole statement returns the result of the last message message3. The following lines are synonymous:
1 object message1; message2; message3 2 object message1. object message2. object message3
Temporary variables may be created on the fly and may hold the result of a statement. They may be used in place of an object later on.
1 temp := root/object. 2 result := temp message. 3 temp another_message
There are three types of messages that can be sent to an object, in all cases the object is mentioned first followed by the message to be sent. Some messages take arguments, arguments are actually statements in their own right and can be quite complex but they mainly comprise other objects and basic types such as strings, numbers or booleans. Other objects will either be named using the domain hierarchy or may be the result of a previous message interaction. Basic types may also be the result of a message interaction or may simply be a "quoted string," a written number or true or false.
These messages are single word commands that the object is expected to recognise, they have no arguments and hence carry no additional data e.g. the following example would return a list of the contents of a domain and then activate a policy. (The list would be discarded because it is not used anywhere.)
1 root/mydomain list. 2 root/policies/mypolicy activate
Binary messages are generally special characters like "+" and ">>" etc. followed by a single data value. Again, the Managed Object is expected to recognise and understand the message. e.g. the following hypothetical statement could add all the objects in the policy domain to mydomain. Mydomain would receive the "+" message with the policy domain as the argument and it would take the appropriate action.
1 root/mydomain + root/policy
Keyword messages are much more like other programming language function calls with one or more arguments, the main difference being that each argument is always named in the call. Each keyword may denote the role of the argument.
The following is used to add a Managed Object to a domain. The Managed Object can now be referred to as either root/mydomain/myobject or root/newobj/someobj.
1 root/mydomain add: "myobject" obj: root/newobj/someobj
The functions invoked by keyword messages are referred to by concatenating the names of all the arguments, the above is called message add:obj:. This is an important thing to know when writing your own Managed Objects in Java.
As mentioned above, arguments may be the result of another message interaction. Here is how a new domain is created and added into the hierarchy. Keyword arguments are often laid out as below for clarity.
1 root add: "mynewdomain" 2 obj: root/template/domain create
The above code performs the following actions, in order:
A new domain is created by sending a create unary message to the domain template.
The result of that call, the new domain, is handed to the root domain as the obj: argument in the add:obj: keyword message.
This gives us a new domain called root/mynewdomain.
Note, it is important to put the quotes to denote a string in the first argument otherwise it would be taken as a managed object and would cause an error, either because the object could not be found or if it were, when the domain receiving the message finds that it is not a string.
Why were things done in this order? Why was the create message sent first? This brings us to message precedence.
The above example works because of the precedence given to messages. Normally everything proceeds left to right, however if there is a mixture of message types within a statement the precedence rules take over. Unary messages are performed first, followed by binary messages followed by keyword messages. If any other precedence is required then parentheses must be used in the normal fashion.
Following on from the above example. If we wanted to put the domain template into another domain and then use it to create a new domain we would have to do one of the following:
1 root add: mydomaintemplate obj: root/template/domain. 2 root/mydomaintemplate create
Using the fact that a domain add:obj: message returns the Managed Object just added, we can do:
1 (root add: mydomaintemplate obj: root/template/domain) create
Of course, in the above two examples we have just lost track of the new domain that was returned because we didn't put it anywhere.
More information about PonderTalk can be found in: