5 ms·
(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 schem
by 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.
- qwertyuiop924 10y agoThat may only create a few seconds of impedance, but it's still utterly psychotic and insane. Once again: if cons isn't cons, than don't call it cons. I don't assume that everything works the same way everwhere, but if you take your primitive function names from another language, and have them behave differently, people will be confused. I mean, sure, if the semantics of cons are a bit different, okay, but you can't just take the name and put it on a function that doesn't work at all like cons. It also violates homoiconicity, and the fundamental guarantee of the reader: what you read in is the same as what you wrote out.
- emidln 10y ago