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