Live data from Hacker News

Differences with other Lisps

clojure.org

91–100 of 108 posts

Re: Differences with other Lisps

#91
post #78

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.

Re: Differences with other Lisps

#92

I've been messing with Clojure/ClojureScript for a few years having previously had zero Lisp experience. Overall, I think Clojure does a good job of being both practical and lispy. It's a language that is for building real things. I've been focusing on ClojureScript ( https://clojurescript.org/ ) as you get the benefit of interoperating with the Javascript ecosystem. The fact that there's a strong community around bo…

> Overall, I think Clojure does a good job of being both practical and lispy. It's a language that is for building real things. As opposed to? Common Lisp and Emacs Lisp are both highly practical. Scheme you might call more academic, but that's not really what people think of when they say "Lisp".

I wasn't trying to set up an "opposition" on the language level in my sentence. The decision was couched in my personal constraints - whether "as a hobbyist" it was practical for me to learn the language successfully. And, having done so would it have the capabilities so I can build things that I'm interested in. For me personally, I like to have plenty of 'similar code' so that I can see what other people do. I was comparing this with a more academic approach which I've seen many Lisp learners enjoy - for example going through the Structure and Interpretation of Computer Programs (SICP). Other languages I looked at and seemed interesting were Elm and Racket - no particular reason why they didn't stick.

I suspect a lot of the dynamics of my choice are because I wasn't coming from any sort of Lisp background previously. If you were coming from Common Lisp then things would feel different.

Re: Differences with other Lisps

#93
post #87

Earlier quoted context omitted.

Oh yeah, you're right, multi-arity fns are also a big exception to the empirical "rule" I mentioned. And yes, (ns) macro looks like a historical mess indeed. > but I am saying that I don't think Clojure's introduction of [] and {} for core syntax on top of their roles as data literals actually made things any better I think of it as embedded JSON so that it's easier to type data structures, and with Clojure you end u…

Right, as data literals my program is going to use they're great, I fell in love with Python a long time ago in part because of its convenient data syntax. Clojure's values-are-values philosophy is also amazing. How much value are they though as core syntax forms? Take keyword parameters for instance. In Clojure you pass to defn something like [a & {:keys [x y]}]. In Common Lisp, that would be (a &key x y). If you wa…

In Common Lisp the arglist is not a runtime datastructure, unless one uses something like APPLY. This means that the usual implementation (compiler/interpreter) will check the declared keyword arguments: is it duplicate, is it used, ...? For calls it can be checked if the keyword is known. That's usually all done by default.

Re: Differences with other Lisps

#94
post #44
post #38

Earlier quoted context omitted.

Only R6RS made () and [] interchangeable. That was hugely controversial, with opponents (myself included) thinking it was a waste of 1/3 of the matching pair symbols. And the suggested use was not quite the syntax you showed: http://www.r6rs.org/final/html/r6rs-app/r6rs-app-Z-H-5.html

I fully agree (and thanks for the idiomatic let bracket ordering correction). But the fact that terribly hacks like this are nonetheless adopted shows how much of a pain the paren clutter is and that claims to the contrary are pure cope.

i maintain two large CL code basis. there is no pain because of parens. really not...

Re: Differences with other Lisps

#95

I've been messing with Clojure/ClojureScript for a few years having previously had zero Lisp experience. Overall, I think Clojure does a good job of being both practical and lispy. It's a language that is for building real things. I've been focusing on ClojureScript ( https://clojurescript.org/ ) as you get the benefit of interoperating with the Javascript ecosystem. The fact that there's a strong community around bo…

I've read that Clojure(Script) has a great REPL experience. Even when using VSCode, can one use the REPL easily?

I can confirm that, Calva enabled me to get comfortable enough with the whole ecosystem to actually start with experimental projects.

I fully plan on making it my main language for my own projects, with that being Java and the web stack at the moment.

Re: Differences with other Lisps

#96
post #57
post #38

Earlier quoted context omitted.

Only R6RS made () and [] interchangeable. That was hugely controversial, with opponents (myself included) thinking it was a waste of 1/3 of the matching pair symbols. And the suggested use was not quite the syntax you showed: http://www.r6rs.org/final/html/r6rs-app/r6rs-app-Z-H-5.html

