[racket-dev] Expansion of optional arguments in lambda
Sounds like a good thing to add to test suite!
Robby
On Sun, Feb 24, 2013 at 2:04 PM, Eric Dobson <eric.n.dobson at gmail.com>wrote:
> I think I figured out the actual answer which is semantics. If the
> arguments are ever set!ed then my implementation will lead to a different
> value.
>
> (define (f a (b (begin (set! a 2) 3)))
> a)
>
> This should return 2 if b is not supplied, but in my expansion it would
> return what ever was supplied for a.
>
>
> On Sun, Feb 24, 2013 at 11:14 AM, Matthew Flatt <mflatt at cs.utah.edu>wrote:
>
>> At Sun, 24 Feb 2013 09:51:12 -0800, Eric Dobson wrote:
>> > lambda supports optional arguments, and does this by expanding out into
>> a
>> > core form that has flag arguments for if each argument is supplied.
>> This is
>> > tricky to type in TR and so I was investigating why it did it this way.
>> I
>> > did a micro benchmark on another method of expansion and it was 60%
>> faster.
>> > Is there a reason that racket does it the current way that I am missing.
>> >
>> > #lang racket
>> >
>> > (define f
>> > (case-lambda
>> > (() (f 1))
>> > ((a) (f a (+ 3 a)))
>> > ((a b) (f a b (* a b)))
>> > ((a b c) (f a b c (- a (/ c b))))
>> > ((a b c d) (+ a b c d))))
>> >
>> > (define (g (a 1) (b (+ 3 a)) (c (* a b)) (d (- a (/ c b))))
>> > (+ a b c d))
>>
>> I'll have to investigate more, but I don't think the story is simple.
>>
>> Below are the decompiled forms, and you'll see that they're essentially
>> the same, due to inlining and other compiler optimizations.
>>
>> Part of the answer is probably how the different forms interact with
>> inlining in the timing loops. If I change the code to
>>
>> (define-values (f g)
>> (let ()
>> (define f ....)
>> (define g ....)
>> (values f g)))
>>
>> (set! f f)
>> (set! g g)
>>
>> after the definition of `g', then performance is the same for the `f'
>> and `g' (with a tiny difference that may be due to the order of clauses
>> in `f' and `g').
>>
>> You may also want to look at performance in the case that the eventual
>> body cannot be inlined (e.g., because it's too large). Then, I think the
>> chain of applications for `f' will probably be significantly worse than
>> the more direct implementation of `g'.
>>
>> ----------------------------------------
>>
>> (define-values
>> (_f)
>> (case-lambda
>> (()
>> '#(/private/tmp/c.rkt:5:4 #<path:/private/tmp/c.rkt> 5 4 44 10 #t)
>> '(flags: preserves-marks single-result)
>> '9)
>> ((arg0-12)
>> '#(/private/tmp/c.rkt:6:4 #<path:/private/tmp/c.rkt> 6 4 59 19 #t)
>> '(flags: preserves-marks single-result)
>> (let ((local13 (+ '3 arg0-12)))
>> (let ((local16 (* arg0-12 local13)))
>> (+ arg0-12 local13 local16 (- arg0-12 (/ local16 local13))))))
>> ((arg0-27 arg1-28)
>> '#(/private/tmp/c.rkt:7:4 #<path:/private/tmp/c.rkt> 7 4 83 23 #t)
>> '(flags: preserves-marks single-result)
>> (let ((local29 (* arg0-27 arg1-28)))
>> (+ arg0-27 arg1-28 local29 (- arg0-27 (/ local29 arg1-28)))))
>> ((arg0-40 arg1-41 arg2-42)
>> '#(/private/tmp/c.rkt:8:4 #<path:/private/tmp/c.rkt> 8 4 111 33 #t)
>> '(flags: preserves-marks single-result)
>> (+ arg0-40 arg1-41 arg2-42 (- arg0-40 (/ arg2-42 arg1-41))))
>> ((arg0-51 arg1-52 arg2-53 arg3-54)
>> '#(/private/tmp/c.rkt:9:4 #<path:/private/tmp/c.rkt> 9 4 149 23 #t)
>> '(flags: preserves-marks single-result)
>> (+ arg0-51 arg1-52 arg2-53 arg3-54))))
>>
>> (define-values
>> (_g)
>> (case-lambda
>> (() '(flags: preserves-marks single-result) '9)
>> ((arg0-59 arg1-60 arg2-61 arg3-62)
>> '(flags: preserves-marks single-result)
>> (+ arg0-59 arg1-60 arg2-61 arg3-62))
>> ((arg0-67 arg1-68 arg2-69)
>> '(flags: preserves-marks single-result)
>> (+ arg0-67 arg1-68 arg2-69 (- arg0-67 (/ arg2-69 arg1-68))))
>> ((arg0-78 arg1-79)
>> '(flags: preserves-marks single-result)
>> (let ((local80 (* arg0-78 arg1-79)))
>> (+ arg0-78 arg1-79 local80 (- arg0-78 (/ local80 arg1-79)))))
>> ((arg0-91)
>> '(flags: preserves-marks single-result)
>> (let ((local92 (+ '3 arg0-91)))
>> (let ((local95 (* arg0-91 local92)))
>> (+ arg0-91 local92 local95 (- arg0-91 (/ local95
>> local92)))))))))
>>
>>
>>
>
> _________________________
> Racket Developers list:
> http://lists.racket-lang.org/dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20130224/24e38253/attachment.html>