Let’s compose some arguments

Clojure has some good support for functional programming. We’ve already looked at anonymous functions.
user=> (fn [x y] (* x y))
#<user$eval__181$fn__183 user$eval__181$fn__183@e61fd1>
user=> (*1 2 3)
6
Here we used *1 which is bound to the last result in the read-eval-print loop, *2 is bound to the result before that and *3 is bound to the one before that.

Functions can be written to take a variable number of arguments by binding an argument to a sequence of all arguments after a given point.
user=> (fn [x y & z] z)
#<user$eval__232$fn__234 user$eval__232$fn__234@cf66b>
user=> (*1 1)
java.lang.IllegalArgumentException: Wrong number of args passed to: user$eval–232$fn (NO_SOURCE_FILE:0)
user=> (*1 1 2)
nil
user=> (*2 1 2 3)
(3)
user=> (*3 1 2 3 4 5)
(3 4 5)

There is good support for dealing with higher order functions. The first, partial, partially applies a function to some arguments producing another function that can be applied to the additional arguments.
user=> (defn addAll[x y z] (+ x y z))
#’user/addAll
user=> (partial addAll 1)
#<core$partial__2880$fn__2882 clojure.core$partial__2880$fn__2882@1884174>
user=> (*1 2 3)
6
user=> (partial addAll 2 3)
#<core$partial__2880$fn__2886 clojure.core$partial__2880$fn__2886@baa466>
user=> (*1 4)
9

Partial is defined in core.clj as
(defn partial
  ([f arg1]
   (fn [& args] (apply f arg1 args)))
  ([f arg1 arg2]
   (fn [& args] (apply f arg1 arg2 args)))
  ([f arg1 arg2 arg3]
   (fn [& args] (apply f arg1 arg2 arg3 args)))
  ([f arg1 arg2 arg3 & more]
   (fn [& args] (apply f arg1 arg2 arg3 (concat more args)))))

comp composes the functions, applying the rightmost first and then applying the next function to the result.
user=> (comp (fn [x] (- x 1)) (partial * 2))
#<core$comp__2874$fn__2876 clojure.core$comp__2874$fn__2876@134b07e>
user=> (*1 5)
9

comp is also defined in core.clj
(defn comp
  [& fs]
    (let [fs (reverse fs)]
      (fn [& args]
        (loop [ret (apply (first fs) args) fs (next fs)]
          (if fs
            (recur ((first fs) ret) (next fs))
            ret)))))

One other possibly useful function is eval which takes a Clojure form and evaluates it. It does this by compiling it and running the result. Eval is useful is rare occasions, but often it is better not to use it.
user=> (eval ‘(defn bar[x] x))
#’user/bar
user=> (eval ‘(bar 20))
20

This is implemented by calling into the code for the Compiler.
(defn eval
  [form] (. clojure.lang.Compiler (eval form)))

Advertisements
This entry was posted in Computers and Internet. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s