www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - DMD 0.165 release

reply Walter Bright <newshound digitalmars.com> writes:
I was going to call this 1.0 RC1, but I just could not resist adding the 
lazy expression evaluation. This adds one of the big capabilities of 
common lisp.

http://www.digitalmars.com/d/changelog.html
Aug 20 2006
next sibling parent Derek Parnell <derek nomail.afraid.org> writes:
On Sun, 20 Aug 2006 21:32:37 -0700, Walter Bright wrote:

 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

Wow! Neat ... but ... So now you'll be working on getting the Docs synchronized with the compiler and adding the "missing" bits, right? Then RC1 can emerge? -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 21/08/2006 2:57:27 PM
Aug 20 2006
prev sibling next sibling parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

Simply WOW ! I can't wait to use the feature. Btw, I think there is a bug in the Enforce example... IMO It should look more like in this test case: import std.stdio; class Spam { void ham() { writefln("ham() called !"); } } T Enforce(T)(T delegate() p, char[] msg) { writefln("entering Enforce()"); auto res = p(); if (!res) throw new Exception(msg); return res; } Spam foo(int a, int b) { writefln("entering foo()"); if (a == b) return new Spam; else return null; } void main() { Enforce(foo(1, 1), "omigosh !").ham(); Enforce(foo(1, 2), "omigosh !").ham(); } -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/
Aug 20 2006
parent Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Tom S wrote:
 Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

Simply WOW ! I can't wait to use the feature. Btw, I think there is a bug in the Enforce example... IMO It should look more like in this test case: import std.stdio; class Spam { void ham() { writefln("ham() called !"); } } T Enforce(T)(T delegate() p, char[] msg) { writefln("entering Enforce()"); auto res = p(); if (!res) throw new Exception(msg); return res; } Spam foo(int a, int b) { writefln("entering foo()"); if (a == b) return new Spam; else return null; } void main() { Enforce(foo(1, 1), "omigosh !").ham(); Enforce(foo(1, 2), "omigosh !").ham(); }

Ooops maybe I'm too sleepy. You probably meant Enforce to look like this: T Enforce(T)(T p, char[] delegate() msg) { if (!p) throw new Exception(msg()); return p; } That would make more sense, as the message is lazily evaluated then...
Aug 20 2006
prev sibling next sibling parent Niko Korhonen <niktheblak hotmail.com> writes:
Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.

Whoa! Really, I'm speechless! I've been toying around with Haskell a lot recently and I really like this feature in D. Thanks, Walter! -- Niko Korhonen SW Developer
Aug 20 2006
prev sibling next sibling parent Reiner Pope <reiner.pope REMOVE.THIS.gmail.com> writes:
Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

That's just great! Cool.
Aug 20 2006
prev sibling next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

Awesome. Two observations: * Together with lambda delegate type inference, it seems that delegates are becoming the central language idiom of D. It's not just an improved C++ any more, I think a whole new programming style is developing. * Andrei's involvement in D seems to be increasing. Can we expect him to publish some D code soon?
Aug 20 2006
next sibling parent reply Walter Bright <newshound digitalmars.com> writes:
Don Clugston wrote:
 * Together with lambda delegate type inference, it seems that delegates 
 are becoming the central language idiom of D. It's not just an improved 
 C++ any more, I think a whole new programming style is developing.

Inner classes, nested functions, delegates, and closures are all closely related. The only thing missing in D is the full generality of closures; once we have that I think D can do what Lisp does, but with a much more palatable syntax.
 * Andrei's involvement in D seems to be increasing. Can we expect him to 
 publish some D code soon?

Andrei is one of the few original thinkers in programming. With D he's been generous with his ideas and critiques, but he's pretty wrapped up with his university studies.
Aug 21 2006
parent reply "Tony" <ignorethis nowhere.com> writes:
"Walter Bright" <newshound digitalmars.com> wrote in message 
news:ecbodc$1v70$1 digitaldaemon.com...
 Don Clugston wrote:
 * Together with lambda delegate type inference, it seems that delegates 
 are becoming the central language idiom of D. It's not just an improved 
 C++ any more, I think a whole new programming style is developing.

Inner classes, nested functions, delegates, and closures are all closely related. The only thing missing in D is the full generality of closures; once we have that I think D can do what Lisp does, but with a much more palatable syntax.

