[racket] a question of style, and one of performance

From: Jordan Schatz (jordan at noionlabs.com)
Date: Mon Jan 9 16:08:54 EST 2012

> Can you give an example of such a language?  I'm curious.
Unfortunately I forget which one, I recall that the reason given was that
since the default value couldn't be determined at compile time the
compiler was unable to optimize functions with such default arguments.

Much of my work is in PHP, and in it you can only use simple values (no
variables, functions, class methods etc) as default function arguments.

-Jordan

On Sun, Jan 08, 2012 at 03:42:51PM -0500, Danny Yoo wrote:
> On Sun, Jan 8, 2012 at 3:23 PM, Jordan Schatz <jordan at noionlabs.com> wrote:
> > This code runs, but I'm guessing that its not the "right way" to do it.
> >
> > (define (js-date [i (current-date)])
> >  (let ([original-format (date-display-format)]
> >        [return ((λ ()
> >                     (date-display-format 'rfc2822)
> >                     (date->string i #t)))])
> >    (date-display-format original-format)
> >    return))
> >
> > 1) In "some other language" using a function as the default value for an
> > argument is inefficient and frowned upon. Is that the case in racket?
> 
> Hi Jordan,
> 
> Can you give an example of such a language?  I'm curious.
> 
> I'm not sure where the inefficiency would come from, unless computing
> the default value expression's value is costly.
> 
> According to the documentation in:
> 
> http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket/private/base..rkt)._lambda))
> 
> with regards to "default-expr": "... if no such argument is provided,
> the default-expr is evaluated to produce a value associated with id."
> 
> >From the reference docs, it sounds like that, unlike a language like
> Python, the default value is evaluated for every use of the function,
> rather than just once when the function's defined.  We can experiment
> with this:
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> #lang racket
> (define (test [x (begin
>                    (printf "I'm evaluating at: ~a\n"
> (current-inexact-milliseconds))
>                    1)])
>   (add1 x))
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> If you run test, you'll see that the default-expr is being evaluated
> for each call to test that depends on the default argument.
> 
> 
> If it is expensive to compute the default expression, we can bind a
> value to a variable, and then refer to that variable instead for the
> default expression.  That way, the expression is just name lookup,
> which is constant-cost.  Functions are named values, so I don't think
> they'd be particularly expensive to use as default expressions.


Posted on the users mailing list.