archives

Implicitness in Syntaxes

In Self and Ruby, to name two examples, procedure call can be implicit. In an expression context, a naked identifer, such as "foo", gets interpreted as a procedure call to "self" or "this" or some such implicit context. So, "foo" can mean "self.foo".

In Mozart/Oz (whichever of those is the language), the naked identifier "foo" implicitly quotes itself. So, in Oz, "foo" can mean what "'foo" means in Lisp, "#foo" means in Smalltalk, and ":foo" means in Ruby, namely, the symbol "foo" itself.

If a programming language syntax chooser chooses to make any meaning implicit in the syntax, e. g., procedure call or quoting, she has expended a lot of syntactic capital in one go. The decision to make one meaning implicit likely excludes the possibility of making some other meaning implicit, and it may turn out that the second assignment of meaning would have been more valuable to programmers. For example, "foo" cannot both mean 'foo and self.foo.

Would readers care to express a feeling about what is the most valuable place to expend the opportunity of assiging implicit meaning in a programming language syntax? Is Oz what to copy, or Self, or something else?

Maybe in the early stages of inventing a language, the designers should reserve the assignment of meaning of naked identifiers as a future decision to be carried out _after_ there is a body of working, useful code. Such a body could then be studied to determine which assignment of implicit meaning would have produced more economy (of keystrokes) as an aid to expressing the programs that exist by then.

But in that case, procedure call, or message passing, or both, whatever operation or meaning like that is most relevant to the semantics of the programming language under construction, still needs to have as economic and tasty a syntax as possible. So, if you think procedure call (or message passing) should be given an explicit syntax, what syntax would you favor? In Oz, for example, the procedure reference and the argument are enclosed in curly braces.

The semantic context in which the question of implicitness in syntax applies for me, is of a language in which it should be common and easy to pass messages by asserting their membership in bags. A concurrent constraint language along the lines of Janus and ToonTalk. A logical variable will be splittable into two kinds of reference, an asker and a teller, representing, respectively, the right to query the variable and the right to tell constraints on the variable.

I'll give an example of what should be easy. In exposing the example to you, I'll follow the Oz convention that symbols in caps represent plumbing and symbols in lowercase represent themselves.

Then we could be in the middle of a procedure definition where one of the parameters in the procedure is some teller given by the plumbing symbol A. The value of A at runtime will be a teller for a bag, the teller having been passed as an argument to the procedure we're writing. Then it should be easy in the defintion of the procedure to write multiple assertions that certain messages belong to the bag. I don't know whether the symbol A should be repeated for each of these, which would amount to an admission that A isn't referentially transparent, or whether there should be a syntax saying A is the union of A', A'', and so on, and we have A', A'', and so on, appearing where we talk about sending our messages into A. But what's more important, is I would like an economical syntax to express a meaning like B := {A foo bar: 2 bletch: 3} where we're sending a message into A consisting of a record with 'foo the verb (just a symbol that is going to be interpreted by whoever is consuming A), 'bar:bletch: the description of two of the parameters or arguments being passed, 2 and 3 the values being passed associated to the keywords 'bar: and 'bletch: respectively, and another argument, the teller for the variable that B is the asker for. The reason for the syntax to treat B differently than 2 where 2 is being passed as the argument with keyword 'bar:, is that it's nice to be able to nest expressions that we think of as returning values. Plumbing can take fewer keystrokes if we don't have to name all the pipes.