I think serious Lispniks would disagree with the above statement (I'm not one of them by the way). However, I find it really encouraging that you are comparing D with Lisp and obviously gaining some important insights into language design as a result. I was concerned that your goal was to create a better C++, rather than a better LANGUAGE, but this is obviously not the case anymore (if it ever was). One advantage of Lisp (which is not present in D) is Lisps removal of the artificial boundary between compile time and runtime capabilities. Put another way, because code and data share a common form in Lisp (the list, which is in fact a form of parse tree), Lisp provides easy access to runtime code generation. I'm at a loss as to how a similar capability could be made available in D. However, if this were possible then I believe you would have created something truly revolutionary. D really has become a very interesting language. Thankyou Walter. Tony Melbourne, Australia tonys - mailbox at hotmail.com
Aug 21 2006
parent Walter Bright <newshound digitalmars.com> writes:
Tony wrote:
 "Walter Bright" <newshound digitalmars.com> wrote in message 
 news:ecbodc$1v70$1 digitaldaemon.com...
 Don Clugston wrote:
 * Together with lambda delegate type inference, it seems that delegates 
 are becoming the central language idiom of D. It's not just an improved 
 C++ any more, I think a whole new programming style is developing.

related. The only thing missing in D is the full generality of closures; once we have that I think D can do what Lisp does, but with a much more palatable syntax.

I think serious Lispniks would disagree with the above statement (I'm not one of them by the way).

Of course they would <g>.
 However, I find it really encouraging that you are comparing D with Lisp and 
 obviously gaining some important insights into language design as a result. 
 I was concerned that your goal was to create a better C++, rather than a 
 better LANGUAGE, but this is obviously not the case anymore (if it ever 
 was).

What catches my interest about Lisp are the folks (like Paul Graham) who claim huge productivity gains from it. Despite such, however, Lisp has failed to gain mainstream acceptance. Maybe D could adopt some of the things that make Lisp so productive, and leave behind the stuff that inhibits Lisp from getting traction. defmac is often trotted out as a big productivity gainer in Lisp, because with it one can define one's own syntax. D's lazy evaluation does the equivalent.
 One advantage of Lisp (which is not present in D) is Lisps removal of the 
 artificial boundary between compile time and runtime capabilities.  Put 
 another way, because code and data share a common form in Lisp (the list, 
 which is in fact a form of parse tree), Lisp provides easy access to runtime 
 code generation.
 
  I'm at a loss as to how a similar capability could be made available in D. 
 However, if this were possible then I believe you would have created 
 something truly revolutionary.

I think that would be D 3.0 <g>.
 D really has become a very interesting language.  Thankyou Walter.

You're welcome.
Aug 21 2006
prev sibling parent Niko Korhonen <niktheblak hotmail.com> writes:
Don Clugston wrote:
 It's not just an improved 
 C++ any more, I think a whole new programming style is developing.

Yes. It's called 'functional programming' <g> -- Niko Korhonen SW Developer
Aug 21 2006
prev sibling next sibling parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
The supplied example:

void foo()
{
     int v = 2;
     cond
     (
	scase(v == 1, writefln("it is 1")),
	scase(v == 2, writefln("it is 2")),
	scase(v == 3, writefln("it is 3")),
	scase(true,   writefln("it is the default"))
     );
}

Gives errors: 'voids have no value'. It works when writefln is changed 
to printf, as it returns an int... It would be cool if voids were also 
allowed to be lazy.


--
Tomasz Stachowiak
Aug 21 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Tom S wrote:
 The supplied example:
 
 void foo()
 {
     int v = 2;
     cond
     (
     scase(v == 1, writefln("it is 1")),
     scase(v == 2, writefln("it is 2")),
     scase(v == 3, writefln("it is 3")),
     scase(true,   writefln("it is the default"))
     );
 }
 
 Gives errors: 'voids have no value'. It works when writefln is changed 
 to printf, as it returns an int... It would be cool if voids were also 
 allowed to be lazy.

That's what I get for changing the code at the last minute. :-(
Aug 21 2006
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Walter Bright wrote:
 Tom S wrote:
 The supplied example:

 void foo()
 {
     int v = 2;
     cond
     (
     scase(v == 1, writefln("it is 1")),
     scase(v == 2, writefln("it is 2")),
     scase(v == 3, writefln("it is 3")),
     scase(true,   writefln("it is the default"))
     );
 }

 Gives errors: 'voids have no value'. It works when writefln is changed 
 to printf, as it returns an int... It would be cool if voids were also 
 allowed to be lazy.

That's what I get for changing the code at the last minute. :-(

:) I get voids have no value for the dotimes example on line: dotimes(10, writef(x++));
Aug 21 2006
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Ivan Senji wrote:
 Walter Bright wrote:
 Tom S wrote:
 The supplied example:

 void foo()
 {
     int v = 2;
     cond
     (
     scase(v == 1, writefln("it is 1")),
     scase(v == 2, writefln("it is 2")),
     scase(v == 3, writefln("it is 3")),
     scase(true,   writefln("it is the default"))
     );
 }

 Gives errors: 'voids have no value'. It works when writefln is 
 changed to printf, as it returns an int... It would be cool if voids 
 were also allowed to be lazy.

That's what I get for changing the code at the last minute. :-(

:) I get voids have no value for the dotimes example on line: dotimes(10, writef(x++));

Hmmm, In trying to get the example to work i tried dotimes(10, (writef(x++),0)); To turn the expression to something other than void but now it prints: [int]0[int]1[int]2[int]3[int]4[int]5[int]6[int]7[int]8[int]9 and I can't understand why is this happening?
Aug 21 2006
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Ivan Senji wrote:
 Ivan Senji wrote:
 Walter Bright wrote:
 Tom S wrote:
 The supplied example:

 void foo()
 {
     int v = 2;
     cond
     (
     scase(v == 1, writefln("it is 1")),
     scase(v == 2, writefln("it is 2")),
     scase(v == 3, writefln("it is 3")),
     scase(true,   writefln("it is the default"))
     );
 }

 Gives errors: 'voids have no value'. It works when writefln is 
 changed to printf, as it returns an int... It would be cool if voids 
 were also allowed to be lazy.

That's what I get for changing the code at the last minute. :-(

:) I get voids have no value for the dotimes example on line: dotimes(10, writef(x++));

Hmmm, In trying to get the example to work i tried dotimes(10, (writef(x++),0)); To turn the expression to something other than void but now it prints: [int]0[int]1[int]2[int]3[int]4[int]5[int]6[int]7[int]8[int]9 and I can't understand why is this happening?

LOL, try this one: dotimes(10, (writefln("%d %s %f", ++i, new Object, 3.14159f), 0));
Aug 21 2006
parent Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Tom S wrote:
 Ivan Senji wrote:
 To turn the expression to something other than void but
 now it prints:
 [int]0[int]1[int]2[int]3[int]4[int]5[int]6[int]7[int]8[int]9
 and I can't understand why is this happening?

LOL, try this one: dotimes(10, (writefln("%d %s %f", ++i, new Object, 3.14159f), 0));

LOL, cool! :)
Aug 21 2006
prev sibling next sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
Hmmm... what does the last example about Enforce have to do with lazy 
evaluation?

It seems like a nice idea, etc., but I can actually run it already 
without upgrading to 0.165.....?

Does really sound nice, though :).

-[Unknown]


 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

Aug 21 2006
next sibling parent Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Unknown W. Brackets wrote:
 Hmmm... what does the last example about Enforce have to do with lazy 
 evaluation?
 
 It seems like a nice idea, etc., but I can actually run it already 
 without upgrading to 0.165.....?
 
 Does really sound nice, though :).

See my second reply to this thread... the point is that 'msg' should be char[] delegate(). Then you can supply an expression to Enforce, e.g. Enforce(a == b, toString(a) ~ " != " ~ toString(b)); and it will only be evaluated in the case when a != b, thus making your code faster. -- Tomasz Stachowiak
Aug 21 2006
prev sibling parent Walter Bright <newshound digitalmars.com> writes:
Unknown W. Brackets wrote:
 Hmmm... what does the last example about Enforce have to do with lazy 
 evaluation?

The expression shouldn't be evaluated if the error happens.
 It seems like a nice idea, etc., but I can actually run it already 
 without upgrading to 0.165.....?

Yes, if you put the delegate part as { return exp; } instead of just exp.
Aug 21 2006
prev sibling next sibling parent Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

This is just beautiful, thanks! thanks! thanks!
Aug 21 2006
prev sibling next sibling parent Kristian <kjkilpi gmail.com> writes:
On Mon, 21 Aug 2006 07:32:37 +0300, Walter Bright  
<newshound digitalmars.com> wrote:

 I was going to call this 1.0 RC1, but I just could not resist adding the  
 lazy expression evaluation. This adds one of the big capabilities of  
 common lisp.

 http://www.digitalmars.com/d/changelog.html

I was very impressed by D... Now I am very much more! :) I hope D will have a great impact on the programming language field. At least D deserves it! Actually I will not be surprised to see if D will be THE programming language someday... It'll take time and work, sure. (Companies will act a lot slower, of course, than individuals.) But hey, maybe after 5-7 years... :)
Aug 21 2006
prev sibling next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter Bright wrote:

 I was going to call this 1.0 RC1, but I just could not resist adding  [...]

