Today’s look into the Clojure API is a post on list*, and how it differs from list and conj.
list* takes as its args elements you want to add to a collection, followed by the collection. If the elements you are adding are primitives, it will return a flat list, simply adding the elements to the collection. Like conj, it adds the elements to the front of the list. Unlike conj, list* always returns a list, even if you give it a vector. If you are adding two collections, you will not get a flat list.
list takes elements to make into a list. If use this to add an element and a list, you will get a nested list.
user=> (def my-vec [1 2 3]) #'user/my-vec user=> (list* my-vec 4) IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:542) user=> (list* 4 my-vec) (4 1 2 3) user=> (def my-list '(1 2 3)) #'user/my-list user=> (list* 4 my-list) (4 1 2 3) user=> (list* my-list 4) IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:542) user=> ;; in list*, the arg to add to the collection (list/vector) is first, collection second ;; unlike in conj, where the collection (list/vector) comes first, then what you want to add ;; with list, the result could have multiple levels user=> (list 4 5 my-list) (4 5 (1 2 3)) ;; with list*, multiple args give a flat list user=> (list* 4 5 my-list) (4 5 1 2 3) user=> (list 4 5 my-vec) (4 5 [1 2 3]) ;; same with vectors user=> (list* 4 5 my-vec) (4 5 1 2 3) ;; for a list, conj will give a flat list with the args in the front user=> (conj my-list 4 5) (5 4 1 2 3) user=> (conj my-vec 4 5) [1 2 3 4 5] ;; sometimes you gotta work with flatten to get a flat list user=> (list 4 5 my-vec) (4 5 [1 2 3]) user=> (list* my-vec my-list) ([1 2 3] 1 2 3) user=> (list* [1 2 3] my-list) ([1 2 3] 1 2 3) user=> (list* my-list my-list) ((1 2 3) 1 2 3) user=> (flatten my-vec) (1 2 3) user=> (list* (flatten my-vec) my-list) ((1 2 3) 1 2 3) user=> (flatten (list 4 5 my-vec)) (4 5 1 2 3) user=> (flatten (list* my-vec my-list)) (1 2 3 1 2 3) user=> (list my-vec my-list) ([1 2 3] (1 2 3)) user=> (flatten (list my-vec my-list)) (1 2 3 1 2 3)
You’re welcome.