D safety! New Feature?

ag0aep6g via Digitalmars-d digitalmars-d at puremagic.com
Fri Aug 5 23:12:10 PDT 2016


On 08/06/2016 03:57 AM, Mark J Twain wrote:
> On Friday, 5 August 2016 at 21:12:06 UTC, ag0aep6g wrote:
[...]
>> ----
>> struct MutableSomething
>> {
>>     int value;
>>     void mutate(int newValue) { value = newValue; }
>> }
>>
>> struct ImmutableSomething
>> {
>>     int value;
>>     /* no mutate method here */
>> }
>>
>> void main()
>> {
>>     auto i = ImmutableSomething(1);
>>     (cast(MutableSomething) i).mutate(2);
>>     import std.stdio;
>>     writeln(i.value); /* prints "2" */
>> }
>> ----
>
> wow, that seems like a huge design issues.
>
> Change one value to double though and it won't work. It's not general
> and seems to be a design flaw. It is not proof of anything in this case
> though. Why? Because an Queue might not have the same size as an
> ImmutableQueue and your "proof" only works when they are the same size.

You can cast between structs of different sizes. Just need to add some 
magical symbols:

----
struct MutableSomething
{
     float value;
     void mutate(int newValue) { value = newValue; }
     float somethingElse;
}

struct ImmutableSomething
{
     int value;
     /* no mutate method here */
}

void main()
{
     auto i = ImmutableSomething(1);
     (* cast(MutableSomething*) &i).mutate(2);
     import std.stdio;
     writeln(i.value); /* prints "2" */
}
----

You can cast anything to anything this way. It's absolutely unsafe, of 
course, just like casting away immutable and then mutating.

Also, MutableFoo and ImmutableFoo would usually have the same fields, 
wouldn't they?

[...]
> What kind of example? I have already given examples and proved that
> there is a functional difference.

The first example you gave was ImmutableArray. You later said it was a 
bad example, and I should disregard it. You also said something about 
caching allocations. I'm still not sure how that's supposed to work 
differently than with an ordinary array/object/whatever. If you uphold 
that point, I would appreciate an example in code that shows how it works.

Then you said that ImmutableQueue would have better errors than 
immutable Queue. That's wrong. Again, I'd appreciate a code example that 
shows the better errors, if you think you were correct there.

The next point was that one can cast immutable away, but they can't cast 
ImmutableFoo to MutableFoo. That's wrong, too. Casting immutable away 
and then mutating has undefined behavior, i.e. it's not allowed. And you 
can cast between unrelated types just fine.

One thing that's true is that an uncallable method is slightly different 
from one that's not there at all. Chris Wright gave an example where 
this would make it a tiny bit harder to mess up. But I think that's a 
rather minor point. And it has to be weighed against the downsides of 
ImmutableFoo, like the added complexity and it being more of an eyesore 
than immutable Foo. If there's more to this, a code example would do 
wonders.

Those are the points/examples that I'm aware of. I don't see much in 
favor of ImmutableFoo. If I missed anything, please point it out. I'm 
repeating myself, but code examples would be great then.

> I will not continue this conversation
> because you refuse accept that. First you haven't given your criteria
> for me to prove anything to you to satisfy whatever it is you want.

I'm not asking for (strict mathematical) proof. Just some example that 
highlights the pros of ImmutableFoo over immutable Foo. Can be 
subjective, like "See? This looks much nicer with my version". So far I 
just don't see any reason to use it over the immutable keyword.

> Second, I'm not here to waste my time trying to prove the merits of the
> tool. Again, either use it if you feel like it does something or don't.
> The method is not flawed in and of itself. It works(if it didn't,
> someone would have probably already shown it not to work).
>
> All you can do is assert a negative, which you can't prove yourself.

I'm not disputing that it works. (Neither am I saying that it does work 
correctly.) Assuming that it works just fine, it apparently does almost 
exactly what immutable does, just in a more cumbersome way.

> So we end up chasing each other tails, which I refuse to do.

I don't think the discussion has been that way so far. You've made some 
points where you were mistaken about how immutable and casting work. So 
they fell flat. You can defend them (point out errors in my refusals), 
or you can bring up other points. You don't have to, of course, but I 
don't think we have to agree to disagree just yet.

I don't know why you refuse to give code examples. If you're using this 
thing, you have something lying around, no? Some code that shows the 
benefits of your approach would shut me up. I'd try for sure to show 
that it works similarly well with plain immutable, though ;)

> If you want more proof then it is up to you, not me. I have my proof and
> it is good enough for me.

Sure, go ahead. But it seems to me that you're basing this on wrong 
impressions of immutable and casts.


More information about the Digitalmars-d mailing list