Will there be a "Beta" period, between the current Alphas and Release ? Just thought it was a bit quick to start announcing Release Candidates right after the D features had been frozen, but maybe that's just me. --anders
Aug 21 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Anders F Björklund wrote:
 Walter Bright wrote:
 
 I was going to call this 1.0 RC1, but I just could not resist adding  
 [...]

Will there be a "Beta" period, between the current Alphas and Release ? Just thought it was a bit quick to start announcing Release Candidates right after the D features had been frozen, but maybe that's just me.

I don't think there's a need for a beta period. D's already in heavy use, we know what state it's in.
Aug 21 2006
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter Bright wrote:

 Will there be a "Beta" period, between the current Alphas and Release ?

I don't think there's a need for a beta period.

Maybe just a quick breather then, to let GDC catch up ? :-) Specifically I was talking about a "feature freeze" time.
 D's already in heavy use, we know what state it's in.

Or "was in", just finished updating my import statements... (didn't notice on my GDC, since it was at DMD 0.162 still) --anders
Aug 21 2006
parent Walter Bright <newshound digitalmars.com> writes:
Anders F Björklund wrote:
 Walter Bright wrote:
 
 Will there be a "Beta" period, between the current Alphas and Release ?

I don't think there's a need for a beta period.

Maybe just a quick breather then, to let GDC catch up ? :-) Specifically I was talking about a "feature freeze" time.
 D's already in heavy use, we know what state it's in.

Or "was in", just finished updating my import statements... (didn't notice on my GDC, since it was at DMD 0.162 still)

I was careful to do the lazy evaluation entirely in the front end, so integration with GDC should be as easy as possible.
Aug 21 2006
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

Is there any chance my post entitled "No way to selectively expose imported symbols using 163" in d.D could be addressed or at least considered before RC1? It would have a slight impact on the wording describing selective import if so. Here is a direct link to the post: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=40811 Sean
Aug 21 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Sean Kelly wrote:
 Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

Is there any chance my post entitled "No way to selectively expose imported symbols using 163" in d.D could be addressed or at least considered before RC1? It would have a slight impact on the wording describing selective import if so. Here is a direct link to the post: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digita mars.D&artnum=40811

I think that's just a compiler bug, not a design problem.
Aug 21 2006
parent Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

Is there any chance my post entitled "No way to selectively expose imported symbols using 163" in d.D could be addressed or at least considered before RC1? It would have a slight impact on the wording describing selective import if so. Here is a direct link to the post: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digita mars.D&artnum=40811

I think that's just a compiler bug, not a design problem.

Just wanted to make sure, since this would affect the wording in the spec :-) Sean
Aug 21 2006
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

Nice work! I'm not sure I understand the advantage offered to the enforcement example however, unless it is in creating the message string (a benefit that was already demonstrated). Where is the lazy evaluation occurring? Sean
Aug 21 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Sean Kelly wrote:
 Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

Nice work! I'm not sure I understand the advantage offered to the enforcement example however, unless it is in creating the message string (a benefit that was already demonstrated). Where is the lazy evaluation occurring?

The example has typos in it, but the advantage is to not evaluate the msg (which can be arbitrarily complex) unless an error actually occurs.
Aug 21 2006
parent reply Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

Nice work! I'm not sure I understand the advantage offered to the enforcement example however, unless it is in creating the message string (a benefit that was already demonstrated). Where is the lazy evaluation occurring?

The example has typos in it, but the advantage is to not evaluate the msg (which can be arbitrarily complex) unless an error actually occurs.

Thanks. I suppose it's worth mentioning that lazy evaluation can result in some confusing errors similar to those encountered with macro functions vs. normal functions. For example: void fn( char delegate() ch ) { if( ch() == 'c' || ch() == 'd' ) { printf( "match\n" ); } } size_t pos = 0; char[] buf = "abdc"; fn( buf[++pos] ); The above code would print "match" because pos would be incremented twice. This makes API changes from the classic to lambda syntax a risky venture, as it risks silently breaking once-working code. Sean
Aug 21 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Sean Kelly wrote:
 Thanks.  I suppose it's worth mentioning that lazy evaluation can result 
 in some confusing errors similar to those encountered with macro 
 functions vs. normal functions.  For example:
 
     void fn( char delegate() ch )
     {
         if( ch() == 'c' || ch() == 'd' )
         {
             printf( "match\n" );
         }
     }
 
     size_t pos = 0;
     char[] buf = "abdc";
 
     fn( buf[++pos] );
 
 The above code would print "match" because pos would be incremented 
 twice.  This makes API changes from the classic to lambda syntax a risky 
 venture, as it risks silently breaking once-working code.

It doesn't break existing once-working code, because the example shown will not compile with 0.164 and earlier compilers.
Aug 21 2006
next sibling parent reply Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 Thanks.  I suppose it's worth mentioning that lazy evaluation can 
 result in some confusing errors similar to those encountered with 
 macro functions vs. normal functions.  For example:

     void fn( char delegate() ch )
     {
         if( ch() == 'c' || ch() == 'd' )
         {
             printf( "match\n" );
         }
     }

     size_t pos = 0;
     char[] buf = "abdc";

     fn( buf[++pos] );

 The above code would print "match" because pos would be incremented 
 twice.  This makes API changes from the classic to lambda syntax a 
 risky venture, as it risks silently breaking once-working code.

It doesn't break existing once-working code, because the example shown will not compile with 0.164 and earlier compilers.

I was thinking more of converting an API call from: void fn( char ch ); to: void fn( char delegate() ch ); Both accept the same parameters under DMD 165, but the result may be different. But this is something library developers simply must keep in mind more than a problem with the technique itself. It would be easy enough to document how the supplied delegate is evaluated. Sean
Aug 21 2006
parent Walter Bright <newshound digitalmars.com> writes:
Sean Kelly wrote:
 I was thinking more of converting an API call from:
 
     void fn( char ch );
 
 to:
 
     void fn( char delegate() ch );
 
 Both accept the same parameters under DMD 165, but the result may be 
 different.  But this is something library developers simply must keep in 
 mind more than a problem with the technique itself.  It would be easy 
 enough to document how the supplied delegate is evaluated.

That's true, but I expect the library developer to be cognizant of how his changes affect user code, and make the right choices.
Aug 21 2006
prev sibling parent reply Frank Benoit <keinfarbton nospam.xyz> writes:
 It doesn't break existing once-working code, because the example shown
 will not compile with 0.164 and earlier compilers.

It does if you had before both: void fn( char delegate() ch ){...} void fn( char ch ){...} is now ambiguous for the call, so the only option is to remove the second proto.
Aug 21 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Frank Benoit wrote:
 It doesn't break existing once-working code, because the example shown
 will not compile with 0.164 and earlier compilers.

It does if you had before both: void fn( char delegate() ch ){...} void fn( char ch ){...} is now ambiguous for the call, so the only option is to remove the second proto.

