4 ms·
I think the Clojure people tend to produce unreadable mess, which tells me the design of their language is down in the gutter. Common Lisp is a language with a
by bluefox 6y ago
I think the Clojure people tend to produce unreadable mess, which tells me the design of their language is down in the gutter. Common Lisp is a language with a lot of warts, sure, but typical Common Lisp code is way, way, way more tasteful than typical Clojure code.
We like our multiparadigmness, thank you very much. That includes being able to mutate things. We also like that the language is stable, and that means no changes to the spec, and that means it won't cover everything. That's OK, because our spec covers more than enough. We have less stable libraries and implementation-specific interfaces to cover the rest. We are still pretty conservative with those, too.
Clojure doesn't have a spec at all (it has documentation for the single implementation; it seems to have another implementation which is even more a toy since no real Clojure programs can run on it, because JVM is part of Clojure, really...) and once things are documented they either stick forever or break. I wouldn't say Clojure has warts; it has massive oozing injuries that keep on spreading indefinitely.
So yeah, we'd rather live with the warts from the 90s, the 80s, the 70s, and the 60s. We like our tradition, and we like our programs not breaking. We have a stable base that we can build 2020, 2030, 2040 stuff on.
- dustingetz 6y agotypical clojure is a mess because it actually gets used in industry by junior devs and such
- bluefox 6y agoIf true, that is a point for Clojure. It keeps the inexperienced on a distinct path where some day, when they're battle-worn and wise and had enough of it, they may find it was a road to Lisp after all.
- dustingetz 6y agoi think you're looking for the principle agent problem aka middle management wrecking everything
- didibus 6y ago> typical clojure is a mess That's a claim that would need to be substantiated first. My experience is that typical Clojure is quite descent actually.
- m45t3r 6y ago> Clojure doesn't have a spec at all (it has documentation for the single implementation; it seems to have another implementation which is even more a toy since no real Clojure programs can run on it, because JVM is part of Clojure, really...) It is true that Clojure doesn't have a spec, but it is very stable. I saw some very minor breaking changes in Clojure, and most code just works after a update (including very big projects). Clojure is very conservative in general, and this is something that Rich says as a explicit design goal. BTW, are you referring to ClojureScript? Because ClojureScript is far from a toy language, it works well and we use in production. Sure it have some warts, but they're mostly workable and while I am not a fan, I am not a fan of frontend in general so this is probably part of the problem.
- bluefox 6y agoI was thinking about ClojureCLR. While my argument could be applied to ClojureScript, I did not think it was fair because ClojureScript calls itself a (proper) subset of Clojure, which is fine and no one expects it to run actual Clojure programs. Again, I apologize for undue harshness.
- didibus 6y agoLots of Clojure code is portable between Clojure, Clojure CLR and ClojureScript. The differences honestly are often pretty similar to what some CL implementations differ in: host interop and multi-threading/concurrency. The biggest difference is that Clojure standard library doesn't wrap all host APIs, so there's a bigger reliance on direct host interop. That's the main thing. And because the hosts themselves don't all share APIs, the interop specific code needs to be written specifically to the host. It's a similar story for multi-threading and concurrency, some hosts don't support it at all, or support a very different version like Actors only, so in those cases the Clojure features related to them are dropped or altered to match the host. You can still provide multi-host libraries, by making use of reader conditionals you can have the code fork at the points where it needs to be specialized for each host. That in turn can be used portably afterwards on whatever hosts the library would have supported.
- didibus 6y agoI've found in practice, Clojure's different implementations are actually way more useful then Common Lisp. In CL, you can in theory take code from ABCL, and then run it over SBCL, but the spec is actually a lie, and not all code will be portable, and most implementation have their own slight deviation and additions to the Spec. And in CL, each implementation is basically the same with a few differences, and thus very few reasons to use one or the other. Where as in Clojure, there's good reasons to go from Clojure Java to ClojureScript to Clojure CLR, to Babashka, to Clojerl, to Ferret, etc. Each time you switch the target platform you get a Clojure that is well adapted to the new platform host. That has made it much more practical I've found in practice. It's actually because there are enough host specific differences that in the end I find it more useful.
- bluefox 6y agoI guess our experience with regards to CL differs. A lot. The spec is lie? Implementations are all the same? To me it sounds like you're talking about a different language. I can take source code from the eighties and nineties (say from CMU AI archive) and, in all likelihood, with a few modifications make it respect the ANSI specification and have it run in 2020 on pretty much any CL implementation. This code is several times older than Clojure. I have a lot of code from 15 years ago to this day that works flawlessly on pretty much any CL implementation. Granted I also have some implementation-specific code and code that would suffer in efficiency and that would hit implementation limits. I use mainly two CL implementations (SBCL, ECL) that serve purposes that are quite different. I know applications where CLISP was chosen because of its size and mostly-portable bytecode. People who care about Appleware tend to like CCL for its support on that platform. Some companies prefer the more enterprisey LispWorks/Allegro. These implementations are all meaningfully different. They all strive to conform to the specification. CLISP and Allegro have nonconforming modes as well, which not many people care about.
- didibus 6y ago> and, in all likelihood, with a few modifications make it respect the ANSI specification and have it run in 2020 > Granted I also have some implementation-specific code and code that would suffer in efficiency and that would hit implementation limits. That's my point. I mean that the Spec make you think it's always 100% compatible, but there are actually some small differences, and it's not always compatible or performing similarly. Clojure just makes that reality explicit. Here are alternate implementations, here's what they support and where they differ, and don't trust that any implementation details might be exactly the same. And for CL, a lot of choosing an alternate implementation is about finding one that supports the platform you target. But in Clojure, that's already handled by an intermediate host, like JVM, JS, or CLR. And so a lot of the meaningful differences between CL implementations arn't meaningful in Clojure, instead they'd be lifted to choosing which JVM you want to use, instead of which Clojure implementation you want to use. And it turns out the JVM is incredibly portable across platforms and does have a Spec, and so does indirectly Clojure. So when you take it practically, the choice of implementation for me is about reach. And there are some places where CL reaches further then Clojure for now, specifically around embedded, IOT, lower level and such. There's also places where it doesn't reach as far as the JVM or JS hosts can give you. And yes, you can use say ABCL, but it's not as simple as copy/pasting your code to it. Part of wanting the reach of the JVM is to tap into its ecosystem of libraries and frameworks, and as soon as you do that, your ABCL code is stuck to only working on ABCL, and is no longer portable to any other CL host, same as Clojure. I'd reframe the problem here, instead of saying CL is portable and has a Spec and Clojure doesn't. I'd say what exactly are you trying to achieve? Do you want to run code written for x86 Windows on ARM64 FreeBSD? Well Clojure code is portable on both using the same implementation but a different JVM. And CL code can be portable as well if switching to a different CL compiler implementation with support for ARM64 FreeBSD. Do you want to use JS libraries in a Common Lisp project and target the browser and NodeJS? Well, I'm actually not sure if CL has any way to do that, but assume it does, great you can do it, but most likely not have it be portable. Similarly with Clojure you have ClojureScript for that.