Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to destructure a vector for use as a function argument

Tags:

clojure

In Python, you can pass a list or tuple to a function and have the function unpack the argument. How can I do that in Clojure? Here is some example Python code:

def f (a, b, c, *d):
    print "a: ", a
    print "b: ", b
    print "c: ", c
    print "d: ", d

f (1, 2, 3, 4, 5, 6)

print
v = (4, 5, 6)
f(1, 2, 3, *v)

result:

a:  1
b:  2
c:  3
d:  (4, 5, 6)

a:  1
b:  2
c:  3
d:  (4, 5, 6)

in my clojure code:

(defn f [a b c & d]
  (println "a: " a)
  (println "b: " b)
  (println "c: " c)
  (println "d: " d))

(f 1 2 3 4 5 6)

(println)
(def v [4 5 6])
(f 1 2 3 v)

result:

a:  1
b:  2
c:  3
d:  (4 5 6)

a:  1
b:  2
c:  3
d:  ([4 5 6])

the d have one element only, how can I let result as python code?

like image 995
number23_cn Avatar asked May 29 '12 15:05

number23_cn


2 Answers

Clojure does not unpack arguments from a vector with a language feature, like Python does.

The closest thing to unpacking is function apply.

In this particular case:

(def v [4 5 6])
(apply f (concat [1 2 3] v))

Prints:

a:  1
b:  2
c:  3
d:  (4 5 6)
like image 183
Leonel Avatar answered Nov 09 '22 11:11

Leonel


Just for completeness.

Say you have a function that takes a vector [d1 d2 d3] as an argument

(defn f
  [a b c [d1 d2 d3]]
  (println "a: " a)
  (println "b: " b)
  (println "c: " c)
  (println "d1: " d1)
  (println "d2: " d2)
  (println "d3: " d3))

This way we can take the first 3 items from the vector that is passed into the function f as d1 d2 d3. Calling the above function results in the following output:

=> (f 1 2 3 [6 7 8 9])
a:  1
b:  2
c:  3
d1:  6
d2:  7
d3:  8

Note that even though the vector contains 4 items, we only take the first 3.

like image 21
mchlstckl Avatar answered Nov 09 '22 11:11

mchlstckl