That's right.
Aug 21 2006
parent reply Derek Parnell <derek psyc.ward> writes:
On Mon, 21 Aug 2006 12:47:01 -0700, Walter Bright wrote:

 Frank Benoit wrote:
 It doesn't break existing once-working code, because the example shown
 will not compile with 0.164 and earlier compilers.

It does if you had before both: void fn( char delegate() ch ){...} void fn( char ch ){...} is now ambiguous for the call, so the only option is to remove the second proto.

That's right.

And yet so wrong too. -- Derek Parnell Melbourne, Australia "Down with mediocrity!"
Aug 21 2006
parent Walter Bright <newshound digitalmars.com> writes:
Derek Parnell wrote:
 On Mon, 21 Aug 2006 12:47:01 -0700, Walter Bright wrote:
 
 Frank Benoit wrote:
 It doesn't break existing once-working code, because the example shown
 will not compile with 0.164 and earlier compilers.

void fn( char delegate() ch ){...} void fn( char ch ){...} is now ambiguous for the call, so the only option is to remove the second proto.


And yet so wrong too.

That would be so wrong if such overloads were common. But I can't think of much of any cases where one would want to write such overloads.
Aug 21 2006
prev sibling next sibling parent =?ISO-8859-1?Q?=22R=E9my_J=2E_A=2E_Mou=EBza=22?= writes:
Walter Bright a écrit :
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

better it tastes. And what about const by default ? I may have missed some of the discussion : I thought something related to it would be decided before 1.0 but don't know anything about such a decision. ( And there is no clue about the fate of the auto keyword : will it be turned into a local or var keyword before 1.0 ? ) Does it means that all these features will be « post 1.0 » ?
Aug 21 2006
prev sibling next sibling parent reply BCS <BCS pathlink.com> writes:
Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

cool, I like it given void foo(char[]); void foo(char[] delegate()); how do I force the use of the first? char[][] fig; int i = 10; fig.length = i; while(i) foo(fig[--i]); // --i must be evaluated
Aug 21 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
BCS wrote:
 Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

cool, I like it given void foo(char[]); void foo(char[] delegate()); how do I force the use of the first?

You can't. Think of it like: void foo(in int x); void foo(out int y); void foo(inout int z); Can't force the use of one of those, either.
Aug 21 2006
next sibling parent reply BCS <BCS pathlink.com> writes:
Walter Bright wrote:
 BCS wrote:
 
 Walter Bright wrote:

 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

cool, I like it given void foo(char[]); void foo(char[] delegate()); how do I force the use of the first?

You can't.

Ouch! That could be bad where the evaluation of the expression has side effects or is time (when not how long) critical. volatile char* vcp; log("data is now: "~(vcp[0..10].dup)); Will the (char[]) form ever get called? Any expression can be converted into a anon-delegate, so anything that would work for the first, also works for the second. How is one picked over the other? This seems to be an "oddity" in the overload rules.
Aug 21 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
BCS wrote:
 Walter Bright wrote:
 BCS wrote:
 given

 void foo(char[]);
 void foo(char[] delegate());

 how do I force the use of  the first?


That could be bad where the evaluation of the expression has side effects or is time (when not how long) critical. volatile char* vcp; log("data is now: "~(vcp[0..10].dup)); Will the (char[]) form ever get called?

It won't compile, as it'll give an ambiguity error.
 Any expression can be converted into a anon-delegate, so anything that 
 would work for the first, also works for the second. How is one picked 
 over the other?
 This seems to be an "oddity" in the overload rules.

It just gives an ambiguity error at compile time.
Aug 21 2006
parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Walter Bright wrote:
 BCS wrote:
 Walter Bright wrote:
 BCS wrote:
 given

 void foo(char[]);
 void foo(char[] delegate());

 how do I force the use of  the first?


That could be bad where the evaluation of the expression has side effects or is time (when not how long) critical. volatile char* vcp; log("data is now: "~(vcp[0..10].dup)); Will the (char[]) form ever get called?

It won't compile, as it'll give an ambiguity error.
 Any expression can be converted into a anon-delegate, so anything that 
 would work for the first, also works for the second. How is one picked 
 over the other?
 This seems to be an "oddity" in the overload rules.

It just gives an ambiguity error at compile time.

Why not (just as the in-out-inout case) give an error when the overloads are defined, instead of just when calling? Because if one will not be able to call the char[] version then it might as well be an error right then.
Aug 22 2006
parent reply BCS <BCS pathlink.com> writes:
Bruno Medeiros wrote:
 Walter Bright wrote:

 It just gives an ambiguity error at compile time.

Why not (just as the in-out-inout case) give an error when the overloads are defined, instead of just when calling? Because if one will not be able to call the char[] version then it might as well be an error right then.

IIRC the in-out-inout case can't be done at the declaration, same goes for other overloads <code name="a.d"> void foo(in char); </code> <code name="b.d"> void foo(out char); </code> <code> import a; import b; ... char c; a.foo(c); //ok b.foo(c); //ok foo(c); //error </code> <code> import a; ... char c; foo(c); //ok </code> you can't always tell if there is a collision until the call is made
Aug 22 2006
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
BCS wrote:
 Bruno Medeiros wrote:
 Walter Bright wrote:

 It just gives an ambiguity error at compile time.

Why not (just as the in-out-inout case) give an error when the overloads are defined, instead of just when calling? Because if one will not be able to call the char[] version then it might as well be an error right then.

IIRC the in-out-inout case can't be done at the declaration, same goes for other overloads <code name="a.d"> void foo(in char); </code> <code name="b.d"> void foo(out char); </code> <code> import a; import b; .... char c; a.foo(c); //ok b.foo(c); //ok foo(c); //error </code> <code> import a; .... char c; foo(c); //ok </code> you can't always tell if there is a collision until the call is made

