Syntax for a symbol literal
Posted: November 19th, 2010 | Author: Mars | Filed under: Syntax | 6 Comments »Symbols are a kind of atomic datatype which can be used to identify things within a program. You can think of them as a unique-ID. The Radian compiler generates symbols internally as part of the object structure, using them as keys in the member index; member access on an object then uses the same symbol to look up the method.
Examples of symbol literals in other languages – these are the only examples I know about, as most languages don’t use symbols:
- Ruby:
:foo - Scheme:
'foo - Clojure:
:foo - Scala:
'foo
I’m not happy with either of these: the apostrophe feels too much like an unbalanced single-quote, and the colon already has two other meanings in the Radian syntax. Using it to begin a symbol would not introduce ambiguity, but I am concerned that reusing the same character in too many different situations would confuse people.
Suggest whatever you use should be thin/small. Just an aesthetic consideration, but something like #symbol is just ugly. I like the colon because it doesn’t distract from looking like just a word, if you see what I mean.
|symbol might be okay if you aren’t using | for anything
I still think the colon works best.
Single quote is used for a subclass of symbol literals in lisp and scheme, but there are symbols which cannot be quoted that way — symbols containing spaces, for example. For those the usual syntax is to quote with vertical bars, as in |Foo Bar|.
I’ve got a modified scheme that I’ve been playing with, and in it, symbol literals may be in any one of three forms: preceded by a single quote, delimited by vertical bars, or followed by a colon.
The last kind works quite well, as it is a nod to forms when used as keyword arguments, something like,
(sort L comparator: >)
Btw, the single quote usage is a little weird at first, but becomes natural after not too very long.
I think I’ll start with the Ruby-style colon and see how it feels. If it looks too confusing I can always change it, since there’s no big installed base of Radian code yet…
The ASCII chars I haven’t assigned yet are
@ $ % | ~ ; \ `. The single-quote is used as an alternate form of string literal, as in JavaScript.Trailing colons are a neat idea – it does read well! It would conflict with the map member syntax, though, which I’ve imagined someday using for named arguments too:
map = {foo: bar, baz: quux}Of course in this case the colon is technically a separate token following the identifiers
fooandbar. I guess this works better in a Scheme like language as list elements are only separated by whitespace anyway.The other major usage of colons in Radian is at the end of every block-beginning statement. This is technically unnecessary since the compiler can always tell whether you are beginning a line anyway, but I like the way it looks, and I like the way it suggests that whatever follows is related to the line you’re looking at. It gets a bit clunky with the new question-mark identifiers, though:
and thus I’ve been toying with the idea of dropping it.
Is there any difference between an immutable string and a symbol?
There is an obscure lisp variant, Picolisp, that strives to be very, very simple. To that end, it conflates a few things that are separate in other languages, among them, strings and symbols.
Just for what it’s worth, and I’m not suggesting you use it, Objective-C uses @selector(foo).
There is supposed to be a difference, yes. My thinking is that symbols represent things within the world of the program, whereas strings are data that the program works on, to be passed in and out.
This also lets me conflate the object protocol and the indexed container protocol. Both are unary functions: the object function accepts a symbol, which identifies the method you want to retrieve, while the container function accepts a key, which identifies the value you want to retrieve. These are such similar operations that I could not resist overlaying them; doing so also means you can build your own objects if the built-in structures don’t suit you.
The difference between strings and symbols therefore lets me distinguish between the operation “look up the value associated with the key ‘foo’” and “look up the method associated with identifier :foo”.
Thanks for pointing that out, Joe: yes, I think Obj-C selectors are very much like what I’m trying to do here.