View mode: basic / threaded / horizontal-split · Log in · Help
July 10, 2012
Re: foreach ref very broken: fails to call front(val)
On 7/10/12 4:29 AM, kenji hara wrote:
> Posted a pull request:
> https://github.com/D-Programming-Language/phobos/pull/678

Hmm, that has a couple of issues.

First, map that modifies things in place is a bug more often than a 
feature given that the caller of map may use front() an arbitrary number 
of times. So I see little intentional and legitimate use for things like 
map!"a += 2"(range).

Second, the return by value from Array is intentional and has to do with 
sealing. Array is intended to never escape the addresses of its 
elements. That way, the collection is "sealed" in the sense there can 
never be uncontrolled pointers to its elements. This allows using 
efficient allocation strategies for the array without compromising its 
safety.

In more recent discussions with Walter we discussed the possibility of 
making "ref" returns transitory, i.e. no caller code can actually save a 
ref result beyond the call. That would allow us to keep sealing while 
also benefitting of ref returns. But that feature has not been 
implemented yet.


Andrei
July 10, 2012
Re: foreach ref very broken: fails to call front(val)
2012/7/10 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:
> On 7/10/12 4:29 AM, kenji hara wrote:
>>
>> Posted a pull request:
>> https://github.com/D-Programming-Language/phobos/pull/678
>
>
> Hmm, that has a couple of issues.
>
> First, map that modifies things in place is a bug more often than a feature
> given that the caller of map may use front() an arbitrary number of times.
> So I see little intentional and legitimate use for things like map!"a +=
> 2"(range).
>
> Second, the return by value from Array is intentional and has to do with
> sealing. Array is intended to never escape the addresses of its elements.
> That way, the collection is "sealed" in the sense there can never be
> uncontrolled pointers to its elements. This allows using efficient
> allocation strategies for the array without compromising its safety.
>
> In more recent discussions with Walter we discussed the possibility of
> making "ref" returns transitory, i.e. no caller code can actually save a ref
> result beyond the call. That would allow us to keep sealing while also
> benefitting of ref returns. But that feature has not been implemented yet.

OK. I know the past discussion about 'sealed container' so I can agree
with your argument.
Then I'll close the pull request.

Thanks.

Kenji Hara
July 10, 2012
Re: foreach ref very broken: fails to call front(val)
On 7/10/12 10:32 AM, kenji hara wrote:
> OK. I know the past discussion about 'sealed container' so I can agree
> with your argument.
> Then I'll close the pull request.

Sounds good for now but let's keep in mind the possibility of 
restricting ref returns. At that point we can "open up" ref returns in 
std.container.

Andrei
July 10, 2012
Re: foreach ref very broken: fails to call front(val)
On 07/10/2012 05:01 PM, Andrei Alexandrescu wrote:
> On 7/10/12 10:32 AM, kenji hara wrote:
>> OK. I know the past discussion about 'sealed container' so I can agree
>> with your argument.
>> Then I'll close the pull request.
>
> Sounds good for now but let's keep in mind the possibility of
> restricting ref returns. At that point we can "open up" ref returns in
> std.container.
>
> Andrei

Would that apply to all ref returns or would there be an additional
attribute that allows to explicitly restrict them?
July 10, 2012
Re: foreach ref very broken: fails to call front(val)
On 7/10/12 11:03 AM, Timon Gehr wrote:
> On 07/10/2012 05:01 PM, Andrei Alexandrescu wrote:
>> On 7/10/12 10:32 AM, kenji hara wrote:
>>> OK. I know the past discussion about 'sealed container' so I can agree
>>> with your argument.
>>> Then I'll close the pull request.
>>
>> Sounds good for now but let's keep in mind the possibility of
>> restricting ref returns. At that point we can "open up" ref returns in
>> std.container.
>>
>> Andrei
>
> Would that apply to all ref returns or would there be an additional
> attribute that allows to explicitly restrict them?

