March 07, 2012
On Wed, 07 Mar 2012 18:01:10 -0500, Stewart Gordon <smjg_1998@yahoo.com> wrote:

> On 07/03/2012 22:48, Steven Schveighoffer wrote:
>> On Wed, 07 Mar 2012 17:37:53 -0500, Stewart Gordon <smjg_1998@yahoo.com> wrote:
> <snip>
>>> cast() is an abomination. I'm not sure OTTOMH whether it's a bug that it works.
>>
>> Sorry, it's just easier than typing cast(int*).
>
> Which is another abomination.  The means of casting away constancy should be explicit.

I agree, but it doesn't make it illegal.  It was just a means to show what I meant.

>
> <snip>
>>>> But from an API point of view, I look at at inout as guaranteeing anything the parameter
>>>> points at won't change while inside the function *using that parameter*. Even though it's
>>>> legal, it's disingenuous (at least as long as we define inout that way).
>>>
>>> That's what const is for.
>>
>> And inout. Sorry, it was meant that way, even if you don't agree.
>
> Maybe _you_ meant it that way, but did anyone else?

I actually designed it...

http://d.puremagic.com/issues/show_bug.cgi?id=1961

http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP2

-Steve
March 08, 2012
On 03/07/2012 11:37 PM, Stewart Gordon wrote:
> On 07/03/2012 15:41, Steven Schveighoffer wrote:
> <snip>
>> In fact, I think this is valid D code:
>>
>> int i;
>> const int *pi = &i;
>> int *p = cast()pi;
>> *p = 5; // legal because I know this points at i, and i is really mutable
>
> cast() is an abomination. I'm not sure OTTOMH whether it's a bug that it
> works.
>

It is not legal code. I did not point it out because it was clear what was meant. cast() only casts away the top level of modifiers. It is perfectly safe except for class objects.
March 08, 2012
On 03/07/2012 04:41 PM, Steven Schveighoffer wrote:
> On Tue, 06 Mar 2012 05:11:34 -0500, Timon Gehr <timon.gehr@gmx.ch> wrote:
>
>> On 03/06/2012 12:27 AM, Steven Schveighoffer wrote:
>> ...
>>>
>>> There are two parts to inout, one is that it can be one function called
>>> 3 different ways, the other is that you know it's constant during
>>> function execution. Some people like that second part, even if it
>>> doesn't fully guarantee everything. I.e. there's a reason people use
>>> const in C++ besides it being trendy.
>>>
>>
>> By passing a delegate that changes an inout-matched argument it is
>> made explicit that inout data may change. Technically, none of the
>> existing guarantees are lost, we just add some expressiveness to the
>> type system.
>
> Yes, I understand that it works. I know that it doesn't violate
> technically any const guarantees.
>

Yes, that is not what I was after:

void foo(inout(int)*x, void delegate(inout(int)*) dg)
// both inout's denote the same wildcard
{   dg(x);
}

void main(){
    int x;
    foo(&x, (p){*p=2;}); // this currently cannot be valid code
}

The function call is explicit about that may change the inout parameter. There are no guarantees lost. It is the call site who changes the parameter. Code that currently has the guarantee that the parameter won't change will keep it, because there is no valid code that could silently change semantics under the change and does not use some fancy introspection.
March 08, 2012
On Wed, 07 Mar 2012 19:06:14 -0500, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 03/07/2012 11:37 PM, Stewart Gordon wrote:
>> On 07/03/2012 15:41, Steven Schveighoffer wrote:
>> <snip>
>>> In fact, I think this is valid D code:
>>>
>>> int i;
>>> const int *pi = &i;
>>> int *p = cast()pi;
>>> *p = 5; // legal because I know this points at i, and i is really mutable
>>
>> cast() is an abomination. I'm not sure OTTOMH whether it's a bug that it
>> works.
>>
>
> It is not legal code. I did not point it out because it was clear what was meant. cast() only casts away the top level of modifiers. It is perfectly safe except for class objects.

If it's not legal code, then how is implicitly casting away inout during function execution legal code?  Isn't this the same thing?

-Steve
March 08, 2012
On 03/08/2012 12:37 PM, Steven Schveighoffer wrote:
> On Wed, 07 Mar 2012 19:06:14 -0500, Timon Gehr <timon.gehr@gmx.ch> wrote:
>
>> On 03/07/2012 11:37 PM, Stewart Gordon wrote:
>>> On 07/03/2012 15:41, Steven Schveighoffer wrote:
>>> <snip>
>>>> In fact, I think this is valid D code:
>>>>
>>>> int i;
>>>> const int *pi = &i;
>>>> int *p = cast()pi;
>>>> *p = 5; // legal because I know this points at i, and i is really
>>>> mutable
>>>
>>> cast() is an abomination. I'm not sure OTTOMH whether it's a bug that it
>>> works.
>>>
>>
>> It is not legal code. I did not point it out because it was clear what
>> was meant. cast() only casts away the top level of modifiers. It is
>> perfectly safe except for class objects.
>
> If it's not legal code, then how is implicitly casting away inout during
> function execution legal code? Isn't this the same thing?
>
> -Steve

It is not legal code because the assignment const(int)* to int* does not succeed. The other part is up to debate. The specification does not define the semantics of casting away const and changing the data.

