Sharp Variables
blog.thejit.org
blog.thejit.org
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).
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.
(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.
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. a = [1,2,3]
=> [1, 2, 3]
a << a
=> [1, 2, 3, [...]]
a.inspect
It's not true laziness, though; it's as long as the list when you tie it to itself.