February 07, 2013
On Thursday, 7 February 2013 at 06:36:22 UTC, H. S. Teoh wrote:
> D ref types are currently highly crippled because of the inability to
> declare ref variables, which mandates ugly workarounds. It should be a
> first-class type qualifier IMO. (Yes I know it's currently a *function*
> qualifier, not a type qualifier... which makes it all the more ugly.)
>

My heart say yes, but my brain doesn't really any way to make
that work :/
February 07, 2013
On 2/7/2013 2:05 AM, deadalnix wrote:
> On Thursday, 7 February 2013 at 09:23:20 UTC, Walter Bright wrote:
>> The point is, there must always be a balance of competing interests. That's
>> certainly true here.
> That is an assertion not an argument.

Try designing anything by using one overriding principle - you won't get a useful result. Designs are always tradeoffs, always.


>> Does C# always allow taking the address of a getter's return value? I don't
>> know, but I'd be surprised if it did.
>>
>
> C# don't have address of. It isn't a system language. Even if you consider the
> whole stuff without the address problem, the D way is different than C#'s.

It's a different language, with a different view of things. Direct comparisons between D and C# need to take that into account.


> The 'funny' things is that C#'s would cause syntax problem issue with address of,
> where D does.

I don't understand this sentence.


>>> and a same identifier can refers to 3 different distinct (however related)
>>> concepts.
>>
>> It is not unusual for an identifier to mean different things in different
>> constructs.
> Usually not when they resolve to the same symbol. And it has to be proven that
> this is a good thing.

How does one prove anything is a "good thing"?


>> Simplicity is great, but it does not always trump everything else. It's also
>> possible for reasonable people to disagree on what is simple or intuitive.
> Here we have a more complex solution, and more problem with it. Conclude
> whatever you want, but each time I choose the complex path in my programmer
> life, I ended up with that kind of effect.
>
> You also seems to conflate simple and intuitive,

Not really, I said "simple OR intuitive" :-)


>> Yes. But I don't see the issue. &foo cannot bind to an alias parameter, nor
>> can foo().
> void function() foo can.

Sure. But I'm lost at what your point is with that example.


>> There are several such ambiguities in D that are resolved by applying semantic
>> disambiguation rules. This is done because although it makes the spec (and the
>> compiler) more complex, it is actually simpler for the user.
> I don't think it is, and looking at other languages choices, I'm not alone.

Given the vast variety and complexity of languages out there, for every example of A you can find, I can find examples of !A. It's not really useful, after all, if other languages got it all right, there's no point to D.


> This kind of thing always seems simple of some cases, but ends up creating a
> huge minefield of special case when you start to combine feature together. And
> this is something that most D users experiences.

I believe that Andrei's proposal resolves these.


> It result in users not using advanced D features (see HIGGS topic for instance,
> or many codebases on github in general) or user having trouble. It is often
> advised to stay away form advanced features of D for production quality stuff
> and I have to say I share the observation. Working on large codebase (well large
> . . . for a personal project, but clearly ridiculous compared to many companies
> codebase : ~25 000LOC) using advanced features of D, I run in such troubles
> almost on a daily basis, and have developed some knowledge of area of the
> language I should not even try to go in.

This is exactly why we're going through this exercise with the properties.

February 07, 2013
The solution to this problem has been posted already many times, simply allow fields to be marked with @property too, having the compiler lower it to a private field with trivial setter/getter method.

As I already mentioned, I don't really see the point of properties at all, if they are not interchangeable with fields. We could as well use setXXX/getXXX as in Java.

On Wed, 2013-02-06 at 22:06 -0800, Walter Bright wrote:
> Properties are always going to be subsets of fields. For example,
> 
>      @property int foo() { return 3; }
> 
> is never going to work with trying to get the address of 3. Trying to
> make it
> work would be a quixotic quest of dubious utility. I.e. I disagree
> that it is a
> serious impairment.


February 07, 2013
On Thursday, 7 February 2013 at 10:32:38 UTC, Walter Bright wrote:
> On 2/7/2013 2:05 AM, deadalnix wrote:
>> On Thursday, 7 February 2013 at 09:23:20 UTC, Walter Bright wrote:
>>> The point is, there must always be a balance of competing interests. That's
>>> certainly true here.
>> That is an assertion not an argument.
>
> Try designing anything by using one overriding principle - you won't get a useful result. Designs are always tradeoffs, always.
>

Ho yeah, I'm not arguing against that. But what is seen as conflicting goal often aren't.

