July 12, 2016
On 2016-07-12 07:33, Andrei Alexandrescu wrote:

> The solution (very ingenious, due to dicebot) in fact does not quite
> cast immutability away. Starting from a possibly immutable pointer, it
> subtracts an offset from it. At that point the memory is not tracked by
> the type system, but known to the allocator to contain metadata
> associated with the pointer that had been allocated with it. After the
> subtraction, the cast exposes the data which is mutable without
> violating the immutability of the object proper. As I said, it's quite
> an ingenious solution.

What if the immutable data is stored in ROM [1]? I assume it's not possible to have an offset to a completely different memory storage.

Not sure if this is important enough to care about.

[1] http://dlang.org/const-faq.html#invariant

-- 
/Jacob Carlborg
July 12, 2016
On 07/12/2016 02:45 PM, Jacob Carlborg wrote:
> On 2016-07-12 07:33, Andrei Alexandrescu wrote:
>
>> The solution (very ingenious, due to dicebot) in fact does not quite
>> cast immutability away. Starting from a possibly immutable pointer, it
>> subtracts an offset from it. At that point the memory is not tracked by
>> the type system, but known to the allocator to contain metadata
>> associated with the pointer that had been allocated with it. After the
>> subtraction, the cast exposes the data which is mutable without
>> violating the immutability of the object proper. As I said, it's quite
>> an ingenious solution.
>
> What if the immutable data is stored in ROM [1]? I assume it's not
> possible to have an offset to a completely different memory storage.
>
> Not sure if this is important enough to care about.
>
> [1] http://dlang.org/const-faq.html#invariant

The assumption is that the memory comes from that allocator. -- Andrei

July 12, 2016
On 07/12/2016 02:37 PM, deadalnix wrote:
> On Tuesday, 12 July 2016 at 14:17:30 UTC, Andrei Alexandrescu wrote:
>> Indeed I'm not the sharpest tool in the shed, and since it's already
>> been established I'm the idiot and you're the wise man
>> (congratulations - surely enough the great work to substantiate that
>> is very soon to follow) in the proverb, I hope you'll allow me one
>> more pedestrian question.
>>
>
> Proverb are not meant to be interpreted literally.

Also proverbs are not licenses for people to be jerks.

>> So I've been looking through this thread for the five examples of what
>> you're talking about (which to my mind is "@safe is just a
>> convention") and the closest I could find is your post on
>> http://forum.dlang.org/post/iysrtqzytdnrxsqtfwvk@forum.dlang.org.
>>
>> So there you discuss the inconsistency of "alias" which as far as I
>> understand has nothing to do with safety. Then we have:
>>
>> enum E { A = 1, B = 2 }
>> E bazinga = A | B;
>> final switch (bazinga) { case A: ... case B: ... } // Enjoy !
>>
>> which I pasted with minor changes here:
>> https://dpaste.dzfl.pl/b4f84374c3ae. I'm unclear how that interacts
>> with @safe. It could, if the language would allow executing unsafe
>> code after the switch. But it doesn't. Could you please clarify? And
>> could you please point to the other examples?
>>
>>
>> Thanks,
>>
>> Andrei
>
> My point has nothing to do with safety, and this is why various example
> have nothing to do with safety. Safety was an example. The enum/final
> switch thing was another. The alias thing again one more.

Where are the others?


Andrei
July 12, 2016
On Tuesday, 12 July 2016 at 18:45:00 UTC, Jacob Carlborg wrote:
> On 2016-07-12 07:33, Andrei Alexandrescu wrote:
>
>> The solution (very ingenious, due to dicebot) in fact does not quite
>> cast immutability away. Starting from a possibly immutable pointer, it
>> subtracts an offset from it. At that point the memory is not tracked by
>> the type system, but known to the allocator to contain metadata
>> associated with the pointer that had been allocated with it. After the
>> subtraction, the cast exposes the data which is mutable without
>> violating the immutability of the object proper. As I said, it's quite
>> an ingenious solution.
>
> What if the immutable data is stored in ROM [1]? I assume it's not possible to have an offset to a completely different memory storage.
>
> Not sure if this is important enough to care about.
>
> [1] http://dlang.org/const-faq.html#invariant

