www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - `return const` parameters make `inout` obsolete

reply "Zach the Mystic" <reachzach gggmail.com> writes:
char* fun(return const char* x);

Compiler has enough information to adjust the return type of 
`fun()` to that of input `x`. This assumes return parameters have 
been generalized to all reference types. Destroy.
Mar 16 2015
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 16 Mar 2015 14:17:57 +0000, Zach the Mystic wrote:

 char* fun(return const char* x);
=20
 Compiler has enough information to adjust the return type of `fun()` to
 that of input `x`. This assumes return parameters have been generalized
 to all reference types. Destroy.
but why compiler has to rewrite return type? i never told it to do that!=
Mar 16 2015
parent reply "Zach the Mystic" <reachzach gggmail.com> writes:
On Monday, 16 March 2015 at 14:23:42 UTC, ketmar wrote:
 On Mon, 16 Mar 2015 14:17:57 +0000, Zach the Mystic wrote:

 char* fun(return const char* x);
 
 Compiler has enough information to adjust the return type of 
 `fun()` to
 that of input `x`. This assumes return parameters have been 
 generalized
 to all reference types. Destroy.
but why compiler has to rewrite return type? i never told it to do that!
It has to if you pass an immutable to x, which you're allowed to do. It only gives an error if you assign the result to a mutable variable. The point is that the signature still contains all the information it needs without `inout`. What old errors will fail to be reported and what new errors would it cause? I haven't been able to think of any.
Mar 16 2015
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 16 Mar 2015 15:33:40 +0000, Zach the Mystic wrote:

 On Monday, 16 March 2015 at 14:23:42 UTC, ketmar wrote:
 On Mon, 16 Mar 2015 14:17:57 +0000, Zach the Mystic wrote:

 char* fun(return const char* x);
=20
 Compiler has enough information to adjust the return type of `fun()`
 to that of input `x`. This assumes return parameters have been
 generalized to all reference types. Destroy.
but why compiler has to rewrite return type? i never told it to do that!
=20 It has to if you pass an immutable to x, which you're allowed to do. It only gives an error if you assign the result to a mutable variable. The point is that the signature still contains all the information it needs without `inout`. What old errors will fail to be reported and what new errors would it cause? I haven't been able to think of any.
this is the question of consistency. if i wrote `char* fun()`, i want fun=20 to return `char*`, and i'm not expecting it to change in a slightest. i=20 don't like when compiler starts to change things on it's own.=
Mar 16 2015
parent reply "Zach the Mystic" <reachzach gggmail.com> writes:
On Monday, 16 March 2015 at 15:39:39 UTC, ketmar wrote:
 On Mon, 16 Mar 2015 15:33:40 +0000, Zach the Mystic wrote:

 On Monday, 16 March 2015 at 14:23:42 UTC, ketmar wrote:
 On Mon, 16 Mar 2015 14:17:57 +0000, Zach the Mystic wrote:

 char* fun(return const char* x);
 
 Compiler has enough information to adjust the return type of 
 `fun()`
 to that of input `x`. This assumes return parameters have 
 been
 generalized to all reference types. Destroy.
but why compiler has to rewrite return type? i never told it to do that!
It has to if you pass an immutable to x, which you're allowed to do. It only gives an error if you assign the result to a mutable variable. The point is that the signature still contains all the information it needs without `inout`. What old errors will fail to be reported and what new errors would it cause? I haven't been able to think of any.
this is the question of consistency. if i wrote `char* fun()`, i want fun to return `char*`, and i'm not expecting it to change in a slightest. i don't like when compiler starts to change things on it's own.
I think it's just less cluttered than `inout`. The simple fact is that if you try to assign an immutable variable to a mutable reference, you will still get an error. I doubt it would take long for programmers to adjust to the new way of reading the signatures. They just see `return` sitting there in front of `const` and know how to handle the situation.
Mar 16 2015
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 16 Mar 2015 15:54:19 +0000, Zach the Mystic wrote:

 I think it's just less cluttered than `inout`. The simple fact is that
 if you try to assign an immutable variable to a mutable reference, you
 will still get an error. I doubt it would take long for programmers to
 adjust to the new way of reading the signatures. They just see `return`
 sitting there in front of `const` and know how to handle the situation.