>>> Does C# always allow taking the address of a getter's return value? I don't
>>> know, but I'd be surprised if it did.
>>>
>>
>> C# don't have address of. It isn't a system language. Even if you consider the
>> whole stuff without the address problem, the D way is different than C#'s.
>
> It's a different language, with a different view of things. Direct comparisons between D and C# need to take that into account.
>
>
>> The 'funny' things is that C#'s would cause syntax problem issue with address of,
>> where D does.
>
> I don't understand this sentence.
>

In C#, foo.bar won't execute bar's method of foo. It will get what is called in D a delegate. foo.bar() execute that delegate.

It remove the need for &foo.bar altogether, so with that mechanism in D, no problem with & operator.

Scala does even one step further by executing the method, or not, depending on what is expected, proving that optional () are compatible with.

Back to D, we have void function() foo; foo is declared as a function here. However, void bar() {} will also be called a function, even if the entity represented by foo and bar are completely different.

When you do foo = &bar, you get a pointer on foo's instruction. Here foo isn't a function in the D sense, but an Array of CPU instruction, or something like that. This entity, coming from C/C++ hasn't ANY useful usage except taking the address of to get a function. Wanting to keep that useless entity is the source of most trouble with the & syntax, and also on previous DIP (not that one).

> How does one prove anything is a "good thing"?
>

Proven may be strong, but you can't refute that some things are better than others.

>>> Yes. But I don't see the issue. &foo cannot bind to an alias parameter, nor
>>> can foo().
>> void function() foo can.
>
> Sure. But I'm lost at what your point is with that example.
>

Now you can pass several object to templates alias parameters, that will behave differently in slightly different subtle ways. For no real good reason.

>> I don't think it is, and looking at other languages choices, I'm not alone.
>
> Given the vast variety and complexity of languages out there, for every example of A you can find, I can find examples of !A. It's not really useful, after all, if other languages got it all right, there's no point to D.
>

If A is the instruction pack entity type mentionned above, you'll find pretty hard to find a !A if we exclude C and C++ (well and D, but it is kind of excluded if look for references). I don't pretend none exists, but it seems pretty hard to find one.

Because the idea is bad for everybody : it make the language more complex, harder to implement compiler/tooling for, can conflict with other features, and worse, have no benefice.

This is a bad idea in all possible way. Actually so bad that even PHP don't implement it.

>> This kind of thing always seems simple of some cases, but ends up creating a
>> huge minefield of special case when you start to combine feature together. And
>> this is something that most D users experiences.
>
> I believe that Andrei's proposal resolves these.
>

He does so by adding special cases. That is the problem with special cases, they multiply themselves faster than rabbits.

>> It result in users not using advanced D features (see HIGGS topic for instance,
>> or many codebases on github in general) or user having trouble. It is often
>> advised to stay away form advanced features of D for production quality stuff
>> and I have to say I share the observation. Working on large codebase (well large
>> . . . for a personal project, but clearly ridiculous compared to many companies
>> codebase : ~25 000LOC) using advanced features of D, I run in such troubles
>> almost on a daily basis, and have developed some knowledge of area of the
>> language I should not even try to go in.
>
> This is exactly why we're going through this exercise with the properties.

It is clear that the property improvement proposed by Andrei is a great step forward. However, the &foo.bar that return the delegate when bar is a property is exactly the kind of stuff that are waiting to explode.

Yes, this DIP remove the syntactic ambiguity (does this take the delegate or the address of the result ?) but that is barely it. I'd say that the fact that & have a meaning is way more problematic than the fact that it is not possible to take the resulting address.
February 07, 2013
On Wed, 06 Feb 2013 17:36:24 -0000, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> A good part of that is the recent debate on what &func should do (take the address of the function vs. the address of its result). With the unsafe meaning out of the way, only the safe one is eligible.

&X takes the address of X.

If X is a symbol which represents an 'int' you get the address of the int itself, not the address of the int's value.

If X is a symbol which represents a 'function' you should get the address of the function itself, not the address of that functions value (AKA the result).

That seems the most logical thing to implement, to me.  I think the confusion arises because ppl conflate the symbol/variable/thing and that thing's value.

If we implement this we then have to ask how to get the address of the value.  I reckon; if you want the address of the value of the function then call the function and take the address of that i.e. &func().  Here, brackets are not optional because they indicate the function is being called.

Alternately if you don't like that, perhaps &*func.  So, if func is "ref int func()" then this syntax makes it analogous to an int* e.g.

int i = 5;
int *p = &i;

&p  // takes the address of the variable 'p'
&*p // takes the address of the variable 'i'

int i = 5;
ref int func() { return i; }

&func   // takes the address of func
&*func  // takes the address of i

I prefer:

&func() // takes the address of i

because to me that is clearer and nicer looking.

