currj
currj copied to clipboard
Currying in Clojure
currj
currj is an experiment in currying and partial evaluation in Clojure. It currently attempts to support function calls, if, and let. It's not very well tested, so if you want to use it for something serious you should probably check the output manually.
currj has been pronounced "Courage".
Goals
- Support for all pure functions.
- Emit code that is no less efficient than a hand-curried function.
- Support ClojureScript
Example Expansion
Small Example
;; original
(currj/fn [a b]
(+ b (* (dec a)
(+ 88 42))))
;; simplified (readable) expansion
(let
[G__2256 (+ 88 42)]
(fn
([a] (let [G__2257 (* (dec a) G__2256)]
(fn [b] (+ b G__2257))))
([a b] (+ b (* (dec a) G__2256)))))
;; actual expansion
(let*
[G__2256 (+ 88 42)]
(fn*
([a] (let* [G__2257 (* (dec a) G__2256)] (fn* ([b] (+ b G__2257)))))
([a b] (+ b (* (dec a) G__2256)))))
Bigger Example
;; original
(currj/fn
[a b c]
(let [d (+ a b)
my-constant (* 2 Math/PI)]
(if (pos? a)
(- c (* d d))
(let [e (inc a)] (/ e c)))))
;; simplified (more readable) expansion
(let
[my-constant (* 2 Math/PI)]
(fn
([a]
(let
[if-condition2492 (pos? a)
e (if-not if-condition2492
(inc a)
nil)]
(fn
([b]
(let
[d (+ a b)
if-condition2494 if-condition2492
G__2495 (if if-condition2494 (* d d))]
(fn ([c] (if if-condition2494
(- c G__2495)
(/ e c))))))
([b c]
(let
[d (+ a b)]
(if if-condition2492
(- c (* d d))
(/ e c)))))))
([a b]
(let
[d (+ a b)
if-condition2497 (pos? a)
G__2498 (if if-condition2497 (* d d))
e (if-not if-condition2497
(inc a)
nil)]
(fn ([c] (if if-condition2497
(- c G__2498)
(/ e c))))))
([a b c]
(let
[d (+ a b)]
(if (pos? a)
(- c (* d d))
(let [e (inc a)]
(/ e c)))))))
;; actual expansion
(let*
[my-constant (* 2 Math/PI)]
(fn*
([a]
(let*
[if-condition2492
(pos? a)
e
(if (clojure.core/not if-condition2492) (inc a) nil)]
(fn*
([b]
(let*
[d
(+ a b)
if-condition2494
if-condition2492
G__2495
(if if-condition2494 (* d d))]
(fn* ([c] (if if-condition2494 (- c G__2495) (/ e c))))))
([b c]
(let*
[d (+ a b)]
(if if-condition2492 (- c (* d d)) (/ e c)))))))
([a b]
(let*
[d
(+ a b)
if-condition2497
(pos? a)
G__2498
(if if-condition2497 (* d d))
e
(if (clojure.core/not if-condition2497) (inc a) nil)]
(fn* ([c] (if if-condition2497 (- c G__2498) (/ e c))))))
([a b c]
(let*
[d (+ a b)]
(if (pos? a) (- c (* d d)) (let* [e (inc a)] (/ e c)))))))
Usage
(require '[currj.core :as currj])
(def f (currj/fn [x y] (+ y (* 2 x))))
(def g (f 5))
(g 3) ;; => 13
(g -8) ;; => 2
;; the * function was only called once
TODO
- Implement
fn*
- Clojurescript support
License
Copyright (C) 2012 Gary Fredericks
Distributed under the Eclipse Public License, the same as Clojure.