having argument modifier that changes function return type is very=20 surprising regardless of how much people used to it. really, why should i=20 parse *arguments* to know the (explicitly specified!) *return* *type*?=20 it's ok with `auto`, it's ok with `inout`, but when i wrote `char *`, i=20 want `char *`. and then compiler decides that it knows better. ok,=20 compiler, you win, can you write the rest of the code for me? no? stupid=20 compiler!=
Mar 16 2015
parent reply "Zach the Mystic" <reachzach gggmail.com> writes:
On Monday, 16 March 2015 at 16:49:36 UTC, ketmar wrote:
 having argument modifier that changes function return type is 
 very
 surprising regardless of how much people used to it. really, 
 why should i
 parse *arguments* to know the (explicitly specified!) *return* 
 *type*?
 it's ok with `auto`, it's ok with `inout`, but when i wrote 
 `char *`, i
 want `char *`. and then compiler decides that it knows better. 
 ok,
 compiler, you win, can you write the rest of the code for me? 
 no? stupid
 compiler!
I feel like you're reacting more to "Change" than to my actual point. `inout` wasn't invented because it looks good, but because it solves the DRY problem for different input types. `return` parameters also solve that problem, plus a few more, and with less DRY even than `inout`. I don't think either type if signature is that hard to read. It's just a matter of getting used to them.
Mar 16 2015
parent ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 16 Mar 2015 18:46:10 +0000, Zach the Mystic wrote:

 On Monday, 16 March 2015 at 16:49:36 UTC, ketmar wrote:
 having argument modifier that changes function return type is very
 surprising regardless of how much people used to it. really, why should
 i parse *arguments* to know the (explicitly specified!) *return*
 *type*?
 it's ok with `auto`, it's ok with `inout`, but when i wrote `char *`, i
 want `char *`. and then compiler decides that it knows better.
 ok,
 compiler, you win, can you write the rest of the code for me? no?
 stupid compiler!
=20 I feel like you're reacting more to "Change" than to my actual point.
your change includes both observation and syntax change. i don't want to=20 separate them.
 It's just a matter of getting used to them.
i can read Z80 machine code without disassembler. that doesn't means that=20 i like to do that.=
Mar 16 2015
prev sibling next sibling parent reply "Idan Arye" <GenericNPC gmail.com> writes:
On Monday, 16 March 2015 at 14:17:58 UTC, Zach the Mystic wrote:
 char* fun(return const char* x);

 Compiler has enough information to adjust the return type of 
 `fun()` to that of input `x`. This assumes return parameters 
 have been generalized to all reference types. Destroy.
Is the `return` in the argument list a new feature? It doesn't compile in 2.066, and I don't see it in 2.067's changelog...
Mar 16 2015
parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 16 March 2015 at 16:02:57 UTC, Idan Arye wrote:
 On Monday, 16 March 2015 at 14:17:58 UTC, Zach the Mystic wrote:
 char* fun(return const char* x);

 Compiler has enough information to adjust the return type of 
 `fun()` to that of input `x`. This assumes return parameters 
 have been generalized to all reference types. Destroy.
Is the `return` in the argument list a new feature? It doesn't compile in 2.066, and I don't see it in 2.067's changelog...
It's been experimentally introduced by DIP25: http://wiki.dlang.org/DIP25
Mar 16 2015
prev sibling next sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 16 March 2015 at 14:17:58 UTC, Zach the Mystic wrote:
 char* fun(return const char* x);

 Compiler has enough information to adjust the return type of 
 `fun()` to that of input `x`. This assumes return parameters 
 have been generalized to all reference types. Destroy.
That's a very interesting observation. I never liked the name `inout`, as it doesn't describe what it does. The only downside I see is that it's more magic, because nothing on the return type says its mutability is going to depend on an argument. I think Kenji also had additional plans for `inout`, related to uniqueness. There was a PR. Better ask him whether it's going to be compatible.
Mar 16 2015
parent "Zach the Mystic" <reachzach gggmail.com> writes:
On Monday, 16 March 2015 at 16:22:46 UTC, Marc Schütz wrote:
 On Monday, 16 March 2015 at 14:17:58 UTC, Zach the Mystic wrote:
 char* fun(return const char* x);

 Compiler has enough information to adjust the return type of 
 `fun()` to that of input `x`. This assumes return parameters 
 have been generalized to all reference types. Destroy.
