Not understanding the proper use of map

3 views
Skip to first unread message

Ryan Neufeld

unread,
Dec 10, 2008, 1:05:40 PM12/10/08
to Clojure
I've been working on learning Clojure after taking a course in Common
Lisp and I am having some troubles translating a particular Common
Lisp function to Clojure that uses mapping.

We're defining a function that takes a function and two lists and
applies the function to each two items in the lists. Not particularly
safe or anything, but decent for learning.

In CL:
(defun parallel (F L1 L2)
(mapcar #'(lambda (x y) (funcall F x y)) L1 L2))

(parallel '+ '(1 2 3) '(4 5 6)) ;; => (5 7 9) ;; Working correctly

My attempt in Clojure:
(defn parallel [F L1 L2] (map (fn [x y] (F x y)) L1 L2))
-- OR --
(defn parallel [F L1 L2] (map F L1 L2))

however...
(parallel '+ '(1 2 3) '(4 5 6)) => (4 5 6)

I gleaned what I could from the Clojure wiki but I'm still missing
something.

Any pointers on where I am going wrong?

Michael Wood

unread,
Dec 10, 2008, 3:00:05 PM12/10/08
to clo...@googlegroups.com
On Wed, Dec 10, 2008 at 8:05 PM, Ryan Neufeld <Neuf...@gmail.com> wrote:
>
> I've been working on learning Clojure after taking a course in Common
> Lisp and I am having some troubles translating a particular Common
> Lisp function to Clojure that uses mapping.
>
> We're defining a function that takes a function and two lists and
> applies the function to each two items in the lists. Not particularly
> safe or anything, but decent for learning.
>
> In CL:
> (defun parallel (F L1 L2)
> (mapcar #'(lambda (x y) (funcall F x y)) L1 L2))
>
> (parallel '+ '(1 2 3) '(4 5 6)) ;; => (5 7 9) ;; Working correctly
>
> My attempt in Clojure:
> (defn parallel [F L1 L2] (map (fn [x y] (F x y)) L1 L2))
> -- OR --
> (defn parallel [F L1 L2] (map F L1 L2))
>
> however...
> (parallel '+ '(1 2 3) '(4 5 6)) => (4 5 6)

Works for me:

user=> (map + [1 2 3] [4 5 6])
(5 7 9)
user=> (defn parallel [f l1 l2] (map (fn [x y] (f x y)) l1 l2))
#'user/parallel
user=> (parallel + '(1 2 3) '(4 5 6))
(5 7 9)
user=> (defn parallel [f l1 l2] (map f l1 l2))
#'user/parallel
user=> (parallel + '(1 2 3) '(4 5 6))
(5 7 9)
user=>

The problem seems to be that you are quoting the +. Not sure why this is, but:

user=> ('+ 1 4)
4
user=>

> I gleaned what I could from the Clojure wiki but I'm still missing
> something.
>
> Any pointers on where I am going wrong?

--
Michael Wood <esio...@gmail.com>

Michael Wood

unread,
Dec 10, 2008, 3:07:53 PM12/10/08
to clo...@googlegroups.com
On Wed, Dec 10, 2008 at 10:00 PM, Michael Wood <esio...@gmail.com> wrote:
[...]

> The problem seems to be that you are quoting the +. Not sure why this is, but:
>
> user=> ('+ 1 4)
> 4
> user=>

OK, I think I know why this happens. It's treating the '+ as the key
for a map, and using the second integer as the default value. I'm not
sure why it treats an integer as a map, though:

user=> (get {:a 1} :a)
1
user=> (get {:a 1} :b)
nil
user=> (get {:a 1} :b 2)
2
user=> (:a {:a 1})
1
user=> (:b {:a 1})
nil
user=> (:b {:a 1} 2)
2
user=> (:a 1 4)
4
user=> ('a 1 4)
4


user=> ('+ 1 4)
4
user=>

--
Michael Wood <esio...@gmail.com>

Stephen C. Gilardi

unread,
Dec 10, 2008, 3:08:43 PM12/10/08
to clo...@googlegroups.com

On Dec 10, 2008, at 3:00 PM, Michael Wood wrote:

The problem seems to be that you are quoting the +.  Not sure why this is, but:

user=> ('+ 1 4)
4

('+ 1 4) is effectively (get 1 '+ 4)

(doc get)
-------------------------
clojure.core/get
([map key] [map key not-found])
  Returns the value mapped to key, not-found or nil if key not present.

As we might expect, it is doing what we told it to do... though in this case a diagnostic like "1 is not a map" would have been helpful.

--Steve

Dean Ferreyra

unread,
Dec 10, 2008, 2:59:51 PM12/10/08
to clo...@googlegroups.com

You've almost got it -- just don't quote the +:

user> (parallel + '(1 2 3) '(4 5 6))
(5 7 9)

By quoting the + you were passing in the symbol, not the function.

Dean

Ryan Neufeld

unread,
Dec 10, 2008, 4:56:22 PM12/10/08
to Clojure
Thats the CL'ism I was hanging on to! Thanks for the amazing and
prompt replies.

Brian Carper

unread,
Dec 10, 2008, 5:28:30 PM12/10/08
to Clojure
On Dec 10, 12:07 pm, "Michael Wood" <esiot...@gmail.com> wrote:
> OK, I think I know why this happens. It's treating the '+ as the key
> for a map, and using the second integer as the default value. I'm not
> sure why it treats an integer as a map, though:
>

Wow, that's a bit of a gotcha. It's not treating the integer as a map
though, get's default behavior is to return nil if the thing it's get-
ing from isn't some kind of collection. (Which is also a bit of a
gotcha, I think.)

user> ('a (fn []))
nil
user> ('a (Object.))
nil
Reply all
Reply to author
Forward
0 new messages