Those are not considered overloads. By "those" I mean that functions from different namespaces are never considered as overloads of one another, and always result in collisions, even if the functions signatures are overload-compatible, such as foo(int) and foo(char). *Proper* overloads are only when the functions are from the same namespace. (with mixins being an uncertain case, but that's another story)
Aug 24 2006
prev sibling parent reply Derek Parnell <derek psyc.ward> writes:
On Mon, 21 Aug 2006 11:06:12 -0700, Walter Bright wrote:

 BCS wrote:
 Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

cool, I like it given void foo(char[]); void foo(char[] delegate()); how do I force the use of the first?

You can't. Think of it like: void foo(in int x); void foo(out int y); void foo(inout int z); Can't force the use of one of those, either.

But why is that *not* a problem with the language? -- Derek Parnell Melbourne, Australia "Down with mediocrity!"
Aug 21 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Derek Parnell wrote:
 On Mon, 21 Aug 2006 11:06:12 -0700, Walter Bright wrote:
 
 BCS wrote:
 given

 void foo(char[]);
 void foo(char[] delegate());

 how do I force the use of  the first?

void foo(in int x); void foo(out int y); void foo(inout int z); Can't force the use of one of those, either.

But why is that *not* a problem with the language?

A good question. I think the answer is that one would be want to overload based on in/out/inout only to write obfuscated code.
Aug 21 2006
parent reply BCS <BCS pathlink.com> writes:
Walter Bright wrote:
 Derek Parnell wrote:
 
 On Mon, 21 Aug 2006 11:06:12 -0700, Walter Bright wrote:

 BCS wrote:

 given

 void foo(char[]);
 void foo(char[] delegate());

 how do I force the use of  the first?

You can't. Think of it like: void foo(in int x); void foo(out int y); void foo(inout int z); Can't force the use of one of those, either.

But why is that *not* a problem with the language?

A good question. I think the answer is that one would be want to overload based on in/out/inout only to write obfuscated code.

but the lazy vs. non-lazy question isn't so simple log(RunSQLStuff()); vs. log("This is a string"); ???
Aug 21 2006
next sibling parent reply Walter Bright <newshound digitalmars.com> writes:
BCS wrote:
 Walter Bright wrote:
 Derek Parnell wrote:

 On Mon, 21 Aug 2006 11:06:12 -0700, Walter Bright wrote:

 BCS wrote:

 given

 void foo(char[]);
 void foo(char[] delegate());

 how do I force the use of  the first?

You can't. Think of it like: void foo(in int x); void foo(out int y); void foo(inout int z); Can't force the use of one of those, either.

But why is that *not* a problem with the language?

A good question. I think the answer is that one would be want to overload based on in/out/inout only to write obfuscated code.

but the lazy vs. non-lazy question isn't so simple log(RunSQLStuff()); vs. log("This is a string"); ???

I don't see what the problem is?
Aug 21 2006
parent Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 BCS wrote:
 Walter Bright wrote:
 Derek Parnell wrote:

 On Mon, 21 Aug 2006 11:06:12 -0700, Walter Bright wrote:

 BCS wrote:

 given

 void foo(char[]);
 void foo(char[] delegate());

 how do I force the use of  the first?

You can't. Think of it like: void foo(in int x); void foo(out int y); void foo(inout int z); Can't force the use of one of those, either.

But why is that *not* a problem with the language?

A good question. I think the answer is that one would be want to overload based on in/out/inout only to write obfuscated code.

but the lazy vs. non-lazy question isn't so simple log(RunSQLStuff()); vs. log("This is a string"); ???

I don't see what the problem is?

I think the problem here might be that it would be more efficient if the latter case were not processed through a delegate wrapper. Sean
Aug 22 2006
prev sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
If you always want the SQL stuff run, you have to do it separately.

But it goes back to this:

if (logging)
	log(RunSQLStuff());

You wouldn't make that mistake.  Given the name of log(), assuming it is 
properly named, and your understanding of D, assuming you don't think 
it's just C, you should be able to put 2 and 2 together.

Anyway, I would suggest that RunSQLStuff() shouldn't return a loggable 
string, because that's just silly.  It should make log() calls itself. 
If you can't change that, it's really unlikely you'll have it returning 
a string worth logging anyway.

But that's specific to this case.

-[Unknown]


 Walter Bright wrote:
 Derek Parnell wrote:

 On Mon, 21 Aug 2006 11:06:12 -0700, Walter Bright wrote:

 BCS wrote:

 given

 void foo(char[]);
 void foo(char[] delegate());

 how do I force the use of  the first?

You can't. Think of it like: void foo(in int x); void foo(out int y); void foo(inout int z); Can't force the use of one of those, either.

But why is that *not* a problem with the language?

A good question. I think the answer is that one would be want to overload based on in/out/inout only to write obfuscated code.

but the lazy vs. non-lazy question isn't so simple log(RunSQLStuff()); vs. log("This is a string"); ???

Aug 22 2006
parent BCS <BCS pathlink.com> writes:
Unknown W. Brackets wrote:
 If you always want the SQL stuff run, you have to do it separately.
 
 But it goes back to this:
 
 if (logging)
     log(RunSQLStuff());
 

replace RunSQLStuff() with VaryLongRunningFunction()
Aug 22 2006
prev sibling next sibling parent reply kris <foo bar.com> writes:
Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

We could already do "lazy expression eval" in D, using dmd164 delegates; sans new sugar. So that Lisp ability was already present? I like a bit of sugar as much as anyone, especially when it's part of some classy dark-chocolate. But there's some practical issues with this most recent syntactic sugar. The overload issue is a real one, and the added complexity of having to manually check a callee declaration before you can grok what happens to an expression arg will also become a realisitic problem. Particularly so when you happen to miss a method overload in some subclass somewhere. In this specific case, I suspect there needs to be an indication of some kind, at the call site, to clearly and unambiguously communicate to a person (and to the compiler) exactly what is going on. Otherwise, this may be just the kind of sugar that rots the teeth of D ?
Aug 21 2006
next sibling parent reply Walter Bright <newshound digitalmars.com> writes:
kris wrote:
 Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

We could already do "lazy expression eval" in D, using dmd164 delegates; sans new sugar. So that Lisp ability was already present?

Yes. But few to nobody noticed it, and I'll posit that this bit of sugar will expand its use by a couple orders of magnitude.
 I like a bit of sugar as much as anyone, especially when it's part of 
 some classy dark-chocolate. But there's some practical issues with this 
 most recent syntactic sugar. The overload issue is a real one, and the 
 added complexity of having to manually check a callee declaration before 
 you can grok what happens to an expression arg will also become a 
 realisitic problem. Particularly so when you happen to miss a method 
 overload in some subclass somewhere.

D (and other languages) already have that with in, out, inout, implicit conversions, all the proposals for const, mutable, and other storage classes. C++ has it for reference types, const types, implicit conversions, etc. You already cannot tell what is happening with the arguments without looking at the prototype. I'll also point out that C/C++ programs routinely use macros to do the equivalent (and much worse).
 In this specific case, I suspect there needs to be an indication of some 
 kind, at the call site, to clearly and unambiguously communicate to a 
 person (and to the compiler) exactly what is going on.

There already was (and is) in the form of { return exp; }. It's just not accepted - I can hardly count all the comments I get from people saying D didn't support this capability, and when I point out the { return exp; }, they frown like people do when you tell them broccoli is good for them.
 Otherwise, this 
 may be just the kind of sugar that rots the teeth of D ?

Maybe, but I haven't seen any food stores carry the Odwalla vegetable juice for years <g>. I do understand your concern, and I think I understand the issues. Only time and experience will tell us definitively if this is the right move or not, but my gut tells me it is. I *do* know that this has a "gee whiz" aspect to it that gets peoples' attention, and that's good for D to help it develop its own clear place in the panopoly of programming languages.
Aug 21 2006
next sibling parent reply kris <foo bar.com> writes:
Walter Bright wrote:
 kris wrote:
 
 Walter Bright wrote:

 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

We could already do "lazy expression eval" in D, using dmd164 delegates; sans new sugar. So that Lisp ability was already present?

Yes. But few to nobody noticed it, and I'll posit that this bit of sugar will expand its use by a couple orders of magnitude.
 I like a bit of sugar as much as anyone, especially when it's part of 
 some classy dark-chocolate. But there's some practical issues with 
 this most recent syntactic sugar. The overload issue is a real one, 
 and the added complexity of having to manually check a callee 
 declaration before you can grok what happens to an expression arg will 
 also become a realisitic problem. Particularly so when you happen to 
 miss a method overload in some subclass somewhere.

D (and other languages) already have that with in, out, inout, implicit conversions, all the proposals for const, mutable, and other storage classes. C++ has it for reference types, const types, implicit conversions, etc. You already cannot tell what is happening with the arguments without looking at the prototype. I'll also point out that C/C++ programs routinely use macros to do the equivalent (and much worse).
 In this specific case, I suspect there needs to be an indication of 
 some kind, at the call site, to clearly and unambiguously communicate 
 to a person (and to the compiler) exactly what is going on.

There already was (and is) in the form of { return exp; }. It's just not accepted - I can hardly count all the comments I get from people saying D didn't support this capability, and when I point out the { return exp; }, they frown like people do when you tell them broccoli is good for them.

Yes; would be nice to eliminate the return and the secondary ';' so it looks like # somefunk ({++i}); # # rather than # # somefunk ({return ++i;}); Quite a difference, and both are still explicit rather than introducing ambiguity. Or, use some kind of operator instead, like c# does? # somefunk (=> ++i);
 
 Otherwise, this may be just the kind of sugar that rots the teeth of D ?

Maybe, but I haven't seen any food stores carry the Odwalla vegetable juice for years <g>. I do understand your concern, and I think I understand the issues. Only time and experience will tell us definitively if this is the right move or not, but my gut tells me it is. I *do* know that this has a "gee whiz" aspect to it that gets peoples' attention, and that's good for D to help it develop its own clear place in the panopoly of programming languages.

Perhaps ;) I should point out that any and all of that "Gee Whiz" will be immediately countered with a "Hrm, there's a lot of ambiguity here", as you've seen already from those who are perhaps the biggest supporters of D The detractment of ambiguity should not be underestimated, and can be surely be avoided (in this case) with an adjustment here or there?
Aug 21 2006
next sibling parent BCS <BCS pathlink.com> writes:
kris wrote:
 Walter Bright wrote:
 There already was (and is) in the form of { return exp; }. It's just 
 not accepted - I can hardly count all the comments I get from people 
 saying D didn't support this capability, and when I point out the { 
 return exp; }, they frown like people do when you tell them broccoli 
 is good for them.

