Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining a function with "extra" parenthesis

Tags:

clojure

Can anyone explain to me why

((fn ([x] x)) 1)

works and returns 1? (There's one "extra" set of parenthesis after the fn) Shouldn't it be the following?

((fn [x] x) 1)

Additionally,

((fn (([x] x))) 1)

(2 "extra" sets of parenthesis) fails with a "CompilerException System.ArgumentException: Parameter declaration([x] x) should be a vector". Why?

Thanks!

like image 738
Anonymous Avatar asked Dec 21 '22 04:12

Anonymous


1 Answers

The extra set of parenthesis allows you to define a function taking a variable number of arguments. The following example defines a function that can take either one argument or two arguments:

(defn foo
  ([x] x)
  ([x y] (+ x y)))

You can see this as defining two functions under a single name. The appropriate function is going to be called depending on the number of argument you provide.

If you define a function with a fixed number of arguments, the two following forms are equivalent:

(defn bar ([x] x))

and

(defn baz [x] x)

With this in mind you can understand the compiler exception. You are trying to define a function as follows:

(defn qux 
  (([x] x)))

When using the extra set of parenthesis, closure expect the first element inside the parenthsesis to be a vector (within brackets). However in this case, the first element is ([x] x) which is a list and not a vector. This is the error you get.

like image 110
Nicolas Dudebout Avatar answered Jan 13 '23 18:01

Nicolas Dudebout