Sharp Variables

Posted in: javascript
I was looking for some way to easily create, read, manipulate and print cyclic or recursive data structures in some programming languages, and got to the cool concept of sharp variables.

Manipulating Recursive Structures in Python

A straightforward way of defining a recursive structure is to first assign a base (non-recursive) structure to a variable, and then alter or extend that variable with a recursive expression. For example, in Python you can write:
my_rec_var = [1, 2, 3]
my_rec_var.append(my_rec_var)
That code will create a recursive data structure: [1, 2, 3, [1, 2, 3, [...]]], or a = [1, 2, 3, a]. Actually, Python's print function lets you print a representation of a recursive structure without recursing indefinitely:
>>> print my_rec_var
[1, 2, 3, [...]]
Python's pickle module lets you dump a recursive data structure into a file. You can also read that serialized structure from the file:
import pickle

#dump it to file
output = open("out.pkl", "wb")
pickle.dump(my_rec_var, output)
However, there's no literal way of creating, reading or modifying that structure:
>>> my_rec_var = [1, 2, 3, [...]]
 ERROR

Manipulating Recursive Structures in Lisp

For manipulating/printing recursive data structures in Common Lisp we first assign T to the global variable *print-circle*
(setq *print-circle* T)
We can define a recursive structure just as we did with Python, by defining some base structure and then modifying the structure to be recursive:
(defvar *my-rec-var* (list 1 2 3 _))
;Replace the underscore placeholder with a self-reference
(setf (fourth *my-rec-var*) *my-rec-var*)
The final structure is represented with sharp variables:
>>> (print *my-rec-var*)
#1=(1 2 3 #1#)
This is just as the "Mathematical" definition we gave above: a = [1, 2, 3, a]. What's interesting about this "serialization format" is that expressions involving sharp variables are truly expressions: these "objects" can be read and manipulated just like any other structure:
>>> (defvar *another-rec-var* ‘#1=(1 2 3 #1#))
#1=(1 2 3 #1#)

>>> (fourth ‘#1=(1 2 3 #1#))
#1=(1 2 3 #1#)

>>> (cons 5 ‘#1=(1 2 3 #1#))
(5 . #1=(1 2 3 #1#))
Sharp variables seem like an excellent solution for creating, reading and manipulating cyclic data structures.

Sharp Variables in JavaScript

Mozilla's JavaScript implementation has Sharp Variables. They've been introduced by Brendan Eich and they are inspired by Common Lisp's syntax. Sharp Variables can be pretty useful in JavaScript, since most of the time we're manipulating object references and Firefox's toSource() method is pretty useful for debugging (among other things).
var myArray = [1, 2, 3];
myArray.push(myArray);
myArray.toSource();
Try running that in your Firefox console, it should return "#1=[1, 2, 3, #1#]". Oh, and did I mention that you can also explicitly manipulate cyclic structures in JavaScript?
//Assign a literal recursive data structure
var anotherArray = #1=[1, 2, 3, #1#];

console.log(anotherArray.toSource());
//"#1=[1, 2, 3, #1#]"

console.log(anotherArray[0]);
//1

console.log(anotherArray[3].toSource());
//"#1=[1, 2, 3, #1#]"
I was happy to find such an interesting Lisp feature in JavaScript.
Comments
blog comments powered by Disqus