This seems the most logical thing to do, and seems the most flexible to me.  If &func were to take the address of the value of func (result) then we'd need to invent a new syntax to take the address of func itself and why do that when we don't really need to. IMO.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
February 07, 2013
On Thursday, 7 February 2013 at 09:23:20 UTC, Walter Bright wrote:
>> DIP25 aim to solve the ref issue. Which is clearly useful. Conflating that goal
>> with making previous DIP on function call is only going to export the mess in
>> another area of the language.
>>
>> This is the very example of why simplicity in semantic is key.
>
> Simplicity is great, but it does not always trump everything else. It's also possible for reasonable people to disagree on what is simple or intuitive.

Can you tell me if you consider my proposal with regard to making ref safe and complete simple and intuitive both for compiler and user, and if not, why? (I don't have an opinion about '&' yet.)

http://forum.dlang.org/thread/ket199$2c27$1@digitalmars.com#post-bsgrtofehxfjmzkaedfr:40forum.dlang.org
February 07, 2013
On Thu, 07 Feb 2013 01:06:34 -0500, Walter Bright <newshound2@digitalmars.com> wrote:

>
> The only time (now) that you can take the address of function return value is if that is a return by ref. So, if taking the address of a ref is disallowed, then the syntax is no longer ambiguous.

Thinking about this, I don't know that I like the idea of disallowing taking the address of ref.

One major usage of taking the address of ref returns is the opIndex operator:

int *ptr = &arr[0];

Or, more generally, the front property of a range:

int *ptr = &arr.front;

What I am concerned about is that this is not going to have the desired effect.  Instead of grudgingly switching to a new style of coding, people will simply return pointers instead of ref.

-Steve
February 07, 2013
Am Thu, 07 Feb 2013 09:04:29 +0100
schrieb "deadalnix" <deadalnix@gmail.com>:

> On Thursday, 7 February 2013 at 07:41:57 UTC, Johannes Pfau wrote:
> > Am Wed, 06 Feb 2013 23:45:51 +0100
> > schrieb Robert <jfanatiker@gmx.at>:
> >
> >> What happened to the scope storage class for parameters.
> >> 
> >> Wouldn't this solve the problems, with the simple rule that
> >> you are
> >> not allowed to pass transient objects by reference if the
> >> parameter
> >> was not declared with scope? And if I understood correctly, the
> >> compiler is already capable of locally ensuring that the
> >> address does
> >> not escape (to ensure the scope requirement), so we are all
> >> set?
> >
> > This is an important question. How would this new proposal
> > interact with
> > scope parameters?
> >
> 
> scope in not enough, as you can alias parameters (for instance swap).

Can you give an example?

I understand the scope is not enough to completely replace the rules in the proposal, but shouldn't it be legal to pass addresses of stack variables in @safe code as a scope parameter? Could this cause issues as well?
February 07, 2013
On Thursday, 7 February 2013 at 09:21:38 UTC, deadalnix wrote:
> On Thursday, 7 February 2013 at 08:48:30 UTC, Rob T wrote:
>> On Thursday, 7 February 2013 at 05:54:29 UTC, deadalnix wrote:
>>> On Thursday, 7 February 2013 at 05:43:24 UTC, Rob T wrote:
>>>> In other words @safe should explicitly mean "I hereby verify that the code is safe" not "I will silently re-write your code in unknown ways to make it safe".
>>>>
>>>
>>> @safe never meant that and Andrei never suggested that.
>>
>> I must have misunderstood something. What did he mean by this?
>>
>> ------------
>>> So you are saying this should compile?:
>>>
>>> struct S{
>>> int x;
>>> int foo()@safe{ return x; }
>>> }
>>>
>>> int delegate()@safe foo()@safe{
>>> S s;
>>> return &s.foo;
>>> }
>>
>> Yah, it should, and it also should detect the escape and allocate foo's
>> frame on the heap.
>>
>> Andrei
>> ------------
>>
>> What is being allocated on the heap?
>>
>
> The frame pointer is, and it isn't dependent of @system or @safe .


S* foo()@safe{
    S s;
    return &s;
}


In the above example, will s be silently allocated on the heap?

--rt
February 07, 2013
On 2/7/2013 6:15 AM, Zach the Mystic wrote:
> Can you tell me if you consider my proposal with regard to making ref safe and
> complete simple and intuitive both for compiler and user, and if not, why? (I
> don't have an opinion about '&' yet.)
>
> http://forum.dlang.org/thread/ket199$2c27$1@digitalmars.com#post-bsgrtofehxfjmzkaedfr:40forum.dlang.org
>

I don't know if it's complete and safe. It's not something that can be determined with a quick read.