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
> ----------------------------------------------------------------
>
>

Reply via email to