February 06, 2013
Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form.

http://wiki.dlang.org/DIP25


Thanks,

Andrei
February 06, 2013
2013/2/6 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>

> Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form.
>
> http://wiki.dlang.org/DIP25


Hmm, this is much reasonable.

In recent, I had wrote and post a compiler extension to reinforce a kind of trait which related to pure function. I call the trait "isolated", and that means "Whether any reachable indirections from parameters does not appear in the returned value".

https://github.com/D-Programming-Language/dmd/pull/1519

With my patch, such as following cases can be detected.

struct S { int* ptr; }
S foo(int* ptr) pure;
S bar(const int* ptr) pure;

void main() {
  int n;
  immutable S s = foo(&n);
  // implicit conversion from S to immutable S is _diallowed_.
  // Because &n may appear in foo's returned value.

  immutable S s = bar(&n);
  // implicit conversion from S to immutable S is _allowed_.
  // Because &n never appear in bar's returned value.
  // (compiler assumes that bar doesn't do any un-@safe operations, e.g.
cast(int*)ptr)
}

As far as I see, the contained essence in the DIP is much similar to the
"isolated" traits.
So I can say that it is *implementable*.

Kenji Hara


February 06, 2013
Am Wed, 06 Feb 2013 02:38:17 -0500
schrieb Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:

> Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form.
> 
> http://wiki.dlang.org/DIP25
> 
> 
> Thanks,
> 
> Andrei

Sounds good.
Regarding rule 2.2:

I think somebody already said that classes could be allocated on
the stack but I guess we can't do anything about that. At least in
@safe code placing a class on the stack should be illegal though, so we
can partially avoid the problem there.
If we have such a special rule for classes would it also make sense to
have a similar rule for struct*?
February 06, 2013
On 02/06/2013 02:38 AM, Andrei Alexandrescu wrote:
> Probably it'll need a fair amount of tweaking. Anyhow it's in
> destroyable form.
>
> http://wiki.dlang.org/DIP25
>
>
> Thanks,
>
> Andrei

This is probably reasonably, but I'm having trouble fully comprehending it.

Once I get to the "Typechecking rules" section and dig into the nitty-gritty, it seems to be written in a way that discusses what is allowed, but only briefly hints at what is disallowed.  It is not immediately clear to me how this would impact my code.

My interpretation so far is that the only difference between DIP25 and current D code is that we won't be allowed to pass stack variables (including by-value/copied parameters) into ref parameters.

HTH
February 06, 2013
On 02/06/2013 09:48 AM, Chad Joan wrote:
>
> Once I get to the "Typechecking rules" section and dig into the
> nitty-gritty, it seems to be written in a way that discusses what is
> allowed, but only briefly hints at what is disallowed. It is not
> immediately clear to me how this would impact my code.
>

I should be more clear myself: I mean "Typechecking rules" and everything that follows it.

February 06, 2013
On 2/6/13 9:49 AM, Chad Joan wrote:
> On 02/06/2013 09:48 AM, Chad Joan wrote:
>>
>> Once I get to the "Typechecking rules" section and dig into the
>> nitty-gritty, it seems to be written in a way that discusses what is
>> allowed, but only briefly hints at what is disallowed. It is not
>> immediately clear to me how this would impact my code.
>>
>
> I should be more clear myself: I mean "Typechecking rules" and
> everything that follows it.

Yah, we need more examples. As for what's disallowed, in a way it's "simple" - everything that's not allowed is disallowed :o).

We definitely should add discussion of disallowed uses.


Andrei

February 06, 2013
On Wednesday, 6 February 2013 at 07:38:17 UTC, Andrei Alexandrescu wrote:
> Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form.
>
> http://wiki.dlang.org/DIP25
>
>
> Thanks,
>
> Andrei

All of the 'fine' ones are fine. Which leaves how one might invoke the 'unfine' ones. The language must make a choice between restricted simplicity and flexible complexity. If it chooses flexibility, the function signature must give a clue as to what the return value contains. 'out' return values and 'scope' parameters will give the clues it needs.

Here are all the 'unfine' functions listed:

ref T gun(ref T);
struct S { int a; T b; }
ref S iun(ref S);

ref T caller(bool condition, ref T v1, ref S v2, T v3, S v4) {
    T v5;
    S v6;

    // Not fine, bound to locals
    // if (condition) return gun(v3);
    // if (condition) return gun(v4.b);
    // if (condition) return gun(v5);
    // if (condition) return gun(v6.b);

    // Not fine, bound to locals
    // if (condition) return iun(v4);
    // if (condition) return iun(v6);
}

Say gun's actual implementation is:

ref T gun(ref T a) {
   auto noo = new T;
   noo = a;
   return noo;
}

You can' tell from the function signature that the return value of this function is good to go, so the call 'return gun(v3);' above would be disallowed even though it didn't need to be. If you marked the signature with 'out', the caller knows it's good to go, and the compiler can statically prevent the function from returning one of its ref parameters. 'out' can be made to imply 'ref' in any case where the type is not inherently a reference anyway.

out T gun(ref T a) {
   return new T; // Pass
   return a; // Error
}

This will solve all problems, except for the very rare corner case when you need to assert fined-grained control over exactly which ref parameters are safe and which are not. 'scope' comes to the rescue here.

ref int fud(ref int a, scope int b) {
   a += b;
   return a; // Pass

   return b; // Error
}
ref int elmer(ref int f) {
   int v;
   return fud(f, v); // Passes
   return fud(v, f); // Fails
}

An 'out' return value simply marks all its 'ref' parameters 'scope' underneath the hood, so there will never be a need for both 'out' and 'scope' in the same signature. Since 'scope' is useless if its not a reference, it implies 'ref' also.

I'm pretty sure this is the best way to make the language completely flexible. I don't anticipate an easier way to get it done, and therefore, to my mind at least, the choice is between simple-but-limited and flexible-and-complicated.
February 06, 2013
On 2/6/13 9:48 AM, Chad Joan wrote:
> My interpretation so far is that the only difference between DIP25 and
> current D code is that we won't be allowed to pass stack variables
> (including by-value/copied parameters) into ref parameters.

Hmm, I need to make things clearer. That's covered plainly in 1.1. You get to pass down stack variables and by-value parameters down to functions taking ref. You won't be able to return them up, no matter what you (safely) try.

Andrei
February 06, 2013
Am 06.02.2013 08:38, schrieb Andrei Alexandrescu:
> Probably it'll need a fair amount of tweaking. Anyhow it's in
> destroyable form.
>
> http://wiki.dlang.org/DIP25
>
>
> Thanks,
>
> Andrei

What I don't get is, why is it better to have a function "addressOf(value)" that does exactly the same as &value? Expect that it is more text to type? Why is addressOf(value) more explicit then &value?

Kind Regards
Benjamin Thaut
February 06, 2013
On 2/6/13 2:38 AM, Andrei Alexandrescu wrote:
> Probably it'll need a fair amount of tweaking. Anyhow it's in
> destroyable form.
>
> http://wiki.dlang.org/DIP25

Updated with a section dedicated to address taking:

http://wiki.dlang.org/DIP25#Taking_address


Andrei

« First   ‹ Prev
1 2 3 4 5 6 7 8
Top | Discussion index | About this forum | D home