4 ms·
Oh, come on. Next, you're going to claim that Clojure is not "an actual Lisp" because it contains neither "Common" nor "Lisp" in the name? Clojure is a proper L
by iLemming 2y ago
Oh, come on. Next, you're going to claim that Clojure is not "an actual Lisp" because it contains neither "Common" nor "Lisp" in the name? Clojure is a proper Lisp. Period. It's homoiconic, it has macros, it is a Lisp-1 Lisp, not "kind of a Lisp-1 thing" or "a thing with a Lispy syntax." It is a proper, legit, respectable addition to the family of Lisps. Yes, it's not a Common Lisp, but it's a Lisp nevertheless. A three-wheeled car is still considered a car. While it may fall into a specific category of vehicles and sometimes be classified as a motorcycle or under a special designation depending on the jurisdiction, it is generally recognized as a type of car.
> why not just learn a functional language like Elixir or Haskell
Have you ever considered that specifically because Clojure borrowed some ideas from Lisp, some from object-oriented languages, and some from FP, it makes it a really good choice for certain applications and developers?
Besides, is it really a big deal not to have proper continuation/restart in Clojure? It really depends. For many use cases, the error handling techniques in Clojure are adequate and align well with its functional paradigms. I've been using Clojure for several years and haven't heard anyone seriously complaining about the lack of continuations, despite many former Common Lispers now being full-time Clojuristas. There are also some philosophical differences: The philosophy behind Clojure focuses on simplicity and building software with different tools and techniques, which can achieve similar robustness in practice. So, I don't know. Sure, I personally wouldn't mind having built-in support for continuations in Clojure, and there were some attempts to bring that via libraries, but this was never a "high priority thing" for Clojurists. If in 17 years of existence of Clojure (and almost 40 years of Emacs Lisp), that never became a thing everyone wants, I guess it's not as critical as you paint it to be.
- vzcx 2y agoLisp is a family of languages. They share a common ancestry. That family is larger than Common Lisp, although Common Lisp is might be the last living descendant. While there are common traits among members of the family (parenthesized notation, certain special forms, symbol names), the presence of these traits does not itself define the family any more than having fins implies that an animal must be a member of the fish family. A language is not only its syntax, but also it's semantics. Lisp is not just parentheses or even 'homoiconicity.' In addition to the surface syntax, there is a shared cultural understanding of what certain symbols mean, how they fit together into a system, what a symbol even is, and so on. Given that, while there is some surface resemblance to lisp, it's plainly obvious to me that Clojure does not belong in that family. This is not a dig at Clojure! Clojure makes a lot of people happy and productive, and that's great. It's my third favorite language on the JVM. But when you take a closer look at some very core design decisions made in Clojure you'll find that they depart strongly enough from all the other languages in the Lisp family that it belongs to a distinct language family. A few of them: - Reader doesn't intern symbols - EQUAL symbols aren't EQ - Introduction of vars - Cons doesn't cons - No numeric tower - Backquote behavior These things don't necessarily come up in day-to-day programming, so it might seem like quibbling, but these are fairly central differences in meaning. I think it's sensible to consider "Clojures" as a distinct language family. Rhere are languages like Fennel and Hy that are clearly Clojures, and I'm sure there will be more.
- iLemming 2y agoI'm not here to debate taxonomy. Rich Hickey says: "Clojure is a dialect of Lisp and shares with Lisp the code-as-data philosophy and a powerful macro system." No disrespect, but unless Alan Kay or Guy Steele come to your side and convince Rich to stop calling Clojure a Lisp, I'll be calling it that. Sorry, maybe Mr. Hickey knows better than I do about the language he created?
- lispm 2y ago"Being a Lisp" or "being a dialect of Lisp", these are two different things for me. But even the "dialect of Lisp" actually is more like "spiritual dialect of Lisp". Clojure was from the beginning designed with exactly ZERO backwards compatibility to Lisp. Exactly ZERO of the existing Lisp programs/libraries could work. It was even difficult to port them. It's basically a kind of "dialect" with new operators and data structures, which interprets prior concepts in new ways and mixes in new stuff. But it was designed with compatibility to Java and the JVM -> one could not reuse existing Lisp code, but one could reuse existing Java code -> since Clojure was hosted on the Java and had integrated calling Java code. Reusing Java was more important, because the goal was to work in a Java industry. Thus there wasn't a version of Clojure on top of Lisp, only versions on top of languages/infrastructures like JavaScript or .net, because there was another source of reuse. If we look at the above linked paper "The Evolution of Lisp", then "Evolution" actually meant "Evolution", not "Restart" -> the language evolved by improving, adding, extending, removing, ... around a core design. Clojure was designed as a new dialect, free of the baggage from the past, with a completely fresh start. Reusing existing code or evolving an existing language was a non-goal. It was newly designed as a hosted implementation (-> the Lisp runtime was gone), it was designed with lazy data structures at its core (-> the Lisp linked lists were gone), it was an opinioned new design, based upon of what Rich Hickey liked about Lisp and what would help him to be employed as a consultant in a Java world -> by developing upon and within the Java stack of standards, tools and libraries. And that's fine for him. Rich Hickey had his goals and succeeded with them. Other people found it useful, too.
- iLemming 2y ago
- lispm 2y ago"continuations" are not in standard Common Lisp. They are a Scheme feature (-> functions which capture a state of computation). Common Lisp has a standardized exception handling system called the "Condition system", it features conditions (-> exception classes), handlers and restarts. It provides a non-terminating exception handling system, also often with a user interface -> the user can choose a restarts via some menu system or in the REPL. Something similar is in Smalltalk, which provides excellent tools for error handling and debugging. Lisps prior to Common Lisp usually had elaborate ways to handle runtime errors and extensive REPL interfaces for it, for example the break loop -> a REPL in the error context. The most prominent and widely cited was the one of Interlisp, which featured also user facing automatic error repair (-> DWIM). Whenever I see a Lisp, which doesn't stop at an error and then let me look at it, I feel sad. GNU Emacs is an application (a text editor) -> debug-on-error is by default NIL. That makes sense in an application. > that never became a thing everyone wants, I guess it's not as critical as you paint it to be. People asked for it, it seems. But the answer was no. See for example "https://vimeo.com/223309989 https://vimeo.com/223309989", "REPL driven development". It was a topic in the Q&A at the end. Also: Since JVM/Java already has a built-in exception handling, why build another one? There are some libraries...
- iLemming 2y agoAh... it's that thing that stars a debugger when you hit an exception, right?
- brabel 2y agoCommon Lisp has the Condition System [1] and that is not a continuation mechanism, though it may seem similar because you can stop a computation and resume it with a different value, for example. I think that to classify as a continuation, CL would just need to expose the condition system's internals to allow the user to choose how to "use" it, but as it is, you can't: the only way to use conditions is to have predefined handlers for them... I remember that this was an important difference because with delimited continuations you can implement stuff (like async/await I think - probably most Monads?) that you can't in CL's Condition Systems (I can't find the article talking about this right now, hopefully someone else can chip in). [1] https://lisp-docs.github.io/cl-language-reference/chap-9/j-b-condition-system-concepts https://lisp-docs.github.io/cl-language-reference/chap-9/j-b...