4 ms·
I see the answers below and I want to ask everyone. Is there any other lisp besides Clojure right now, that is actively developed but not early stage, and also
by pvinis 10y ago
I see the answers below and I want to ask everyone. Is there any other lisp besides Clojure right now, that is actively developed but not early stage, and also not old? I want to use lisp and I don't care about the JVM. But whenever I search for lisps, I find some for C, Go, Rust that are too young, or Common Lisp which I read is too old and weird, and complicated. I really like Clojure and that's what I use for now, but a lisp without the JVM mighty be cool.
- qwertyuiop924 10y agoClojure... well, I wouldn't go so far as to say it's "not a lisp" (some people would), but it's quirky. It's like that weird guy who's just as competent as the rest of us, but has an "interesting" perspective on how he tackles problems. The example I got in another thread on this is: (list? '(1 2 3)) ;;; => true (= '(1 2 3) (cons 1 '(2 3))) ;;; => true (list? (cons 1 '(2 3))) ;;; => false That's actually psychotic: if your lists aren't lists, than don't call them lists! Anyways, Scheme is the part of the lisp family tree that actually evolves, albeit slowly. The spec is minimal, so compatability between implementations is low. I'd reccomend either Chicken or Guile scheme to most people, as both have pretty good FFI, decent performance (Chicken's is better), and good libraries (for a scheme). Racket isn't a Scheme, although it started as one. The official implementation of Arc runs on an old version of Racket, from when it was closer to Scheme (we should probably port it to another scheme at some point...). It's not really my thing, but you might like it, and it has some of the best library support of any lisp outside Common Lisp. OTOH, you may like Common Lisp. Bits of it are idiosyncratic, and it's huge and inelegant, but it's a tremendously powerful language, and very well supported and documented. There are actively developed implementations, and the most popular is probably SBCL.
- emidln 10y ago(list? '(1 2 3)) ;;; => true '(1 2 3) is, in fact, a list of 3 elements (= '(1 2 3) (cons 1 '(2 3))) ;;; => true = is closer to equal? in scheme. The doc string for clojure.core/= explains this pretty well: Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison. Finally, (list? (cons 1 '(2 3))) ;;; => false `cons` is defined over a sequence in Clojure, not a list. The doc string actually says this upfront "Returns a new seq ..." and the type of this happens to be a `clojure.lang.Cons`. To get add a value to a list, you would actually use `conj`, which conjoins a value onto a collection or sequence in a way that is specific to that collection or sequence. (list? (conj '(2 3) 1)) ;;; => true If you are dead-set on using lists for some reason (you probably want a different datatype in Clojure), you could always define: (defn cons? [x] (instance? clojure.lang.Cons x)) (defn list-cons [v l] (cond (cons? l) (list-cons v (into '() (reverse l))) (list? l) (conj l v) :else (throw (AssertionError. "Assert failed: list-cons requires a PersistentList or a Cons.")))) If you really want a Lisp-style cons with pairs and such, you'll need to define that yourself. It's not hard, or particularly useful, but if you really feel you must...
- qwertyuiop924 10y agoWhat I was saying is that that is really unintuitive. Cons has a specific meaning and clojure redefines it creatively. That's not a good thing. If your function isn't cons than don't call it that. Also, lisp pairs are very useful.
- lispm 10y agoUnfortunately they print as (1 2 3), even though they are different data structures. A naive user would think that if (1 2 3) is a list, then anything that prints like (1 2 3) is a list... printing it and rereading it -> I get a new data structure type. Really? Added with the random use of Lisp names to mean something different, while claiming to be a Lisp, this is only creating confusion.
- qwertyuiop924 10y agoIt may be a lisp, but I'm not having that debate in two threads at once :-). Nonetheless, this is poor design, and poor language ergonomics in actions. I think Rainer and I can agree on that much.
- emidln 10y agoCons prints the same as a list, which means when it is read, it is a list. '(1 2 3) is a PersistentList, not a Cons. In particular, this is what I expect: (= foo (read-string (pr foo))) As it turns out, in Clojure this holds (because = isn't identical?): (use 'clojure.test) (let [kons (cons 1 '(2 3)) kons-str (pr-str kons) read-kons (read-string kons-str)] (is (instance? clojure.lang.Cons kons)) (is (not (list? kons))) (is (string? kons-str)) (is (= "(1 2 3)" kons-str)) (is (list? read-kons)) (is (not (instance? clojure.lang.Cons read-kons))) (is (= kons read-kons))) Does this really create confusion for more than the 30 seconds it takes to read the doc string of clojure's cons? I don't know about you, but when I move to a different language (even a different lisp), I don't assume things always work exactly like they do in Common Lisp. When I came to clojure, I even took a look at the old version of this page: https://clojure.org/reference/lisps https://clojure.org/reference/lisps, which details this and other differences from the Schemes I had mostly used in the past.
- monads_wtf 10y agoYou want seq? user=> (type (cons 1 '(2 3))) #<Class@bc57b40 clojure.lang.Cons> user=> (type (conj '(2 3) 1)) #<Class@6137cf6e clojure.lang.PersistentList> user=> (seq? (cons 1 '(2 3))) true user=> (seq? (conj '(2 3) 1)) true
- qwertyuiop924 10y agoAnd that's really unintuitive and confusing. Especially coming from common lisp or scheme.