The idea is that in general, you cannot cast away immutability because of this. But the allocator knows that the data at (ptr-offset) is not in ROM (because it didn't allocate it from ROM), and thus can cast away immutability without any issue.
And the allocator is not violating any type system invariant, because there cannot exist any immutable reference to (ptr-offset), given that this area was not given away by the allocator.
July 12, 2016
On 07/12/2016 02:53 PM, Lodovico Giaretta wrote:
> On Tuesday, 12 July 2016 at 18:45:00 UTC, Jacob Carlborg wrote:
>> On 2016-07-12 07:33, Andrei Alexandrescu wrote:
>>
>>> The solution (very ingenious, due to dicebot) in fact does not quite
>>> cast immutability away. Starting from a possibly immutable pointer, it
>>> subtracts an offset from it. At that point the memory is not tracked by
>>> the type system, but known to the allocator to contain metadata
>>> associated with the pointer that had been allocated with it. After the
>>> subtraction, the cast exposes the data which is mutable without
>>> violating the immutability of the object proper. As I said, it's quite
>>> an ingenious solution.
>>
>> What if the immutable data is stored in ROM [1]? I assume it's not
>> possible to have an offset to a completely different memory storage.
>>
>> Not sure if this is important enough to care about.
>>
>> [1] http://dlang.org/const-faq.html#invariant
>
> The idea is that in general, you cannot cast away immutability because
> of this. But the allocator knows that the data at (ptr-offset) is not in
> ROM (because it didn't allocate it from ROM), and thus can cast away
> immutability without any issue.
> And the allocator is not violating any type system invariant, because
> there cannot exist any immutable reference to (ptr-offset), given that
> this area was not given away by the allocator.

Thanks for the crisp summary. -- Andrei
July 12, 2016
On 7/12/2016 6:13 AM, John Colvin wrote:
> On Tuesday, 12 July 2016 at 10:19:04 UTC, Walter Bright wrote:
>> On 7/12/2016 2:40 AM, John Colvin wrote:
>>> For the previous statement to be false, you must define cases where
>>> casting away immutability *is* defined.
>>
>> @system programming is, by definition, operating outside of the
>> language guarantees of what happens. It's up to you, the systems
>> programmer, to know what you're doing there.
>
> This is so, so wrong. There's a world of difference between "you have to
> get this right or you're in trouble" and "the compiler (and especially
> the optimiser) is free to assume that what you're doing never happens".
> Undefined behaviour, as used in practice by modern optimising compilers,
> is in the second camp. You might have a different definition, but it's
> not the one everyone else is using and not the one that our two fastest
> backends understand.
>
> Given the definition of undefined behaviour that everyone else
> understands, do you actually mean "modifying immutable data by any means
> is undefined behaviour" instead of "casting away immutable is undefined
> behaviour"?

What's the difference?

Anyhow, if you cast away immutability, and the data exists in rom, you still can't write to it (you'll get a seg fault). If it is in mutable memory, you can change it, but other threads may be caching or reading the value while you do that, i.e. synchronization issues. The optimizer may be taking advantage of immutability in its semantic transformations.

As a systems programmer, you'd have to account for that.

July 12, 2016
On 7/12/2016 11:37 AM, deadalnix wrote:
> My point has nothing to do with safety, and this is why various example
> have nothing to do with safety.

So the only known issues with @safe are already in bugzilla. This is good information.

July 12, 2016
On 7/12/2016 8:04 AM, Andrei Alexandrescu wrote:
> That would not be the right thing to do.

Another wrinkle is that immutable data can be shared, and casting away immutability means it won't be synchronized anymore. So doing this would require knowledge that other threads aren't accessing it.

July 13, 2016
On 13/07/16 03:29, Walter Bright wrote:
>So doing this would
> require knowledge that other threads aren't accessing it.
>

You say that as if it's a bad thing.

Yes, casting away protection should be done only when you know what you're doing. If you make a mistake, bad things will happen.

I think a system programming language cannot prevent the user from doing dangerous things. You will simply not be leaving enough rope.

Shachar
July 13, 2016
On 2016-07-12 20:48, Andrei Alexandrescu wrote:

> The assumption is that the memory comes from that allocator. -- Andrei

Right, didn't think of that.

-- 
/Jacob Carlborg