February 16, 2014
On Sun, 16 Feb 2014 00:14:07 -0500, Meta <jared771@gmail.com> wrote:

> On Sunday, 16 February 2014 at 04:46:34 UTC, Steven Schveighoffer wrote:
>> It is safe if you can guarantee the input is ultimately mutable. But there is no way to enforce such a guarantee. It is on the caller to make sure that is true.
>>
>> I don't see why inout should be identified as any different from const in this respect. You could just as easily say the same thing about const.
>>
>> -Steve
>
> Which is what I said in an earlier post. Wouldn't you be able to do this with a template somehow?
>
> template LogicalConst(T)
> if (isMutable!T)
> {
>      alias LogicalConst = inout(T);
> }
>
> void bumpWithConstArg(T)(ref LogicalConst!T t)
> {
>      //Compiler error if you try to modify t
>      //t += 1;
>
>      //Fine, cast it to mutable then modify
>      //Nothing unsafe here because we verified t is mutable
>      cast(T)t += 1;
> }
>
> void main()
> {
>      immutable n = 0;
>      //No IFTI match because n is immutable
>      bumpWithConstArg(n);
>
>      auto m = 0;
>      //Okay, m is mutable
>      bumpWithConstArg(m);
> }
>
> This doesn't actually work, but this is just off the top of my head.

I think you are making a wrong turn somewhere. This has exactly the same behavior:

void bumpWithConstArg(T)(ref T t)
{
   t += 1;
}

void main()
{
   immutable n = 0;
   bumpWithConstArg(n); // fails to compile

   auto m = 0;
   bumpWithConstArg(n);
}

The problem you have to solve is this:

void foo(const(int) t)
{
   bumpWithConstArg(t);
}

void main()
{
   immutable n = 0;
   foo(n); // needs to fail

   auto m = 0;
   foo(m); // needs to work.
}

-Steve
February 16, 2014
On Sun, 16 Feb 2014 00:22:33 -0500, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> The problem you have to solve is this:
>
> void foo(const(int) t)

Gahh... should have been:

void foo(ref const(int) t)

-Steve
February 16, 2014
On Sunday, February 16, 2014 03:25:08 Stanislav Blinov wrote:
> On Saturday, 15 February 2014 at 04:03:51 UTC, Adam D. Ruppe wrote:
> 
> What about a library solution for something like C++-esque mutable?

You're casting away const if you do that, and that's precisely what you shouldn't be doing. const is for _physical_ constness and should never be used if you want logical constness. Even attempting to use const for logical constness is incredibly dangerous, and the compiler is free to change what it does based on the knowledge that an object cannot be changed via a const reference and that an immutable object can never be changed. So, even if you manage to get away with casting away const and mutating in a particular situation right now, there's no guarantee that that code will work across compilers or architectures or that it will continue to work on future versions of the same compiler. The best thing to do is to just forget about even attempting to use const for logical constness. That's not what it's for, and you're going to have bugs (potentially very nasty and subtle bugs) if you attempt it.

- Jonathan M Davis
February 16, 2014
On Sunday, February 16, 2014 04:35:52 Meta wrote:
> On Sunday, 16 February 2014 at 03:26:42 UTC, Steven Schveighoffer
> 
> wrote:
> > I'm not sure what you are asking, because the answer I want to give is so trivial :)
> 
> Then I don't know what we're arguing about. I'm saying that if you pass mutable data to an inout function, inout effectively acts as logical const within that function, as the compiler doesn't allow you to modify the inout function argument but it is safe to cast away inout. Do you agree or disagree with this?

And that would be pointless. If a parameter is inout, then you have to treat it as const and cannot possibly know that the argument is mutable unless it's only ever passed a mutable argument and the programmer makes sure that that's all it's ever passed. And if that's the case, what's the point of having it be inout instead of mutable?

And you really shouldn't be thinking of inout as being different from const from the function's perspective. The only difference is that if the caller passes a mutable or immutable argument, then they get a return value with the same mutability instead of it ending up as const like it would if the function took const instead of inout. It makes no difference to the function itself, and the function writer should not do anything differently inside the function than they would do if it took const.

- Jonathan M Davis
February 16, 2014
On Sunday, 16 February 2014 at 06:28:45 UTC, Jonathan M Davis wrote:
> On Sunday, February 16, 2014 03:25:08 Stanislav Blinov wrote:
>> On Saturday, 15 February 2014 at 04:03:51 UTC, Adam D. Ruppe
>> wrote:
>> 
>> What about a library solution for something like C++-esque
>> mutable?
>
> You're casting away const if you do that, and that's precisely what you shouldn't be doing. const is for _physical_ constness and should never be used if you want logical constness...

I hear you. In this case, one might ask why casting away const is allowed at all :)
February 16, 2014
On Sunday, February 16, 2014 06:55:36 Stanislav Blinov wrote:
> On Sunday, 16 February 2014 at 06:28:45 UTC, Jonathan M Davis
> 
> wrote:
> > On Sunday, February 16, 2014 03:25:08 Stanislav Blinov wrote:
> >> On Saturday, 15 February 2014 at 04:03:51 UTC, Adam D. Ruppe wrote:
> >> 
> >> What about a library solution for something like C++-esque mutable?
> > 
> > You're casting away const if you do that, and that's precisely what you shouldn't be doing. const is for _physical_ constness and should never be used if you want logical constness...
> 
> I hear you. In this case, one might ask why casting away const is allowed at all :)

Primarily for cases where you have to pass a const object to a function which has mutable parameters, and you know that it's not going to mutate its parameters - that and the fact that D is a systems language, so it will let you blow off your foot if you really try. It _is_ possible to mutate a const object without breaking code, but you have to know exactly what you're doing, and it's very, very risky such that it's pretty much always a bad idea. But if you really want to try blowing your foot off, D will let you. It just protects you such that you can't do it without trying (e.g. by casting away const).

- Jonathan M Davis
February 16, 2014
IMHO only practically usable "logical const" alternative in D are getters (in absence of setters). For all other cases better to simply abandon the concept, it simply does not fit the type system.
1 2 3
Next ›   Last »