If we decide to introduce the feature it would apply to all ref 
parameters and results. That means functions receiving a ref parameter 
cannot save its address anywhere, and that callers of functions that 
return a ref result cannot save the address beyond the function call.

Still trying to figure out whether this is too restrictive. My opinion 
is that that's sensible because many uses opposing it are antipatterns 
anyway. For example, if a function sneaks away the address of something 
it better makes that clear in the signature by requiring a pointer in 
the first place.


Andrei
July 10, 2012
Re: foreach ref very broken: fails to call front(val)
On Tuesday, 10 July 2012 at 14:19:04 UTC, Andrei Alexandrescu 
wrote:
>
> ...
>
> Second, the return by value from Array is intentional and has 
> to do with sealing. Array is intended to never escape the 
> addresses of its elements. That way, the collection is "sealed" 
> in the sense there can never be uncontrolled pointers to its 
> elements. This allows using efficient allocation strategies for 
> the array without compromising its safety.
>
> ...
>
> Andrei

Thanks for the reply. I had actually opened a thread about making 
Array return by ref, and you answered you thought it was a good 
point, and said that there should be an enhancement request about 
it:
http://forum.dlang.org/thread/bkozswmsgeibarowfwvq@forum.dlang.org#post-jss5iu:24qct:241:40digitalmars.com
But I guess you meant for ranges in general. I wasn't there for 
the discussions about sealed classes, so I had not considered it.

...

Anyways, still curious about that "foreach with ref" loop: Any 
chance I can expect it to work with Array in a near future? Or if 
not, shouldn't I get a compile error that you can't bind a 
reference to a temporary?

And more generally, how would code like this _ever_ work?

Array!int arr
foreach(ref a; arr)
  a += 5;

Since there is no mechanism to pass the "op" to "front"?
July 10, 2012
Re: foreach ref very broken: fails to call front(val)
On Tuesday, July 10, 2012 23:25:41 monarch_dodra wrote:
> On Tuesday, 10 July 2012 at 14:19:04 UTC, Andrei Alexandrescu
> 
> wrote:
> > ...
> > 
> > Second, the return by value from Array is intentional and has
> > to do with sealing. Array is intended to never escape the
> > addresses of its elements. That way, the collection is "sealed"
> > in the sense there can never be uncontrolled pointers to its
> > elements. This allows using efficient allocation strategies for
> > the array without compromising its safety.
> > 
> > ...
> > 
> > Andrei
> 
> Thanks for the reply. I had actually opened a thread about making
> Array return by ref, and you answered you thought it was a good
> point, and said that there should be an enhancement request about
> it:
> http://forum.dlang.org/thread/bkozswmsgeibarowfwvq@forum.dlang.org#post-jss5
> iu:24qct:241:40digitalmars.com But I guess you meant for ranges in general.
> I wasn't there for
> the discussions about sealed classes, so I had not considered it.
> 
> ...
> 
> Anyways, still curious about that "foreach with ref" loop: Any
> chance I can expect it to work with Array in a near future? Or if
> not, shouldn't I get a compile error that you can't bind a
> reference to a temporary?
> 
> And more generally, how would code like this _ever_ work?
> 
> Array!int arr
> foreach(ref a; arr)
> a += 5;
> 
> Since there is no mechanism to pass the "op" to "front"?

I believe that according to TDPL, if you use ref in a foreach with a range, 
and range.front = value isn't legal, then you should get a compilation error. 
Whether a += value works depends on whether range.front += value works, and at 
present, that's pretty much only going to work with ranges whose front returns 
by ref, since property syntax isn't currently sophisticated enough to combine 
the getter and setter properties to make stuff like front++ or front += 5 
possible.

