August 22, 2006
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?
August 22, 2006
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.

August 22, 2006
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.
I agree with this. I thought lazy evaluation in functional languages was 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'.
August 22, 2006
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.
<--snip-->
> 
>> 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
August 22, 2006
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?
>> 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.
> <--snip-->
>>> 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.

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>.
August 22, 2006
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
August 22, 2006
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");
> 
> 
> ???
August 22, 2006
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?
>>> 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?
> 
> 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.
August 22, 2006
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; }
"
August 22, 2006
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