The incorrect error message for a wrong number of arguments should also be easy to fix. Just remove the (x^ ... . w) line of the cases macro. But then you lose the rest argument when you want it, so it's a slightly less but still easy fix: make that line dependent on whether the call to lambda* had a rest argument. (If the efficiency is attractive enough to you, I'm sure you'll write this into your library =P)
I'm not sure about the "lots of distinct procedures" point. Because I would actually expect lambda* to be used quite a lot. I'm imagining someone essentially renames lambda* to lambda, and maybe there would also be a library (perhaps based on cut/cute) that re-exports (rnrs) procedures as curried versions. However since Ikarus expands everything to case-lambda anyway, maybe there are optimizations in place such that having long case-lambdas isn't as expensive as you think? I don't know - it does seem likely that you'll need to allocate all those tiny procedures... The number you also need to consider (along with the number of uses of lambda*) is how many arguments procedures usually have. It's usually << 10, so the number of lines never gets huge. On Wed, May 27, 2009 at 8:09 PM, Derick Eddington <[email protected]> wrote: > On Wed, 2009-05-27 at 17:24 +1000, Ramana Kumar wrote: >> anonymous curried procedures? >> >> also, is your curry better than my case-lambda approach? yours is >> about the same amount of code, and possibly more efficient... I don't >> know > > Problems I see with yours: > >> (define f0 (lambda* (a b c) (+ a b c))) >> (f0 1 2 3 4) > Unhandled exception > Condition components: > 1. &assertion > 2. &who: apply > 3. &message: "not a procedure" > 4. &irritants: (6) >> (import (xitomatl curry)) >> (define/curry (f1 a b c) (+ a b c)) >> (f1 1 2 3 4) > Unhandled exception > Condition components: > 1. &assertion > 2. &who: apply > 3. &message: "incorrect number of arguments" > 4. &irritants: (#<procedure> 4) >> > > - It creates a lot of new distinct procedures (not just allocating > closures of the same underlying procedure). Probably not a concern > because they're tiny and there won't be a ton of uses of your lambda*, > but it has the potential to bloat space with tons of redundant > procedures. > > - It doesn't support zero or "rest"-only arguments. But that's easy to > change. > > But yours is significantly faster: > >> (define f0 (lambda* (a b c d e f g) 1)) >> (define f1 (lambda/curry (a b c d e f g) 1)) >> (define-syntax bigloop > (syntax-rules () > ((_ expr ...) > (do ((i #e1e7 (- i 1))) > ((fx= i 0)) > expr ...)))) >> (time (bigloop)) > running stats for (bigloop): > no collections > 116 ms elapsed cpu time, including 0 ms collecting > 143 ms elapsed real time, including 0 ms collecting > 0 bytes allocated >> (time (bigloop ((((f0 1 2) 3) 4 5 6) 7))) > running stats for (bigloop ((((f0 1 2) 3) 4 5 6) 7)): > 191 collections > 1597 ms elapsed cpu time, including 64 ms collecting > 1878 ms elapsed real time, including 91 ms collecting > 800004096 bytes allocated >> (time (bigloop ((((f1 1 2) 3) 4 5 6) 7))) > running stats for (bigloop ((((f1 1 2) 3) 4 5 6) 7)): > 726 collections > 10925 ms elapsed cpu time, including 192 ms collecting > 12392 ms elapsed real time, including 261 ms collecting > 3040004096 bytes allocated >> > > -- > : Derick > ---------------------------------------------------------------- > >
