Suppose I have an object x that can accept any of the selectors s1 , s2 , ..., sn . Suppose further that the result of any of these selectors running on an object is an updated object of the same type. Then I could βchainβ these selectors (as long as they are unary messages) as I want, for example:
x s1 s2 ... sn
This will produce the result x s1 and apply the selector s2 , then apply the selector s3 to this result, etc. I would like to apply one or more of these selectors in some order for different results:
x s8 s2
In Smalltalk, I can do this if the selectors are unary messages. However, if my selectors are keyword messages, I can no longer do this. If x individually accepts the selector, s1: s2: ..., sn: then the following does not work:
x s1: a1 s2: a2 ... sn: an
There is an operator ; :
x s1: a1 ; s2: a2 ; ... ; sn: an
But using cascading: each step changes the original x on this path, and I don't want to change x in this case.
To associate keyword messages, I think I have to use the following syntax with parentheses:
(...(((x s1: a1) s2: a2) ... sn: an)
Which makes me feel like I'm programming in LISP if I have 3 or more keywrod messages. A concrete example of this might be a multidimensional array. If foo is a 3-dimensional array, and you wanted to access the object at a location 2,3,5 in the array, I think it would look like this:
(((foo at: 2) at: 3) at: 5) some_object_selectors
This is a trivial example, of course, but illustrates the case. You may have other types of embedded objects or another chain of sequential operations with objects in which you are interested in the final result.
Is there a more syntactically attractive way to do this in Smalltalk? I assume that there is no other operator, possibly a cousin of the operator ; (let's say we use & , for example), which would connect them, for example:
x s1: a1 & s2: a2 & ... & sn: an
Since I would like to apply the selectors in any or almost any desired order (for possible different results), the shape of the s1:s2:s3:... selector is too restrictive. In addition, it provides a tool that already exists in other languages, such as Ruby, where it is equivalently expressed as:
x.s1(a1).s2(a2)...sn(an)
Without a special operator, an alternative would be to pass an array of selector-argument pairs or, possibly, a lookup table for pairs of selector pairs. The lookup table requires an installation for transferring literals (it needs to be created and filled), which makes me lean towards the array, as I can simply write it as:
x { {s1. a1}. {s2. a2}. ... {sn. an} }
This is still a bit uncomfortable, and I'm not sure if it is more elegant than just using all parentheses. I am afraid that my question may be at least partially subjective, but I am interested to know what might be the best practice, and whether there is an operator that I do not know about which can help, or if someone is entertained by the Smalltalk standard body.