Lazy eval

Walter Bright newshound at digitalmars.com
Mon Aug 21 20:54:36 PDT 2006


Derek Parnell wrote:
> On Mon, 21 Aug 2006 19:41:24 -0700, Walter Bright wrote:
> 
>> Derek Parnell wrote:
>>> On Mon, 21 Aug 2006 16:33:00 -0700, Walter Bright wrote:
>>>> The problem with requiring the { } around the argument is that 
>>>> programmers just don't like it. I don't think I can make them like it.
>>> Huh? You asked them all? You didn't ask me and I like it. 
>> Did you use it before 0.165? 
> 
> Yes. However I couldn't release it in Build until GDC caught up to the
> ability, so I took it out again.
> 
>> Did anyone? Everyone I'd show the { } 
>> syntax to reacted with zzzzzz. 
> 
> I didn't.

Ok.

>> I show them the one without, and all of a 
>> sudden they are excited about it and can think of all kinds of uses.
> And so am I, but now I *also* wary of the pitfalls that this implicit
> conversion to delegates open up.

It's good to be wary of unusual new features. There are usually 
unanticipated problems with them.


>> C++ programmers have been trying to do this for over a decade - first 
>> with preprocessor macros, and now with expression templates.
> And do I give a toss about C++ programming foibles ;-)

LOL! But expression templates, horrible hack that they are, are often 
listed as the reason C++ is so powerful and therefore why should one 
change? Expression templates are how C++ does "domain specific 
languages" and David Abraham explains them to packed conference rooms. 
So I believe there is a serious demand for them, but not the way C++ 
does it, as probably only 5 people on the planet are able to create a 
DNS using them.

With the lazy evaluation thing, though, writing DNSs becomes simple and 
straightforward, which may (just may) catapult D forward like defmac 
rescued Lisp from oblivion.


> Not sure about that. I see the problem with existing calls to functions
> suddenly behaving differently with no apparent reason. With this new
> ability, a library writer can change the interface and my program will
> still compile, but may now behave in unexpected ways.

He can do that anyway - I've already enumerated several ways. But 
there's been an awful lot of threads here that boil down to adding more 
information to the function declaration so that it's easier for the user 
to see what is happening. (And it's a little hard to hide a delegate 
declaration!)

I should also point out that:
	void foo(int x);
and:
	void foo(int delegate() x);
will have different name mangling. So if you change the library, and 
don't recompile the user code, it won't link.


> Let's assume the original API said 
> 
>    void SomeFunc(char[] x);
> 
> so I code ...
> 
>  void xyzzy(inout x)
>  {
>     char[] r = std.string.format("%d", x);
>     x++;
>  }
>  . . .
>  int y = 7;
>  SomeFunc( std.string.format("The number is " ~ xyzzy(y)) );
> 
> 
> Then the library writer changes this to 
> 
>    void SomeFunc(char[] delegate() x);
> 
> My code still compiles but there is now no guarantee that my xyzzy()
> function will be called. The API function may chose to not call it for some
> reason valid to itself. But I'm left scratching my head trying to work out
> why my variable 'y' is sometimes being updated and other times not.

Suppose there's an API function:

	void anotherFunc(int x);

which I call:

	int y = 3;
	anotherFunc(y);
	writefln(y);

then the library writer changes the API to:

	void anotherFunc(inout int x);

and internally increments x. I'm left wondering why 4 is now being 
printed instead of 3.

Changing an API and thereby breaking (obviously or subtly) the user code 
is as old as programming ("DLL hell" is a term probably older than many 
programmers!). The only answer I can think of is, if you must change the 
API of a function, and you have legacy users of it, give the changed one 
a new name and tag the old name with 'deprecated'.



More information about the Digitalmars-d mailing list