Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Why don’t lisp fans use older lisp implementations like Common Lisp or scheme? Is it just a lack of libraries and frameworks?


Clojure is functional to the core and innovates a lot of areas, while other Lisps are more multi-paradigm and slant towards an OOP style. If you want to work universally with persistent data structures in your code and the libraries you use, Clojure is really the only option. Clojure also modernises Lisp syntax slightly (and a bit controversially) by getting rid of lots of parentheses and introducing new styles of parens for the core built-in data structures: ( ) [ ] { } #{ }. There's a bunch of other stuff, but really, Clojure is significantly different from other lisps.

The Rationale page on clojure.org has a pretty good rundown: https://clojure.org/about/rationale


Personally, I like what Clojure has done for Lisp syntax. I don’t have the greatest eyesight anymore and Clojure makes it easier to read my code.


I agree. Greg Hendershott apparently also agreed as he ported some Clojurisms to racket in the form of a language / loadable library:

https://docs.racket-lang.org/rackjure/index.html


Some of it is libraries and frameworks. Some of it is the attention Clojure has paid to ergonomics. A lot of Clojure’s libraries seem to have been built by smart people for mediocre programmers (like me!). Elsewhere in lisp land it can feel like smart people wrote libraries for themselves.

For me Racket is probably the closest thing to a decent end-to-end modern lisp experience with decent libraries outside Clojure. Gerbil Scheme also looks promising.

For me I’m most often writing smallish standalone apps, which I feel are easier to make in Racket than Clojure. But between the two languages, I’d probably take Clojure if I didn’t have the JVM along for the ride. Of course the JVM is also one of Clojure’s biggest strengths. Also, I don’t trust Oracle enough to stop pretending that Graal doesn’t exist.


Aside from being faster, more mature and with better observability, why is bringing "the JVM along for the ride" different from bringing Racket's runtime along? Also, you do know that Oracle is behind OpenJDK, has been for ten years, and has recently made the JDK completely open-source and free of field-of-use restrictions for the first time in Java's history?


Off topic; But since you work at Oracle, what is the Oracle copyright terms on alternative implementations of Java? (in the light of Android lawsuits). Eg: some research or commercial implementation for a subset of java etc?


What do you mean by "alternative implementations"? OpenJDK is 100% open source, and is entirely governed by its open-source license. You can do whatever you want with -- including take just big or small pieces from it and change them -- it as long as you comply with the license. If you want to use the name "Java", your software must pass the TCK.


No. By alternative implementation I meant eg: some experimental java compiler to a different target eg: say JS / wasm, or a memory efficient class library implementation etc..


The Java spec is not open source. You could either extract as much or as little from OpenJDK and comply with its open-source license or obtain a spec license if you don't wish to open-source your implementation. In other words, you have the open-source route or the closed source route, but the closed-source route isn't free. (BTW, I am not authorized to speak on behalf of anyone other than myself, so this is just my opinion).


I haven’t figured out a way with the JVM / Clojure to compile and distribute a small self-contained bundle nearly as easily as I can with Racket.

And Graal (the option I’m aware of for compiling JVM-based code into a redistributable binary) is definitely Oracle. If I wrote more long-running code, or I could redistribute a stripped down JVM as easily as with Racket’s build tool “raco” I might have a different view, and I’d definitely prefer OpenJDK to Oracle’s.


OpenJDK is also made (primarily) by Oracle [1]; in fact, OpenJDK is the name of Oracle's one and only Java implementation project, although Oracle builds both free and support subscription binaries from it. Both OpenJDK and Graal are open source, though. OpenJDK now includes a tool called jlink [2] that allows you to create a small, self-contained bundle that includes a custom runtime as well as your app.

[1]: http://openjdk.java.net/

[2]: https://docs.oracle.com/en/java/javase/13/docs/specs/man/jli...


I’d love to see a tutorial on how to do this with Clojure—especially integrated with the Clojure build tooling.


Gerbil Scheme allowed me to be productive in Scheme. It really is a treat to work with. No tooling required other than compiling Gambit, Gerbil and having a text editor. Those three things let you ship fast binaries, with static or shared libraries. Couple that with a nice macro system (a la Racket) and you can get going really fast.


"I don’t trust Oracle enough to stop pretending that Graal doesn't exist."

