Tuesday, October 9, 2012

Clojure Map function

I came across one of the quiz from 4clojure, it asks us to reimplement interleave.
=> (interleave [:a :b :c] [1 2 3])
(:a 1 :b 2 :c 3)
After I solve this quiz with a long solution, I looked at the other people solution. One of the solution that impressed me somewhat similar to this
=> (apply concat (map vector [:a :b :c] [1 2 3]))
(:a 1 :b 2 :c 3)
If we run only evaluate Map part, the result looks like this
=> (map vector [:a :b :c] [1 2 3])
([:a 1] [:b 2] [:c 3])
I had hard time to understand that. I got a question in my head. "Of what reason, why Map function take element of 2 vector (3th, 4th parameters) one by one?" It turns out that this is a Clojure Map function behavior.

Then I realized that the reason why I don't easily get that because all functional programming style syntaxes that I have played with, Map functional only takes 1 argument.

Look at Ruby code.
=> [1, 2, 3].map { |i| i + 1 }
[2, 3, 4]  
But for Clojure's Map function, it takes variable arguments and behave like what I explained earlier.
=> (map inc [1 2 3])
(2 3 4) 
=> (map + [1 2 3] [4 5 6])
(5 7 9)
Another question I had was "Can we archive the same variable arguments behavior with Object-Oriented style?"
The answer is No because we can only calling a method to 1 object. But of course, you can archive this with OO language but in functional way like this.
map(->x,y{ x+y }, [1,2,3], [4,5,6])
This examples might look trivial but if we look at it carefully it represents fundamental differences between OO languages and functional languages. For OO language, our method call is a mechanism of passing message to an object. But for functional language, it's just a function call.

No comments:

[PostgreSQL] How to create read-only standby replica (follower)

This link  and this link explain it really well and concise