It is also not the same as with the proposed change to inout. inout would not be 'removed' in the function body, it would be 'removed' upon inout-matching the parameters. Inout should be able to replace overloads on const, therefore I think that is the way it should work on the conceptual level.
March 08, 2012
On Thu, 08 Mar 2012 13:17:15 -0500, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 03/08/2012 12:37 PM, Steven Schveighoffer wrote:
>> On Wed, 07 Mar 2012 19:06:14 -0500, Timon Gehr <timon.gehr@gmx.ch> wrote:
>>
>>> On 03/07/2012 11:37 PM, Stewart Gordon wrote:
>>>> On 07/03/2012 15:41, Steven Schveighoffer wrote:
>>>> <snip>
>>>>> In fact, I think this is valid D code:
>>>>>
>>>>> int i;
>>>>> const int *pi = &i;
>>>>> int *p = cast()pi;
>>>>> *p = 5; // legal because I know this points at i, and i is really
>>>>> mutable
>>>>
>>>> cast() is an abomination. I'm not sure OTTOMH whether it's a bug that it
>>>> works.
>>>>
>>>
>>> It is not legal code. I did not point it out because it was clear what
>>> was meant. cast() only casts away the top level of modifiers. It is
>>> perfectly safe except for class objects.
>>
>> If it's not legal code, then how is implicitly casting away inout during
>> function execution legal code? Isn't this the same thing?
>>
>> -Steve
>
> It is not legal code because the assignment const(int)* to int* does not succeed.

Oh right, I forgot that casting using cast() just goes to the tail-const version.  grr... We really need const_cast...

> The other part is up to debate. The specification does not define the semantics of casting away const and changing the data.

Yes, I couldn't really find that.  It does specifically say casting away const and then modifying is invalid, but it does not say anything about "if you know the underlying data is mutable".  But again, this is the point I was trying to make, we are casting away a const-like attribute and modifying the data.

> It is also not the same as with the proposed change to inout. inout would not be 'removed' in the function body, it would be 'removed' upon inout-matching the parameters. Inout should be able to replace overloads on const, therefore I think that is the way it should work on the conceptual level.

It is essentially the same as this:

void bar(const(int) * i, void delegate(const(int)* i) dg) {dg(i);}
void main()
{
   void foo(int *i) {*i = 5;}
   bar(&i, cast(delegate(const(int)*)) &foo);
}

Which I don't know if it's valid.  Given that compiler enforcement of inout being *sure* that the data is actually mutable, it's much safer than what I wrote above, but it's certainly no different.  It's just compiler-checked vs. manually checked.

-Steve
March 08, 2012
On 08/03/2012 19:38, Steven Schveighoffer wrote:
<snip>
> Yes, I couldn't really find that. It does specifically say casting away const and then
> modifying is invalid, but it does not say anything about "if you know the underlying data
> is mutable". But again, this is the point I was trying to make, we are casting away a
> const-like attribute and modifying the data.
<snip>

No more than we are already doing with the inout return.

Stewart.
March 09, 2012
On Thu, 08 Mar 2012 17:43:34 -0500, Stewart Gordon <smjg_1998@yahoo.com> wrote:

> On 08/03/2012 19:38, Steven Schveighoffer wrote:
> <snip>
>> Yes, I couldn't really find that. It does specifically say casting away const and then
>> modifying is invalid, but it does not say anything about "if you know the underlying data
>> is mutable". But again, this is the point I was trying to make, we are casting away a
>> const-like attribute and modifying the data.
> <snip>
>
> No more than we are already doing with the inout return.

Except that technique has been approved by Walter and included in the language.

-Steve
March 10, 2012
On 19/02/2012 14:27, Stewart Gordon wrote:
<snip>
> int opApply(int delegate(ref inout(T)) dg) inout;
>
> But then I realised a potential ambiguity:
> (a) the constancy is passed through to the delegate
> (b) the delegate has an inout parameter in its own right
<snip>

Thinking about it, if we go with (a), then (b) can be achieved by defining an alias of the delegate type.  Just one problem I can see: since a signature that uses (b) can't be represented in code without an alias, how would compiler messages, .stringof and TypeInfo notate the type?

But if we go with (b), then there doesn't seem to be a way to achieve (a) without inventing new syntax.

Stewart.
March 10, 2012
On Fri, 09 Mar 2012 19:44:20 -0500, Stewart Gordon <smjg_1998@yahoo.com> wrote:

> On 19/02/2012 14:27, Stewart Gordon wrote:
> <snip>
>> int opApply(int delegate(ref inout(T)) dg) inout;
>>
>> But then I realised a potential ambiguity:
>> (a) the constancy is passed through to the delegate
>> (b) the delegate has an inout parameter in its own right
> <snip>
>
> Thinking about it, if we go with (a), then (b) can be achieved by defining an alias of the delegate type.  Just one problem I can see: since a signature that uses (b) can't be represented in code without an alias, how would compiler messages, .stringof and TypeInfo notate the type?
>
> But if we go with (b), then there doesn't seem to be a way to achieve (a) without inventing new syntax.

As I recently mentioned in the bug report, (b) must be the case without any additional syntax, because otherwise you have two types with identical syntax, but different underlying types.

In order to do (a), we need new syntax.  That's not a good thing, but not the end of the world.

-Steve
1 2 3
Next ›   Last »