assert semantic change proposal

David Bregman via Digitalmars-d digitalmars-d at puremagic.com
Wed Aug 6 09:19:26 PDT 2014


On Wednesday, 6 August 2014 at 08:25:38 UTC, Walter Bright wrote:
> On 8/5/2014 11:28 PM, Tofu Ninja wrote:
>> Please stop responding in such a dismissive way, I think it is
>> already pretty obvious that some are getting frustrated by 
>> these
>> threads. Responding in a dismissive way makes it seem like you
>> don't take the arguments seriously.
>
> I responded to the equivalent design proposal several times 
> already, with detailed answers. This one is shorter, but the 
> essential aspects are there. I know those negative aspects came 
> across because they are addressed with your counter:

I don't think I've seen your arguments against adding assume(), 
last time this was discussed you were still claiming that there 
was no difference between the two, so we couldn't even get to 
discussing it!

>
> > How about something like
> > @expected assert(x > 2); or @assumed assert(x > 2);
> > It wouldn't introduce a new keyword, but still introduces the
> expected/assumed semantics.
>
> The riposte:
>
> 1. it's long with an unappealing hackish look
> 2. it follows in the C++ tradition of the best practice being 
> the long ugly way, and the deprecated practice is the 
> straightforward way (see arrays in C++)
> 3. users will be faced with two kinds of asserts, with a subtle 
> difference that is hard to explain, hard to remember which is 
> which, and will most likely use inappropriately
> 4. everyone who wants faster assert optimizations will have to 
> rewrite their (possibly extensive) use of asserts that we'd 
> told them was best practice. I know I'd be unhappy about having 
> to do such to my D code.
>

Nice, this is progress. You're giving us some actual reasoning! :)

Is this the full list of your reasons or just a subset?

1, 2:
Those don't apply to assume() without the annotations right? I 
agree that's hacky looking with annotations.

3:
If the separation is not made official, a lot of people will end 
up having to roll their own, potentially with all kinds of names. 
This is much more fragmenting than just having official assert 
and assume. myAssert, debugCheck, smurfAssert, etc. ugh.

As for the difference being subtle, hard to remember, understand, 
or explain: This totally supports my argument. If people don't 
even understand the subtlety, there's no way they are ready to be 
inserting undefined behavior everywhere in their code. assume (or 
your assert) is a dangerous power tool, joe coder probably 
shouldn't be using it at all. Yet you want it used everywhere by 
default?

4:
This is a valid argument. The flip side is that everyone else has 
to invent their own function and rewrite their code with it, 
unless they have 100% faith their code is not buggy, or don't 
care about undefined behavior (or don't know they care about it 
until they get bitten by it later). Or if they go for the quick 
fix by disabling -release, then you just pessimized their code 
instead of optimized it. Plus what about people who miss the 
change, or unmaintained code?

Isn't the default way of doing things to err on the side of not 
breaking people's code? Why is this time different? I know you 
hate more switches (for good reason), but this seems like a good 
case for -Oassert or -Ounsafe, for the elite few people whose 
code is actually suitable for such dangerous transformation.


I would like to note some additional benefits of separating the 
two concepts and hopefully get your thoughts on these. Some of 
these are repeating from previous posts.

-assert(0) is defined as a special case, so it can't express 
unreachability. This makes it less powerful for optimizing than 
it should be. assume(0) does not have this problem. e.g. 
switch(){ /* ... */ default: assume(0); }

-the proposed assert is not @safe, which creates complications 
since the current assert is. assume() does not have this problem, 
as it can be defined as @system from the start.

-with the functions separate, it can be made clear that assume() 
is a dangerous tool that should be used sparingly. It will mean 
that code is more searchable and easier to audit - if there is a 
heisenbug, try a search for @trusted and assume() constructs.

-retain C compatibility, which is supposed to be a goal of D.


More information about the Digitalmars-d mailing list