Did I parse that correctly as: "I don't trust Oracle, therefore I pretend Graal doesn't exist"?


Yes :-)


> decent end-to-end modern lisp experience with decent libraries outside Clojure

Those are still LispWorks and Allegro Common Lisp.


I don’t think being a lisp is the primary reason for using Clojure, but it’s the added bonus of being a lisp designed for FP, concurrency, and host VM integration.


My personal take: CL is a multi-paradigm rummage bin that demonstrated to the world the greatness of many features (e.g. macros, CLOS), but is also beset by many design flaws--some due to genuine infelicity of conception, and some due to unavoidable limitations of software and hardware at the time. (For one thing, there are approximately 101 ways to test equality). The result is that you could be a career CL programmer and see code written in a style you've never seen before, and that it suffers from design flaws that, if fixed, would result in something that would no longer be Common Lisp. Scheme's problem is kind of the opposite: it's stripped down, but also has not purged all of CL's unfortunate baggage, and very conspicuously lacks an out-of-the-box and full-featured package manager.

Clojure, being just over 10 years old, has gotten to benefit from decades of witnessing other languages' spectacular design disasters, and it was designed by one person in a few years instead of by committee over decades. This results in a language that is much more aesthetically coherent, adhering to a pragmatic flavor of FP, and avoids a lot of gnarly warts: for instance, Clojure has one basic way to test equality irrespective of data type, and all basic data structures are immutable.


I'm not sure you've picked the right example here - far from being a gnarly wart, differences types of equality are a fundamental issue. Your language can choose to either a) hide it effectively (constraining some things) b) expose it to the user which means they have to think about it or c) try (a) but leak and give weird corner cases.

It's not obvious that (a) is superior to (b), an (c) is often what you get.


In the abstract you're right that equality is subtle and complicated, but it seems to me that in practice, most practicing software engineers just want value-equality on garden-variety data structures most of the time (remember == for Strings in Java?), and that for this use-case, a leaky abstraction is fine--preferable, even. At least, the alternative--forcing users to consider the subtleties of equality even in circumstances where it can be safely ignored and having them memorize dozens of cryptic equality operator names--is excessive and unnecessary.


I'm not really saying any of those choices is wrong (although clearly you can make design mistakes that make the leaks problematic, if you pick (c)). It's more that none of them are clearly right.

Really I'm rejecting the idea that that equality as presented in CL was any of: wrong, design by committee, or something we have learned do better since '84.

There are historical artifacts in CL that aren't great (cf filesystem stuff) but this wasn't a good example in my opinion.

I hear your argument - not fully convinced other than in a 80/20 sense. And CL was not designed as a language to leave the 20% out in the cold.

To be fair I don't find clojure compelling as a lisp but I don't think I'm being biased in above.


Yeah, equalp is a really useful abstraction. Deep equality mashed together with case-folding. Something I've always wanted.


Of course in the rare cases I want deep equality without case (and number) folding, I can always implement it myself using... ooops!


I've had a lot of success in my own language designs with dividing the problem into two cases, equality and identity, or EQUALP and EQ in CL lingo. Despite having written a ton of CL over the years, I still fail to remember the specifics of EQL & EQUAL. Defaulting to full value equality does come with a performance cost, but I feel like we're mostly past the point where we should waste precious time on these kinds of micro optimizations for most use cases.

https://github.com/codr7/gfoo


I agree at least separating identity and equality seem to be important in practice. I'm not completely sold on where the other lines should be.

I don't love the CL implementation, particular eql vs equalp on numerics seems fiddly, and it's hard to keep all the cases separate. Homoiconicity introduces the need for a "representation equality" i guess which isn't always needed, etc.


Who knows what the lisp crowd is ?

I'd like to have a broad view of how many lispers working with one.

the few I know:

- scheme had a coma period due to specs issues (scheme small and large standard)

- commonlisp .. no idea but it seems quicklisp is enough for anybody to work, and there are many libs. Maybe not java/python levels .. but many. It's just out of the radar.


Clojure lets you leverage all libraries of the host language e.g. Java, Javascript or C#.


Many lisp fans do in fact use Common Lisp. Freenode #lisp, the term Lisp, Reddit lisp all primarily refer to and are about Common Lisp.

Additionally, there are many Lisp old timers that do not consider Clojure a Lisp.


