Does a modern Lisp really need both symbols and strings? In particular, is there any reason to have two separate types, and reader syntax for both?
Traditionally strings have been mutable (even literals!), and symbols have had properties other than their names, so it has been easy to justify having separate types. But a modern Lisp may reasonably have immutable strings, and remove all extraneous features from symbols, so the only difference is whether they're interned. That's not worth making a distinction of type.
There's a practical problem: when they appear in source code, "foo"
is written for its characters and foo
for its identity. So "foo"
needs to be self-evaluating, unlike foo
. Does this mean they have to be different types?
No: "
can be a reader macro, so "ice cream"
reads as '|ice cream|
. That interferes with its other uses, like docstrings, but not badly. (And it's about time we replaced docstrings with something a little more flexible, anyway.) Maclisp used '|explicit quoted symbols|
wherever strings were needed, and it was annoying to read, so we do need the abbreviation.
While we're messing with "
, let's make it read as something distinctive: (doublequote foo)
instead of (quote foo)
. This has two good properties which every reader macro should have. First, it's reversible, so read
and write
can remain inverses as far as possible. Second, it's a simple abbreviation, so it preserves the transparency of syntax, and avoids entangling the reader with other parts of the language. It's also more flexible, because we can change its meaning by redefining doublequote
. This makes it easy to add features like string interpolation, where "Hello, $scope!"
expands to something like (format nil '|Hello, ~A!| scope)
. And this can all be done in user code, without complicating the language kernel.
I think I won't miss strings.
I always think of strings as more lightweight than symbols: they get GCed properly, they don't come with p-lists or packages, etc.
ReplyDelete