Yeah, Smalltalk also works this way...mostly.
3 negated + 2 negated.
Alas, as with the post, this also breaks down when you have more than 2 arguments (or in Smalltalk parlance, 1 argument in addition to the message receiver), as those are handled by keyword arguments and you can't tell where the keywords for one message stop and the ones for the next one start. Let's say we have some nested arrays, which are accessed with at: in Smalltalk:
array at:4 at:2 at:1.
Alas, that doesn't get interpreted as 3 messages, but as the single message at:at:at:. As it kind of has to be as there is no way to disambiguate. Surprisingly, Smalltalk
does have a way to chain messages and thus separate the keywords, the semicolon:
array at:4;
at:2;
at:1.
Alas, this sends the subsequent messages to the original receiver, so it is equivalent to:
array at:4.
array at:2.
array at:1.
(And so this example doesn't actually make sense, it's just a syntax example). So what you have to do is add parens:
((array at:4) at:2) at:1.
Hmm, not nice. For Objective-S (
https://objective.st), I introduced the pipe for message chaining:
array at:4 | at:2 | at:1.
One way of looking at this is as a syntactic device that allows left-to-right typing without backtracking, which it is. And that is both nice to write and quite readable, IMNSHO.
A second way of looking at it is as a version of the pipe/filter architectural style, with each message expression being a filter, the results from the filter on the left piped into the filter on the right as the receiver. This is a little bit like |> in some FP languages. But really only a little bit, because in Objective-S this is not the whole story, but just a way of integrating messaging into the way the pipe/filter architectural style is supported at the language level.