Yes; would be nice to eliminate the return and the secondary ';' so it looks like # somefunk ({++i}); # # rather than # # somefunk ({return ++i;}); Quite a difference, and both are still explicit rather than introducing ambiguity. Or, use some kind of operator instead, like c# does? # somefunk (=> ++i);

I second this. I'm not sure that syntax would be best but some sort of /explicit/ syntax to make an expression into a delegate (a /shorthand/ for the {return exp;}, not another "convention") would be much less confusing. options: (Just off the top of my head) op Expression op ( Expression ) op == one of: "&", " ", "^", "$", "\" The &(exp) form looks interesting: "take the address of this R-value". Kinda sounds right. Have to think on that.
Aug 21 2006
prev sibling next sibling parent Reiner Pope <reiner.pope REMOVE.THIS.gmail.com> writes:
kris wrote:
 There already was (and is) in the form of { return exp; }. It's just 
 not accepted - I can hardly count all the comments I get from people 
 saying D didn't support this capability, and when I point out the { 
 return exp; }, they frown like people do when you tell them broccoli 
 is good for them.


a really cool feature, and although I knew it could be done with delegates in D, it seemed somehow wrong to me. An official rubber-stamp from the spec saying 'lazy evaluation is officially supported in D, using this syntax' breaks the mental block for me.
 
 
 Yes; would be nice to eliminate the return and the secondary ';' so it 
 looks like
 
 # somefunk ({++i});
 #
 # rather than
 #
 # somefunk ({return ++i;});
 
 Quite a difference, and both are still explicit rather than introducing 
 ambiguity. Or, use some kind of operator instead, like c# does?
 
 # somefunk (=> ++i);
 
 

I think that something explicit, yet short, like this is good because it makes clear what is going on, while keeping the gee whiz factor because you can say, 'D supports lazy evaluation: look at the => (or whatever) operator'.
Aug 21 2006
prev sibling next sibling parent reply Pragma <ericanderton yahoo.removeme.com> writes:
kris wrote:
 
 # somefunk ({++i});
 #
 # rather than
 #
 # somefunk ({return ++i;});
 
 Quite a difference, and both are still explicit rather than introducing 
 ambiguity. Or, use some kind of operator instead, like c# does?
 
 # somefunk (=> ++i);
 

Here's my $0.02. I just noticed this: import std.stdio; void foobar(char[] x){ writefln("x is a string: '%s'",x); } void foobar(char[] delegate() x){ writefln("x is a delegate: '%s'",x()); } void main(){ foobar("value"); foobar(cast(char[] delegate())("value")); //<=== note the cast() } ... which outputs: x is a string: 'value' x is a delegate: 'value' I was quite happy to find that this is a valid workaround, and that the result of the cast() isn't automatically resolved to the first variant of foobar(). As Kris has mentioned, having some way to cast an expression to a delegate /explicitly/ while still using some kind of shorthand would really help seal the deal here. After all, cast() is really only used to circumvent implicit casting and to resolve type matching ambiguities - both of which are present in the current implicit expr-to-delegate conversion scheme. I also feel that such an addition can quite happily co-exist with the current feature-set we have. I'm not too crazy about '=>' but something like using {} without an embedded return (as others have mentioned) might be the right trick. As long as it has the same behavior as the explicit cast() above, it has my vote. foobar("value"); foobar({"value"}); It's subtle, yet impossible to confuse for anything else. The only remaining problem is that casting a delegate in the /other direction/ fails void main(){ foobar({ return cast(char[])"value"; }); foobar(cast(char[]){ return cast(char[])"value"; }); } test.d(18): function test.foobar called with argument types: (char[]) matches both: test5.foobar(char[]) and: test5.foobar(char[] delegate()) I would expect cast() to disable the implicit expression/delegate conversion, as my first example seems to do this already. Instead it allows a match for the delegate version of foobar() which is the same as saying "its okay to implicitly convert me back to a delegate" even though it was explicitly converted to something else. I'm sure there's some kind of happy medium to be found between explicit and implicit conversions when finding a match for a given contract. However, I don't think we're there yet. -- - EricAnderton at yahoo
Aug 22 2006
next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Pragma wrote:
 kris wrote:
 # somefunk ({++i});
 #
 # rather than
 #
 # somefunk ({return ++i;});

 Quite a difference, and both are still explicit rather than 
 introducing ambiguity. Or, use some kind of operator instead, like c# 
 does?

 # somefunk (=> ++i);