- Jonathan M Davis
July 10, 2012
Re: foreach ref very broken: fails to call front(val)
On 07/10/2012 11:51 PM, Jonathan M Davis wrote:
> On Tuesday, July 10, 2012 23:25:41 monarch_dodra wrote:
>> ...
>> And more generally, how would code like this _ever_ work?
>>
>> Array!int arr
>> foreach(ref a; arr)
>> a += 5;
>>
>> Since there is no mechanism to pass the "op" to "front"?
>
> I believe that according to TDPL, if you use ref in a foreach with a range,
> and range.front = value isn't legal, then you should get a compilation error.
> Whether a += value works depends on whether range.front += value works, and at
> present, that's pretty much only going to work with ranges whose front returns
> by ref, since property syntax isn't currently sophisticated enough to combine
> the getter and setter properties to make stuff like front++ or front += 5
> possible.
>
> - Jonathan M Davis

That is a bug. @property has very limited value if pairs of @property
functions are accessed in a way syntactically distinguishable from
field access.
July 10, 2012
Re: foreach ref very broken: fails to call front(val)
On 07/10/2012 05:07 PM, Andrei Alexandrescu wrote:
> On 7/10/12 11:03 AM, Timon Gehr wrote:
>> On 07/10/2012 05:01 PM, Andrei Alexandrescu wrote:
>>> On 7/10/12 10:32 AM, kenji hara wrote:
>>>> OK. I know the past discussion about 'sealed container' so I can agree
>>>> with your argument.
>>>> Then I'll close the pull request.
>>>
>>> Sounds good for now but let's keep in mind the possibility of
>>> restricting ref returns. At that point we can "open up" ref returns in
>>> std.container.
>>>
>>> Andrei
>>
>> Would that apply to all ref returns or would there be an additional
>> attribute that allows to explicitly restrict them?
>
> If we decide to introduce the feature it would apply to all ref
> parameters and results. That means functions receiving a ref parameter
> cannot save its address anywhere, and that callers of functions that
> return a ref result cannot save the address beyond the function call.
>
> Still trying to figure out whether this is too restrictive. My opinion
> is that that's sensible because many uses opposing it are antipatterns
> anyway. For example, if a function sneaks away the address of something
> it better makes that clear in the signature by requiring a pointer in
> the first place.
>
>
> Andrei

I am somewhat opposed to that change.
One issue is that it would make built-in arrays more magical.

struct S{ ???? }

version(A) int[] array;
version(B) S array;

auto p = &array[i];

However, the need for restricted ref returns is quite obvious.
'scope ref' ?
July 11, 2012
Re: foreach ref very broken: fails to call front(val)
On Wednesday, July 11, 2012 00:15:34 Timon Gehr wrote:
> On 07/10/2012 11:51 PM, Jonathan M Davis wrote:
> > On Tuesday, July 10, 2012 23:25:41 monarch_dodra wrote:
> >> ...
> >> And more generally, how would code like this _ever_ work?
> >> 
> >> Array!int arr
> >> foreach(ref a; arr)
> >> a += 5;
> >> 
> >> Since there is no mechanism to pass the "op" to "front"?
> > 
> > I believe that according to TDPL, if you use ref in a foreach with a
> > range,
> > and range.front = value isn't legal, then you should get a compilation
> > error. Whether a += value works depends on whether range.front += value
> > works, and at present, that's pretty much only going to work with ranges
> > whose front returns by ref, since property syntax isn't currently
> > sophisticated enough to combine the getter and setter properties to make
> > stuff like front++ or front += 5 possible.
> > 
> > - Jonathan M Davis
> 
> That is a bug. @property has very limited value if pairs of @property
> functions are accessed in a way syntactically distinguishable from
> field access.

I don't know if it's technically a bug or not. That would depend on the spec, 
and I suspect that it's mum on the matter, which would make the compiler 
technically correct no matter what it does with regards to this, since TDPL 
doesn't say anything on it either that I recall. But if it's not a bug, it's 
definitely an enhancement request that should be seriously considered. I 
believe that there are a couple of related enhancement requests, but I can't 
find them at the moment.

- Jonathan M Davis
1 2 3
Top | Discussion index | About this forum | D home