简体   繁体   中英

Am I reinventing the (squared) wheel?

As we should know, Clojure's map can be applied to a sequence:

(map #(* %1 %1) [1 2 3])           ; (1)

..or to more than one, in this way:

(map vector [0 1] [2 1])           ; (2)
;=> ([0 2] [1 1])

Now I want to obtain the same result as (2), but I have the arguments stored inside a sequence. In other words, the following does not give the desired result:

(map vector [[0 1] [2 1]])         ; (3)
;=> ([[0 1]] [[2 1]])

So I've written this simple macro, where umap stands for "unsplice map":

(defmacro umap [fun args-list]
  "umap stands for unspliced map.
  Let args-list be a list of args [a1 a2 ... an].
  umap is the same of (map fun a1 a2 .. an)"
  `(map ~fun ~@args-list))

Obviously it works like a charm:

(umap vector [[0 1] [2 1]])        ; (4)
;=> ([0 2] [1 1])

So here's my question: am I reinventing the wheel? Is there another way to do the same as (4)?

Bye and thanks in advance,

Alfredo

apply unpacks all of the elements in the sequence at the end of the argument list.

user> (apply map vector [[0 1] [2 1]])
([0 2] [1 1])

It's not at all obvious that your umap works like a charm. In fact it will only work if you have the argument vector as a literal at compile time - which is exactly the times you could have passed multiple arguments to map anyway!

user> (umap vector [[1 2] [1 2]])
([1 1] [2 2])
user> (let [args [[1 2] [1 2]]]
        (umap vector args))
java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
[Thrown class java.lang.RuntimeException]

The macro only has access to the symbol args because it runs at compile time, and can't splice it in order to use map. The right answer is to use apply , which treats its last argument as a sequence, and splices it into a series of additional arguments to the given function:

user> (let [args [[1 2] [1 2]]]
        (apply map vector args))
([1 1] [2 2])

我错过了什么,或者mapcat是否适合您的需求?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM