August 22, 2006
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()
August 22, 2006
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
August 22, 2006
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())
August 22, 2006
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.
August 22, 2006
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);
> 
> 
August 23, 2006
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
August 23, 2006
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..
August 23, 2006
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
August 23, 2006
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
August 23, 2006
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".  (!!)