So a "sharp variable" is just a particular syntax to represent a reference? Is anyone else somewhat unimpressed by this? I mean, sure, it's kind of helpful for readability in the printout, and it's kind of nice to be able to one-line a recursive data structure. Just about any reasonably clear syntax will work for the former; there's no reason that the programmer would need to know about it before encountering it.
The latter is mostly useful in a lazy evaluation context; in other situations, you're only rarely creating recursive data structures in the first place (circular linked lists are the most obvious case).
I'm also struggling to see the big benefit. I guess if you are allowed multiple sharp variable references -- as apparently Mozilla's Javascript allows -- you can construct a directed graph in a single statement, including cycles. I don't see that being very useful outside of entering test cases, though.
Graphs are the new hashtable - this is a great feature. Much of the interesting things being done now are done with giant graph structures.
BTW, it's so lame that PLT Scheme is going in the opposite direction. They had the same excellent notation for a long time, but now since they forbid list mutation* they are useless.
(* Yes, I know you can explicitly use mutable lists, but they don't work with the huge list library, for example SRFI-1, and there's no literal syntax for them, so it's like using lists in a language that doesn't like lists. Useless.)
Actually, I wonder if there's a better syntax for graph literals than this? That would be valuable.
I've seen them used to create inline infinite lists:
(loop for loop-this in '#1=(:a :b :c . #1#)
for just-once in '(1 2 3 4 5 6 7)
do (format t "~S => ~S~%" just-once loop-this))
=>
1 => :A
2 => :B
3 => :C
4 => :A
5 => :B
6 => :C
7 => :A
NIL
This encapsulates the "loop over this list forever" at its definition, instead of making me use an array and using length/modulo where it's used. There are of course many other solutions, but this one is both short and perfectly describes what I want.
Many Lisp library functions take lists as inputs (no kidding!), so this is a very efficient alternative to actually creating a repetitive list. (Pythoners: think itertools.cycle).
Also, any time you want to build a simple-but-not-trivial graph inline (great for unit testing), these come in handy.
There must not be a space between the "#1" and the "=" - it behaves as one token, "#1=". Otherwise you get an "Illegal Character" error.
Playing with it in Firefox's error console (is there an easier way?), it seems general. e.g. this works:
var myArray = [1, 2, #1= [1,2,#1#]]; myArray.toSource();
The sharp variables seem to work as if you generated them as incrementing labels. Hence, the references must be back-references not forward-references (so you can say "[1, #1= [2, 3], #1#]", but not "[1, #1#, #1= [2, 3]]"). And they must be numeric ("[1, #a= [2, 3], #a#]" is out). And their naming becomes the order they are needed in (so "#2= [#1= [#2#], #1#]" becomes "#1=[#2=[#1#], #2#]"). Reminiscent of regex backreferences.
I was hoping this was further evidence of javascripts roots as a lisp. But it seems like it is spider-monkey-centric and thus not some throwback to the original spec/implementation. Still cool!
Sharp variables don't seem particularly useful, but I didn't know about .toSource() in Firefox before I read this article, and that does sound like it could be useful.
The latter is mostly useful in a lazy evaluation context; in other situations, you're only rarely creating recursive data structures in the first place (circular linked lists are the most obvious case).