lazy evals + parameter passing

Chris Nicholson-Sauls ibisbasenji at gmail.com
Mon Sep 4 12:25:07 PDT 2006


Jari-Matti Mäkelä wrote:
> Hi, I've been away for a while working with Ruby.
> 
> It seems the D spec is now extended with lazy evaluation of function
> arguments. Very nice indeed.
> 
> I tried to search the ng but haven't seen any mention about 'yield' in
> the context of lazy evals. Currently I think the implementation is only
> half ready or then I've forgotten how to program in D :) See, some Ruby here
> 
> def inject(list, n)
>  list.each { |v| n = yield(n, v) }
>  return n
> end
> 
> def sum(list)
>  return inject(list, 0) { |n, v| n + v }
> end
> 
> sum( [1,2,3] )
> 
> => 6
> 
> If I understand this correctly, currently D only supports yield's
> without arguments when used with anonymous delegates (Ok, it's lacking
> multiple return values too, but those can be simulated easily). The
> point is that the caller _can_ actually send parameters to the delegate,
> but there's no way to receive arguments from the sender. Is it too
> expensive to extend current lazy evals with arguments in a systems
> programming language like D? Does it even require the use of tuples?
> 
> I think it's fully possible by introducing |par1, ..., parn | syntax so that
> 
> { | a, b | a+b }
> 
> would be the same as
> 
> int _anonymous(inout a, inout b) {
>   return a+b;
> }
> 
> What do you think? Does it look ugly? Doesn't it offer a great deal of
> new functionality. I think we really NEED this - please Walter, make it
> pre-1.0 :)

First, D's interesting new Lazy feature is really not like Ruby's Block feature at all -- 
although I for one wouldn't mind seeing something like yielding show up in D.  Instead, 
Lazy is primarily about affirming that an expression will not be evaluated until it is 
neccessary to do so.  In other words, that you could for example pass a complicated string 
expression to a function which MAY or MAY NOT output that string somewhere.  Lazy 
evaluation promises you that the string won't get processed unless that function DOES 
output it.

That noted, of course, they do behave essentially as delegates (and internally ARE 
delegates I believe) and so the given expression MAY be evaluated multiple times.  One 
would have to note the documentation for the function in question before relying on or 
protecting against any side effects.

Second, the new anonymous delegate syntax already gives us more-or-less what you want 
except for two missing items: a delegate body containing nothing but an expression should 
get an implicit 'return ... ;' wrapped around it, yielding capability.

     { | a, b | a + b }
is actually
     (a,b){ a + b }

I'm also not positive if type inferance would handle this case or not, so it may more 
correctly be:
     (int a, int b){ a + b }

-- Chris Nicholson-Sauls



More information about the Digitalmars-d mailing list