Hacker News new | past | comments | ask | show | jobs | submit login

I've only just started learning Common Lisp and never used Clojure, but what are the implications or trade-offs of

>Symbols are not storage locations (see Var)

I thought the way symbols worked in CL are one of the three big ideas (s-exps and macros being the other two).




There's two main aspects to the claim. The first is Clojure's general stance against "place-oriented programming" that ties in with its immutable-by-default data structures. A good talk is https://github.com/matthiasn/talk-transcripts/blob/master/Hi...

The second is more specific. In Clojure, symbols are just names. When the compiler encounters a symbol, and it's not a special java kind or a local, it'll try to lookup that symbol in a Namespace map, and return a Var. The Var is where the storage is, the symbol is just a name to find it. Re-def'ing the symbol doesn't change anything about the old Var, it just associates the symbol with a new Var. In CL though, symbols are themselves objects that have attributes (http://www.lispworks.com/documentation/HyperSpec/Body/t_symb...) which store data. If you (inspect 'a) you'll see it has a string name, package, and an empty value, function, and plist. When you (defparameter a 8) and inspect 'a again, you'll see it has a value attribute of 8. You can then (defun a ()) and inspect again, and see both the value and function attributes are set. Of course CL is a Lisp-2.

Part of Clojure symbols being just names, means they aren't owned by any namespace. If you have three namespaces with functions that return 'x, they will all be value-equal to each other. Clojure symbols can be namespace-qualified, like 'some-ns/x, but that just restricts the lookup, the namespace doesn't own such a symbol. You can even make such a symbol without having defined the namespace some-ns first. In CL by contrast, if you create three functions in three different packages returning 'x, they will not be value-equal. And if you try to reference a symbol in 'some-package:x when the package doesn't exist, you'll get an error.

Clojure symbols are not storage-equal though: (identical? 'x 'x) is false. In CL, in the same package, (eq 'a 'a) is true.

Some consequences: another feature is that Clojure's syntax-quote/quasi-quote ` for macros will automatically bring in the symbol's full namespace, e.g. if you (ns a) and quote 'inc or 'a you'll get inc and a back, but if you syntax-quote `inc and `a you'll get back clojure.core/inc and a/a respectively. This helps reduce the chance of name collisions. Another consequence is that since symbols don't belong to namespaces in Clojure, you don't have to worry about a CL behavior of polluting your package's namespace with a bunch of symbols. (i.e. in CL when you switch to package a and type 'a, you just interned the symbol a in that package.) And another consequence is that if you make a function private in Clojure, you can't get at it with the symbol name from outside of the namespace, whereas in CL, if you don't export something from your package (making it "private"), you can still get at it outside with package::symbol.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: