On May 31, 1:55 am, Daniel Lyons <fus...@storytotell.org> wrote:
> On May 30, 2009, at 7:25 PM, kinghajj wrote:
>
>
>
> > On May 30, 1:19 pm, Daniel Lyons <fus...@storytotell.org> wrote:
> >> You can't have both partial application and variable arity functions.
>
> > Uh, yeah you can. Haskell can have variadic functions, like
> > Text.Printf.printf, and with some explicit type signatures you can
> > still partially apply it.
>
> Taking (+) as an example, or any other function with an & rest
> argument, how would your version of Clojure know when to return a
> value and when to return a function of yet another argument?
>
> —
> Daniel Lyonshttp://www.storytotell.org-- Tell It!
On May 31, 1:55 am, Daniel Lyons <fus...@storytotell.org> wrote:
> On May 30, 2009, at 7:25 PM, kinghajj wrote:
>
>
>
> > On May 30, 1:19 pm, Daniel Lyons <fus...@storytotell.org> wrote:
> >> You can't have both partial application and variable arity functions.
>
> > Uh, yeah you can. Haskell can have variadic functions, like
> > Text.Printf.printf, and with some explicit type signatures you can
> > still partially apply it.
>
> Taking (+) as an example, or any other function with an & rest
> argument, how would your version of Clojure know when to return a
> value and when to return a function of yet another argument?
>
> —
> Daniel Lyonshttp://www.storytotell.org-- Tell It!
Two ways that I can think of, the first is to return a value only when
we evaluate with zero arguments, as in Hiredman's 'uncurry' function:
http://tinyurl.com/mrvely
(defn uncurry
"applied to a function it returns a function that will continue
partially applying until it is called with no arguments"
[x]
(fn uc [& y]
(if (seq y)
(uncurry (apply partial x y))
(x))))
(((((uncurry +) 10) 92 83) 90)) ;=> 275
We might also choose to return a value when a special function closing
value is used in the final parameter position:
(defn end-curry "Like above, but returns value when last argument is
()"
[f]
(fn [& y]
(if (= (last y) ())
(apply f (drop-last y))
(end-curry (apply partial f y)))))
((((end-curry +) 110) 192 183) 181 ()) ; => 666
This doesn't give automatic behaviour with fixed arity functions.
However, that's just a little extra logic. God help us if we try to
profile these functions :)
kinghajj, the printf technique is a surprising application of type
classes, but it still feels like a terrible hack when used, IMO, as
evidenced by your need for explicit type declarations. You're
basically creating a 2 parameter instance of some printf type class,
no? Which gives me an idea of how we can do the same thing!
(defn curry-n "Continuously curries a function through multiple
calls,
untill at least n arguments have been received,
then returns value"
([f n]
(fn [& y]
(let [safe-count (count (take n y))]
(if (< safe-count n)
(curry-n (apply partial f y) (- n safe-count))
(apply f (take n y)))))))
now we can write horribly nasty things like
(apply ((apply (curry-n + 200000) (take 10000 (repeatedly rand)))
-9000) (repeatedly rand))
which are probably better off written as
(- (reduce + (take 200000 (repeatedly rand))) 9000),
but note we can apply an 'n-curried' function to an infinite sequence
and it doesn't complain:
(apply ((((curry-n + 2000) 1 2 3 4 5) 6 7) 8) (iterate inc 9))
And Hajj, we can kind of translate your haskell to
(def print-hello ((curry-n printf 2) "Hello %s")
(print-hello "my baby!")
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---