Here's my $0.02. I just noticed this: import std.stdio; void foobar(char[] x){ writefln("x is a string: '%s'",x); } void foobar(char[] delegate() x){ writefln("x is a delegate: '%s'",x()); } void main(){ foobar("value"); foobar(cast(char[] delegate())("value")); //<=== note the cast() } ... which outputs: x is a string: 'value' x is a delegate: 'value' I was quite happy to find that this is a valid workaround, and that the result of the cast() isn't automatically resolved to the first variant of foobar(). As Kris has mentioned, having some way to cast an expression to a delegate /explicitly/ while still using some kind of shorthand would really help seal the deal here. After all, cast() is really only used to circumvent implicit casting and to resolve type matching ambiguities - both of which are present in the current implicit expr-to-delegate conversion scheme. I also feel that such an addition can quite happily co-exist with the current feature-set we have. I'm not too crazy about '=>' but something like using {} without an embedded return (as others have mentioned) might be the right trick. As long as it has the same behavior as the explicit cast() above, it has my vote. foobar("value"); foobar({"value"}); It's subtle, yet impossible to confuse for anything else. The only remaining problem is that casting a delegate in the /other direction/ fails void main(){ foobar({ return cast(char[])"value"; }); foobar(cast(char[]){ return cast(char[])"value"; }); } test.d(18): function test.foobar called with argument types: (char[]) matches both: test5.foobar(char[]) and: test5.foobar(char[] delegate()) I would expect cast() to disable the implicit expression/delegate conversion, as my first example seems to do this already. Instead it allows a match for the delegate version of foobar() which is the same as saying "its okay to implicitly convert me back to a delegate" even though it was explicitly converted to something else. I'm sure there's some kind of happy medium to be found between explicit and implicit conversions when finding a match for a given contract. However, I don't think we're there yet.

Changing the first foobar to this doesn't work however: foobar("some" ~ "value"); // or: foobar("value: " ~ aFooBarMessage.toString())
Aug 22 2006
prev sibling parent reply Carlos Santander <csantander619 gmail.com> writes:
Pragma escribió:
 
 I'm not too crazy about '=>' but something like using {} without an 
 embedded return (as others have mentioned) might be the right trick.  As 
 long as it has the same behavior as the explicit cast() above, it has my 
 vote.
 
 foobar("value");
 foobar({"value"});
 
 It's subtle, yet impossible to confuse for anything else.
 

I also want it to be explicit someway, and I liked {} but what if struct initializers get added? (did I get my wording right?) struct A { char [] txt; } void foo (char [] txt) {} // #1 void foo (char [] delegate () dg) {} // #2 void foo (A a) {} // #3 ... foo ({"hi!"}); How does the compiler know which one we want? Casting would be an option, but I think it'd be too verbose most of the time. So, while I don't like => either, some other operator along those lines maybe better. Following the previous example: foo ("hi!") // calls #1 foo ({"hi!"}); // calls #3 foo (=> "hi!"); // calls #2 Ok, maybe => doesn't look so bad after all :P -- Carlos Santander Bernal
Aug 22 2006
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Carlos Santander wrote:
 Pragma escribió:
 I'm not too crazy about '=>' but something like using {} without an 
 embedded return (as others have mentioned) might be the right trick.  
 As long as it has the same behavior as the explicit cast() above, it 
 has my vote.

 foobar("value");
 foobar({"value"});

 It's subtle, yet impossible to confuse for anything else.

I also want it to be explicit someway, and I liked {} but what if struct initializers get added? (did I get my wording right?) struct A { char [] txt; } void foo (char [] txt) {} // #1 void foo (char [] delegate () dg) {} // #2 void foo (A a) {} // #3 .... foo ({"hi!"}); How does the compiler know which one we want? Casting would be an option, but I think it'd be too verbose most of the time. So, while I don't like => either, some other operator along those lines maybe better. Following the previous example: foo ("hi!") // calls #1 foo ({"hi!"}); // calls #3 foo (=> "hi!"); // calls #2 Ok, maybe => doesn't look so bad after all :P

I have to agree with this, => does keep looking better and better..
Aug 23 2006
parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Ivan Senji wrote:
 Carlos Santander wrote:
 Pragma escribió:
 I'm not too crazy about '=>' but something like using {} without an 
 embedded return (as others have mentioned) might be the right trick.  
 As long as it has the same behavior as the explicit cast() above, it 
 has my vote.

 foobar("value");
 foobar({"value"});

 It's subtle, yet impossible to confuse for anything else.

I also want it to be explicit someway, and I liked {} but what if struct initializers get added? (did I get my wording right?) struct A { char [] txt; } void foo (char [] txt) {} // #1 void foo (char [] delegate () dg) {} // #2 void foo (A a) {} // #3 .... foo ({"hi!"}); How does the compiler know which one we want? Casting would be an option, but I think it'd be too verbose most of the time. So, while I don't like => either, some other operator along those lines maybe better. Following the previous example: foo ("hi!") // calls #1 foo ({"hi!"}); // calls #3 foo (=> "hi!"); // calls #2 Ok, maybe => doesn't look so bad after all :P

I have to agree with this, => does keep looking better and better..

Ideally, a syntax should also support declaring single expression delegates with arguments. (int a){a+1} (int a) => a+1 And in the future, possibly type inferred: (a){a+1} a => a+1 (a,b){a+b} a,b => a+b /Oskar
Aug 23 2006
parent Sai <leo303161 yahoo.com> writes:
Oskar Linde wrote:
 Ideally, a syntax should also support declaring single expression 
 delegates with arguments.
 
 (int a){a+1}
 (int a) => a+1
 
 And in the future, possibly type inferred:
 (a){a+1}
 a => a+1
 
 (a,b){a+b}
 a,b => a+b
 
 /Oskar

This looks like syntax from Maple, which I use all the time in Maple. cool. http://www.bl.physik.tu-muenchen.de/rechner/maple/program/subsection3_4_3.html Sai
Aug 23 2006
prev sibling next sibling parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
kris wrote:
 # somefunk ({++i});

I'm a big fan of this syntax, since we (or, at least, I) already associate {} with "block of code". I'm very excited about this development (even without any explicit syntax) but I, too, worry about ambiguities. My gut says that if we don't make this explicit, we're going to be bitten by it later, when somebody stumbles upon some strange circumstance where the situation is truly *ambiguous*, or -worse yet- the code does something different than what would seem to be the obvious thing. We don't have the example yet...but if we omit the explicit syntax, then it's going to be hard to fix when we find those examples.
Aug 22 2006
prev sibling parent Sai <leo303161 yahoo.com> writes:
I vote for func({expr})
which is short form for func({ return expr;})