> a waste of 1/3 of the matching pair symbols I count 5, (), [], {}, and /\ though the last one is a bit of a stretch (but it's reversible: \/). Am I missing something? Did you mean "1/3 of the matching pair symbols left" as () is already used? Or is not usable?

There are functions starting with so that's no good. And / and \ are already used elsewhere.

Re: Differences with other Lisps

#97
post #44
post #38

Earlier quoted context omitted.

Only R6RS made () and [] interchangeable. That was hugely controversial, with opponents (myself included) thinking it was a waste of 1/3 of the matching pair symbols. And the suggested use was not quite the syntax you showed: http://www.r6rs.org/final/html/r6rs-app/r6rs-app-Z-H-5.html

I fully agree (and thanks for the idiomatic let bracket ordering correction). But the fact that terribly hacks like this are nonetheless adopted shows how much of a pain the paren clutter is and that claims to the contrary are pure cope.

It is not a terrible hack. It is a useful thing to do if you dont have things like paren highlighting or paredit.

I am firmly in the "paren clutter doesn't exist" camp.

Re: Differences with other Lisps

#98
post #49

The bigger picture: Clojure was designed with no backwar(d/t)s compatibility. https://clojure.org/about/rationale#_lisp_is_a_good_thing > Clojure is a Lisp not constrained by backwards compatibility Which means that basically no (!) Lisp software from the past ran in Clojure and trying to make it results in a re-implementation and re-architecture of that software.

> Clojure was designed with no backwar(d/t)s compatibility Correction: Clojure was designed with no backwards compatibility with previous lisps Clojure puts a huge focus on being backwards compatible within it's own ecosystem. I've used libraries that haven't been updated in ages (think Clojure 1.3) but still works the same way as they did back then. This is also reflected in the community where libraries are very ca…

> Clojure puts a huge focus on being backwards compatible within it's own ecosystem

Like lots of languages. Incl. Lisp itself. For example the Maxima computer algebra system written in Lisp has been started >50 years ago (as Macsyma) and still is being worked on.

https://maxima.sourceforge.io

The current build system ASDF works in Lisp implementations which date back to the mid-70s...

https://common-lisp.net/project/asdf/#implementations

Re: Differences with other Lisps

#99
post #98

Earlier quoted context omitted.

> Clojure was designed with no backwar(d/t)s compatibility Correction: Clojure was designed with no backwards compatibility with previous lisps Clojure puts a huge focus on being backwards compatible within it's own ecosystem. I've used libraries that haven't been updated in ages (think Clojure 1.3) but still works the same way as they did back then. This is also reflected in the community where libraries are very ca…

> Clojure puts a huge focus on being backwards compatible within it's own ecosystem Like lots of languages. Incl. Lisp itself. For example the Maxima computer algebra system written in Lisp has been started >50 years ago (as Macsyma) and still is being worked on. https://maxima.sourceforge.io The current build system ASDF works in Lisp implementations which date back to the mid-70s... https://common-lisp.net/project/…

> Like lots of languages. Incl. Lisp itself.

Sure, I'm just highlighting that your statement about Clojure is correct when it comes to compatibility against other languages while being incorrect if you consider it within the Clojure ecosystem itself.

Re: Differences with other Lisps

#100
post #98

Earlier quoted context omitted.

> Clojure puts a huge focus on being backwards compatible within it's own ecosystem Like lots of languages. Incl. Lisp itself. For example the Maxima computer algebra system written in Lisp has been started >50 years ago (as Macsyma) and still is being worked on. https://maxima.sourceforge.io The current build system ASDF works in Lisp implementations which date back to the mid-70s... https://common-lisp.net/project/…

> Like lots of languages. Incl. Lisp itself. Sure, I'm just highlighting that your statement about Clojure is correct when it comes to compatibility against other languages while being incorrect if you consider it within the Clojure ecosystem itself.

You might want to tell the maintainers about their error:

> Clojure is a Lisp not constrained by backwards compatibility

https://clojure.org/about/rationale

Post reply on HN