Created
June 30, 2013 04:33
-
-
Save gilesbowkett/5893860 to your computer and use it in GitHub Desktop.
comparing every element in a list to every other element
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; common lisp version, totally works | |
; (defun build (list1 list2) | |
; (if (null list1) | |
; () | |
; (append (mapcar #'(lambda (bubble) | |
; (list (first list1) bubble)) | |
; list2) | |
; (build (rest list1) list2)))) | |
; if you tell lisp: (build '(1 2) '(1 2)) | |
; lisp will happily reply: ((1 1) (1 2) (2 1) (2 2)) | |
; literal clojure translation | |
(defn build [list-1 list-2] | |
(if (nil? list-1) | |
() | |
(concat (map (fn [bubble] | |
(list (first list-1) bubble)) | |
list-2) | |
(build (rest list-1) list-2)))) | |
; if you tell clojure: (build '(1 2) '(1 2)) | |
; lisp will stack overflow error all up in your business | |
; if you're curious there's a Ruby version here: | |
; https://github.com/gilesbowkett/tweenr/blob/master/bit101_style.rb#L2 |
The problem is that the empty list returns false to nil?
in Clojure. ()
and nil
are distinct. So it's going into an infinite loop.
Should do (nil? (seq list-1))
instead.
Or do (when (seq list-1) (concat ....))
This looks like you're trying to take the Cartesian cross-product of two sequences. I know you got help on the failure already, but in case you're interested, a more Clojurey approach would look like this:
(defn build [seq1 seq2]
(for [elem1 seq1 elem2 seq2] [elem1 elem2]))
And that's short enough that I probably wouldn't even bother making a function out of it.
If you want something that's the Cartesian product of n sequences, that's slightly more involved:
(defn cross-prod [& colls]
(->> colls
(reduce #(for [x %1 y %2] [x y]))
(map flatten)))
The Common Lisp code reimplements MAPCAN. Use it:
(defun cp (l1 l2)
(mapcan (lambda (e2)
(mapcar (lambda (e1) (list e1 e2)) l1))
l2))
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
recur
also fails because it's not in the tail position