func(expr) is too ambiguous & confusing for good maintanance

Sai


kris wrote:
 Yes; would be nice to eliminate the return and the secondary ';' so it 
 looks like
 
 # somefunk ({++i});
 #
 # rather than
 #
 # somefunk ({return ++i;});
 
 Quite a difference, and both are still explicit rather than introducing 
 ambiguity. Or, use some kind of operator instead, like c# does?
 
 # somefunk (=> ++i);
 
 

Aug 22 2006
prev sibling parent reply Lars Ivar Igesund <larsivar igesund.net> writes:
Walter Bright wrote:
 
 We could already do "lazy expression eval" in D, using dmd164 delegates;
 sans new sugar. So that Lisp ability was already present?

Yes. But few to nobody noticed it, and I'll posit that this bit of sugar will expand its use by a couple orders of magnitude.

 
 In this specific case, I suspect there needs to be an indication of some
 kind, at the call site, to clearly and unambiguously communicate to a
 person (and to the compiler) exactly what is going on.

There already was (and is) in the form of { return exp; }. It's just not accepted - I can hardly count all the comments I get from people saying D didn't support this capability, and when I point out the { return exp; }, they frown like people do when you tell them broccoli is good for them.

I keep wondering who you hear all these things from, because the feelings I got from staying around the IRC channel, and reading the NG, is that people in general is overly excited by the possibilities of the previous lambda syntax, and that it was in fact this excitement that prompted the thread on whether the frames should be allocated on stack or heap, escape analysis, etc. Are you sure that such a feature will really cause an onrush if it's delivered by an disclaimer? And how do you explain that broccoli is the _only_ vegetable my son enjoys to eat? ;) -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi
Aug 21 2006
parent Walter Bright <newshound digitalmars.com> writes:
Lars Ivar Igesund wrote:
 Walter Bright wrote:
 We could already do "lazy expression eval" in D, using dmd164 delegates;
 sans new sugar. So that Lisp ability was already present?

will expand its use by a couple orders of magnitude.

 In this specific case, I suspect there needs to be an indication of some
 kind, at the call site, to clearly and unambiguously communicate to a
 person (and to the compiler) exactly what is going on.

accepted - I can hardly count all the comments I get from people saying D didn't support this capability, and when I point out the { return exp; }, they frown like people do when you tell them broccoli is good for them.

I keep wondering who you hear all these things from, because the feelings I got from staying around the IRC channel, and reading the NG, is that people in general is overly excited by the possibilities of the previous lambda syntax, and that it was in fact this excitement that prompted the thread on whether the frames should be allocated on stack or heap, escape analysis, etc.

I am pretty excited myself about the possibilities of delegates, and it grows every time there's a simplification in using them. NGs aren't the only thing I participate in; around here there's an active community of programmers who like to meet and chitchat about programming over coffee or beer. I occasionally get invited to a corporation to talk about D and listen to what they want and need. Being able to talk to people in 3D land makes it a lot easier to get a feel for what catches peoples' interest, not the least of which is they'll say things they'll never be caught dead writing on a NG post <g>.
 Are you sure that such a feature will really cause an onrush if it's
 delivered by an disclaimer?

I'm not sure. But I want to give it a shot.
 And how do you explain that broccoli is the
 _only_ vegetable my son enjoys to eat? ;)

I wouldn't presume to understand that <g>.
Aug 22 2006
prev sibling parent Georg Wrede <georg nospam.org> writes:
kris wrote:
 Walter Bright wrote:
 
 I was going to call this 1.0 RC1, but I just could not resist adding 
 the lazy expression evaluation. This adds one of the big capabilities 
 of common lisp.

 http://www.digitalmars.com/d/changelog.html

We could already do "lazy expression eval" in D, using dmd164 delegates; sans new sugar. So that Lisp ability was already present? I like a bit of sugar as much as anyone, especially when it's part of some classy dark-chocolate. But there's some practical issues with this most recent syntactic sugar. The overload issue is a real one, and the added complexity of having to manually check a callee declaration before you can grok what happens to an expression arg will also become a realisitic problem. Particularly so when you happen to miss a method overload in some subclass somewhere. In this specific case, I suspect there needs to be an indication of some kind, at the call site, to clearly and unambiguously communicate to a person (and to the compiler) exactly what is going on. Otherwise, this may be just the kind of sugar that rots the teeth of D ?

I just came on-and-off home from the "mill" (the one about using D as a factory automation language), and my e-mail client suggested only downloading some 50 latest unread messages (instead of the 380 in this NG alone). So I haven't read much else than this message and the Change Log. Yet. A first thought: While it remains to be seen whether the new (Lisplike stuff & co.) things are genuinely a leap forward, I must say that from a marketing perspective they are -- well, plain Killers! Imagine Walter having a talk, and the audience is composed of Ultra Gurus. Now, insinuating Lisp like properties of syntax, and presenting them with examples like those on the Lazy... page -- makes every guru want to comment (but hey: the comment is not to actually comment, rather to give the impression to others that "I've understood some of this, see, see!"). Which of course puts the onus on the others to run home and do some serious homework so that they can throw robust opinions later on. Which of course unaivoidably leads to those gurus learning D on the side, which of course is a Good Thing(tm), especially considering that _we_ know that D is contagious: taste it, and you're hooked for life! Funny, maybe. But I'm not actually downplaying the new syntax, or its being Lisp like. I do see Kris's worries, and I'm nervous too. But I keep my fingers crossed, which is all I can do 'till we have some hard facts and real-world experience to chew on. And I really want to hold on to my first impression, which was "this is so cool it turns my stomach". (!!)
Aug 23 2006
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Walter Bright wrote:
 I was going to call this 1.0 RC1, but I just could not resist adding the 
 lazy expression evaluation. This adds one of the big capabilities of 
 common lisp.
 
 http://www.digitalmars.com/d/changelog.html

Typo in http://www.digitalmars.com/d/type.html "But these are distinguisable" Also, whilst reading the spec changes, I find it worth mentioning this new particular aspect of null in the context of delegate conversions, and dgnull: "A null is implicitly converted to a Type delegate() by creating an anonymous delegate that returns null. To get an actual null value for the delegate, use one of the following: const Type delegate() dgnull; // default initializer for delegate is null ... Type delegate() dg1; // default initializer for delegate is null Type delegate() dg2 = dgnull; Type delegate() dg3 = (Type delegate()).init; Type delegate() dg4 = cast(Type delegate()) null; Type delegate() dg5 = null; // initializes dg5 to // delegate Type() { return null; } "
Aug 22 2006