Search code examples
clojurelispcommon-lispsequencecons

common lisp cons creates a list from two symbols, clojure cons requires a seq to cons onto?


(Disclaimer - I'm aware of the significance of Seqs in Clojure)

In common lisp the cons function can be used to combine two symbols into a list:

(def s 'x)
(def l 'y)
(cons s l)

In clojure - you can only cons onto a sequence - cons hasn't been extended to work with two symbols. So you have to write:

(def s 'x)
(def l 'y)
(cons s '(l))

Is there a higher level pattern in Clojure that explains this difference between Common LISP and Clojure?


Solution

  • In Clojure, unlike traditional Lisps, lists are not the primary data structures. The data structures can implement the ISeq interface - which is another view of the data structure it's given - allowing the same functions to access elements in each. (Lists already implement this. seq? checks whether something implements ISeq.(seq? '(1 2)), (seq? [1 2])) Clojure simply acts differently (with good reason), in that when cons is used, a sequence (it's actually of type clojure.lang.Cons) constructed of a and (seq b) is returned. (a being arg 1 and b arg 2) Obviously, symbols don't and can't implement ISeq.

    Clojure.org/sequences

    Sequences screencast/talk by Rich Hickey However, note that rest has changed, and it's previous behaviour is now in next, and that lazy-cons has been replaced by lazy-seq and cons.

    clojure.lang.RT