That's a very interesting observation. I never liked the name `inout`, as it doesn't describe what it does. The only downside I see is that it's more magic, because nothing on the return type says its mutability is going to depend on an argument. I think Kenji also had additional plans for `inout`, related to uniqueness. There was a PR. Better ask him whether it's going to be compatible.
`return` would work just as well for uniqueness. inout(T*) fun(inout(T*) x); -> T* fun(return const T* x); I don't think any information is being lost. My attitude is that unless you are losing information, the underlying logic won't be any harder to implement. I think that `return` parameters are a building block of `inout`, but more useful because they can be used separately from it. Perhaps in the early days of D, it just seemed too weird to have `return` parameters, but now with ref safety, they are better justified. But if they'd been there back then, `inout` probably wouldn't exist, since you can just build it in its current form from `const` and `return`.
Mar 16 2015
prev sibling parent reply Nick Treleaven <ntrel-pub mybtinternet.com> writes:
On 16/03/2015 14:17, Zach the Mystic wrote:
 char* fun(return const char* x);

 Compiler has enough information to adjust the return type of `fun()` to
 that of input `x`. This assumes return parameters have been generalized
 to all reference types. Destroy.
inout can be used for local variables too.
Mar 17 2015
parent reply "Zach the Mystic" <reachzach gggmail.com> writes:
On Tuesday, 17 March 2015 at 12:02:15 UTC, Nick Treleaven wrote:
 On 16/03/2015 14:17, Zach the Mystic wrote:
 char* fun(return const char* x);

 Compiler has enough information to adjust the return type of 
 `fun()` to
 that of input `x`. This assumes return parameters have been 
 generalized
 to all reference types. Destroy.
inout can be used for local variables too.
Yeah that might be a use for it. inout(T*) fun(inout(T*) t) { inout(T*) x = t; return x; } --> T* gun(return const T* t) { const(T*) x = t; return x; } To be fully viable, `return` would have to be secretly recorded as part of the `x's type, so that the compiler could forgive returning it to a non-const. But the compiler should probably track that `x` is copied from `t` anyway, so that it can verify `return t` when it returns `x`, and the same information would be used to forgive `x's constness. But yeah, there might still be a use for `inout`.
Mar 17 2015
parent reply "ixid" <adamsibson hotmail.com> writes:
 To be fully viable, `return` would have to be secretly recorded 
 as part of the `x's type, so that the compiler could forgive 
 returning it to a non-const. But the compiler should probably 
 track that `x` is copied from `t` anyway, so that it can verify 
 `return t` when it returns `x`, and the same information would 
 be used to forgive `x's constness.

 But yeah, there might still be a use for `inout`.
Why is this ability important? It feels like trying to distort non-templates into templates. Is this the alternative to using templates or repeating yourself or are there other important aspects to it?
Mar 17 2015
parent "Zach the Mystic" <reachzach gggmail.com> writes:
On Tuesday, 17 March 2015 at 18:27:01 UTC, ixid wrote:
 To be fully viable, `return` would have to be secretly 
 recorded as part of the `x's type, so that the compiler could 
 forgive returning it to a non-const. But the compiler should 
 probably track that `x` is copied from `t` anyway, so that it 
 can verify `return t` when it returns `x`, and the same 
 information would be used to forgive `x's constness.

 But yeah, there might still be a use for `inout`.
Why is this ability important? It feels like trying to distort non-templates into templates. Is this the alternative to using templates or repeating yourself or are there other important aspects to it?
I don't know for sure. I think the main point of `inout` is to avoid returning a copy of a reference that's mutable and assigning it to an immutable. When there is no copy of a reference (i.e. it's unique), or if you know that all possible copies are immutable, there's no problem. Even an immutable reference with lifetime shorter than the `const` value it copies is okay. In other words, it seems like there are a lot of cases where you can assign something that returns a regular `T*` to an `immutable(T*)` safely.
Mar 17 2015