July 30, 2014
> So now you now have a safe function that is unsafe.

Even in debug builds.

Bye,
bearophile
July 30, 2014
On 07/31/2014 12:39 AM, Walter Bright wrote:
> On 7/30/2014 2:30 PM, Timon Gehr wrote:
>> Did you read the article?
>>
>> http://en.wikipedia.org/wiki/Assertion_%28computing%29#Disabling_assertions
>>
>>
>> '[...] disabling assertion checking can mean that a program that would
>> have
>> aborted will continue to run. This is sometimes preferable.'
>>
>> This is not what DMD does in -release where assertions are 'disabled'. It
>> follows a diametrally opposite philosophy.
>
> Not at all. The Wikipedia article does not argue that the program will
> continue in a valid state.

Then you must also hold the belief that continuing to run in an invalid state is sometimes preferable?
July 30, 2014
On 07/31/2014 12:55 AM, bearophile wrote:
>> So now you now have a safe function that is unsafe.
>
> Even in debug builds.
>
> Bye,
> bearophile

Why?
July 30, 2014
On 7/30/14, 3:41 PM, David Nadlinger wrote:
> On Wednesday, 30 July 2014 at 22:30:59 UTC, Walter Bright wrote:
>> On 7/30/2014 3:20 PM, Artur Skawina via Digitalmars-d wrote:
>>>    void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; }
>>
>> The compiler will insert array bounds checking for you.
>
> Trying to understand what your position is: In release mode, but with
> bounds checking enabled, would the compiler
>    a) be allowed to replace this with a RangeError or, say, ud2 or
> another halt()-type instruction?
>    b) treat any call to f() as undefined behavior?

I think that's a good example. My understanding (I know it wasn't me who was asked...): the presence of assert should not influence the introduction of bounds checks.

Andrei

July 30, 2014
On 7/30/14, 3:42 PM, Timon Gehr wrote:
> I've seen mostly agreement so far, but mostly not from you and Walter.

That's probably natural and healthy: contributors are trigger-happy about adding new and clever features, and Walter and I are conservative for good balance.

I propose we all tone it down a notch. It's good to discuss potential features; conversely it's not as good to transgress in a scoring-points contest where everybody tries to out-sarcasm the previous one and have the last word.

Far as I can understand yes, there is distinction between "assert" and "assume". I don't find it as material as it would need to be to make "assume" a language feature. We can refine assert's definition to reach a good compromise advantageous for all, which would be the best outcome of this discussion.

I don't meant this as definitive or even prescriptive; I've been plenty wrong before. But I think everyone is in agreement that good discussion is that that pushes the state of D forward. Let's all focus on that.


Thanks,

Andrei

July 30, 2014
On 07/31/14 01:14, Andrei Alexandrescu via Digitalmars-d wrote:
> On 7/30/14, 3:41 PM, David Nadlinger wrote:
>> On Wednesday, 30 July 2014 at 22:30:59 UTC, Walter Bright wrote:
>>> On 7/30/2014 3:20 PM, Artur Skawina via Digitalmars-d wrote:
>>>>    void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; }
>>>
>>> The compiler will insert array bounds checking for you.
>>
>> Trying to understand what your position is: In release mode, but with
>> bounds checking enabled, would the compiler
>>    a) be allowed to replace this with a RangeError or, say, ud2 or
>> another halt()-type instruction?
>>    b) treat any call to f() as undefined behavior?
> 
> I think that's a good example. My understanding (I know it wasn't me who was asked...): the presence of assert should not influence the introduction of bounds checks.

But it would. Special casing just the built-in types would only avoid the problem for built-in types. User defined types that handle the bounds checks differently would still be affected (and @unsafe).

artur
July 30, 2014
Andrei Alexandrescu:

> Far as I can understand yes, there is distinction between "assert" and "assume". I don't find it as material as it would need to be to make "assume" a language feature.

I didn't ask for an assume() in this thread. I have suggested/discussed/asked the inclusion in D of means to allow library writers to create a struct type like a SafeInt (that inside calls intrinsic functions like muls()) that manages the values range about as well as built-in types like int. I have asked this to allow optimizations typical of built-ins with library-defined types too (in particular to replace the call to muls with a regular faster multiplication).

Bye,
bearophile
July 31, 2014
On 7/30/14, 4:29 PM, Artur Skawina via Digitalmars-d wrote:
> On 07/31/14 01:14, Andrei Alexandrescu via Digitalmars-d wrote:
>> On 7/30/14, 3:41 PM, David Nadlinger wrote:
>>> On Wednesday, 30 July 2014 at 22:30:59 UTC, Walter Bright wrote:
>>>> On 7/30/2014 3:20 PM, Artur Skawina via Digitalmars-d wrote:
>>>>>     void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; }
>>>>
>>>> The compiler will insert array bounds checking for you.
>>>
>>> Trying to understand what your position is: In release mode, but with
>>> bounds checking enabled, would the compiler
>>>     a) be allowed to replace this with a RangeError or, say, ud2 or
>>> another halt()-type instruction?
>>>     b) treat any call to f() as undefined behavior?
>>
>> I think that's a good example. My understanding (I know it wasn't me who was asked...): the presence of assert should not influence the introduction of bounds checks.
>
> But it would. Special casing just the built-in types would only avoid
> the problem for built-in types. User defined types that handle the bounds
> checks differently would still be affected (and @unsafe).

I think bounds checking is an intrinsic feature of the language, not something easily configurable. -- Andrei

July 31, 2014
Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> On 7/30/14, 7:55 AM, Tofu Ninja wrote:
>> On Wednesday, 30 July 2014 at 14:51:34 UTC, Andrei Alexandrescu wrote:
>>> Also, it's unclear to me what the optimizer would be supposed to do if an assumption turns out to be false.
>> 
>> Bad... bad... things...
> 
> So then I see nothing that assume can do that assert can't. -- Andrei

The point is that optimizations based on asserts can have a big impact because they are leaky.

By having both, a dangerous assume and a mre harmless assert (that terminates in debug and does nothing in release), the programmer can use assert a lot without many consequences if there's an error. Only if optimizations are really necessary he can use assume, but he can use it with care.

It's not that assert is not powerful enough. It too dangerous to be used frequently.

Tobi
July 31, 2014
On 7/30/2014 3:40 PM, bearophile wrote:
> Walter Bright:
>
>>>    void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; }
>>
>> The compiler will insert array bounds checking for you.
>
> But if your "assert" is the same as an assume(), then the optimizer should
> remove bounds checks (otherwise it's a lousy implementation of assume()) and
> leave no tests whatsoever inside the function f. So now you now have a safe
> function that is unsafe.

That's a good point. You could reasonably argue that such an optimization should not happen.


> I think you are still missing the essential difference between assume and assert.

How does assume improve the situation?