I'm curious, what features are missing that stops Clojure from being considered a proper Lisp?

From my brief experience it can do most of the same things except reader macros.


The common talking points are

* Clojure is based on seqs rather than cons cells.

* Clojure renamed certain common functions, like car and cdr, so 30 year old Lisp example code no longer compiles.

* Clojure doesn't have implicit tail call optimisation for recursion.

* Clojure reveals its host platform when it has runtime errors.


This list doesn't strike me as the important things that Clojure is missing. They're all relatively minor matters. There are several other things that I would consider much more important.

I've gone on at some length about those things before (for example, see my long comment in this thread: https://news.ycombinator.com/item?id=22318748, ), so I won't repeat it here.

I'll just say that Clojure is pretty nice as far as it goes, and I like it when it's the right tool for the job, but I feel like it's only halfway to being a proper Lisp. Whenever I work in it for very long I always miss more complete Lisps, and I daydream about a Clojure with the missing pieces filled in.


> I daydream about a Clojure with the missing pieces filled in

Be the change you want to see in the world and start filling in the missing pieces! ;-)


That's a fair response. I've thought about working on a Clojure implementation on a Common Lisp runtime, precisely because I'd like to see a Clojure that is a real, proper Lisp.

Cloture is an interesting effort:

https://github.com/ruricolist/cloture

I hope ruricolist succeeds.

But so far I haven't actually done any work in that direction. When I work on interpreters and compilers, I generally work on trying to improve upon Common Lisp, rather than trying to help Clojure catch up to it.

Years ago, in the early 1990s, I worked on an experimental OS at Apple. It was written mostly in a Lisp called Ralph (which later evolved into Dylan). Ralph was basically Scheme's kernel operations on top of data types built on CLOS with some functional-programming idioms.

Ralph had all of the nice things I was pining for in that post that I previously linked, but it was also a smaller, simpler, and more consistent language than Common Lisp, and it was easier to learn and easier to extend.

I've been working for years now on a language that started as a Ralph embedded in Common Lisp, but which has mutated quite a bit over the years as I learned new things and experimented with adding them to my implementations. It's been complete enough for me to ship a few products with it, but it's not done, and lately I've been inclined to steer it more back toward Ralph.

Mostly. There are still a few newer features I might like to keep.

So, while I acknowledge that it's totally fair of you to exhort me to work on Clojure, and it's not necessarily a bad idea, there is another Lisp for me to work on that is dearer to me.


Clojure did not just rename a few functions. It's basically zero source code compatible with Lisps. Not only old example code does not run, nothing runs. No applications, no libraries, no tools, ... It's not even easy to port. It's a rewrite and/or redesign.

Obviously this is okay for people who don't care of the historical baggage (and want to avoid it) and who don't care about the functionality of Lisps, like interactive error handling.


Nothing is sharable between Common Lisp and Scheme, either, but Scheme is generally considered a Lisp.


That used to be different. There were Scheme programs running in both Scheme and Common Lisp or moving between them. For example the Yale Haskell compiler was originally developed in a Scheme dialect called T and then moved to Lisp (here Common Lisp) by embedding a shallow compatibility layer in Lisp. Another example is Common Music, a music composition system, which ran for a while both in Scheme and CL. Scheme itself was originally a hosted program on top of Maclisp. A few more Scheme implementations were written and/or embedded in Lisp - for example the Scheme variants for Naughty Dog's Crash Bandicoot and Jak and Daxter Playstation games were written in Common Lisp. The Scheme written by Peter Norvig was used in a content management system, embedded in CL.

Nowadays I don't think of Scheme as a mainline Lisp -> it moved from a close Lisp dialect to its own language with its own standards, books, user groups, libraries, implementations, applications, ...


Right. The reason Common Lisp is called “common” is that it has a standard that allows anyone to build a lisp from scratch that will run any common lisp code essentially completely unchanged (obviously you need to adjust a bit where you hit the OS, but even the file access methods are spec’ed). If you aren’t conformant you aren’t a Common Lisp - you could still be a lisp. Clojure is a lisp, just not a Common Lisp.


While this is not directly related to being a proper Lisp, one of the reasons (not the only one, of course) some people may prefer CL is CLOS.


It's amusing in retrospect because one of the criticisms of Common Lisp at the time was the massive size of its library.




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

Search: