July 30, 2014
On Wednesday, 30 July 2014 at 18:02:39 UTC, Tobias Pankrath wrote:
> On Wednesday, 30 July 2014 at 17:58:45 UTC, Dicebot wrote:
>> On Wednesday, 30 July 2014 at 17:57:04 UTC, Andrei Alexandrescu wrote:
>>> "I assume my program is correct, generate the fastest code for it".
>>
>> Sounds like description for a command that should trigger "You are fired" e-mail notification.
>
> Totally depends on the situation. If you write a SAT solver you can make that assumptions without problems and just verify your results afterwards with a (way simpler) program that was compiled without -release.

It doesn't feel to me like SAT solvers are most common D programs out there, at least not more common than various network/web services. For pretty much any program which is not completely self-contained idea that it can be totally correct at any given point of time sounds like disaster.

At the same time "release" is rather encouraging flag to use, it is not like it is called "-iamreadyfortheconsequences".
July 30, 2014
On 07/30/2014 07:56 PM, Andrei Alexandrescu wrote:
> On 7/30/14, 9:31 AM, Timon Gehr wrote:
>> On 07/30/2014 05:04 PM, Andrei Alexandrescu wrote:
>>> On 7/30/14, 4:56 AM, Daniel Murphy wrote:
>>>> "Artur Skawina via Digitalmars-d"  wrote in message
>>>> news:mailman.217.1406713015.16021.digitalmars-d@puremagic.com...
>>>>
>>>>> `assert` is for *verifying* assumptions. It must not allow them
>>>>> to leak/escape. Otherwise a single not-100%-correct assert could
>>>>> defeat critical runtime checks.
>>>>
>>>> All you're saying is you want them to have different names, not that it
>>>> can't work the way Walter and I have described.  If your assertions are
>>>> invalid and you're compiling with -release, the compiler is free to
>>>> generate invalid code.  -release is dangerous.  -release is telling the
>>>> compiler that the code you wrote is correct,  and it can rely on it to
>>>> be correct.
>>>
>>> Exactly! -- Andrei
>>
>> This just moves the issue around and gives another term a non-obvious
>> meaning (the 'release' switch, which is not called e.g.
>> 'unsafeAssumeCorrect'.
>
> Well to me "-release" is "I assume my program is correct, generate the
> fastest code for it".
>
>> Which is still confusing, because it purports to
>> keep memory safety intact in @safe code by not disabling array bounds
>> checks by default). This is the very topic of this discussion: some
>> people get confused when they are assumed to use standard terms with
>> non-standard meanings. I was objecting to the apparent attitude that
>> this is entirely the fault of the one who gets confused, or that it is
>> symptomatic for lack of understanding of concepts.
>
> I'm not sure what would be the standard misused term in this case.
>
>> I mean, we have at least:
>>
>> some terms with whacky meanings for an outsider:
>> ...
>
>> 'lazy', which denotes pass by name instead of pass by need.
>
> It's not pass by name.
> ...

How so? Is it about failure to allocate a closure?

>> 'pure' which denies access to mutable static variables and IO.
>
> That's the consequence of functional purity as defined by D.

Somewhat debatable, but unworthy of debate.

> I see nothing wrong with it.
> ...

Luckily, that wasn't the claim. :)

>> ...
>
> I think you got a point there but if you searched any programming
> language in its pockets you're liable to find a bunch of similar lint.
> It's the way it goes - there's a need to maximize expressiveness while
> keeping vocabulary and grammatical constructs low. Few of these items
> are near the top of my list of issues in D, and I think the same goes
> for your list.
> ...

Probably. I never wrote it down in an ordered fashion.

>> To me, the apt response to a relative newcomer who gets confused by one
>> of those or something like them, especially when used without quotation
>> marks, is not at all similar to "You're misunderstanding and misusing
>> this feature, stop making noise."
>
> Consider this: after considerable effort you are failing to explain your
> case for "assume" to the language creators.

I think there was no such case (yet), only an unsuccessful attempt to clear up a misunderstanding based on terminology.

> How do you think you'll fare with newcomers?
> ...

Hopefully, awesomely. Much less preconceptions.

>
> Andrei
>

July 30, 2014
On 7/30/2014 8:28 AM, H. S. Teoh via Digitalmars-d wrote:
>[...]

Exactly right.

July 30, 2014
> a way for x and y (that are of the library-defined type SInt) to keep the value range of an ubyte.

Such management of value ranges by library code could also allow to modify the implementation of iota to compile this:


void main() {
    import std.range, std.algorithm;
    auto result = iota(20).map!(i => char(i + 'a'));
}


That mimics with library code this program that today compiles (thanks to various improvements in foreach range handling:

void main() {
    foreach (immutable i; 0 .. 20)
        char c = char(i + 'a');
}


You can probably special-case iota() in the compiler, to allow the first program (because in D the x..y is not first class, unfortunately), but if you offer more generic tools usable by library code you can use them in many other situations.

Bye,
bearophile
July 30, 2014
On Wednesday, 30 July 2014 at 18:18:24 UTC, Wyatt wrote:
Incidentally, this conversation actually forced
> me to look into the semantics of assert() in C and C++, and it turns out it's moderately muddy, but it seems they're only eliminated if you #define NDEBUG?
Building CMake-Projects with DCMAKE_BUILD_TYPE=Release,
will set -DNDEBUG and therefore disable asserts.

As C++ programmer, I can't understand how somebody would want to
have assert in his release-build.

"Therefore, this macro is designed to capture programming errors,
not user or run-time errors, since it is generally disabled after
a program exits its debugging phase."
http://www.cplusplus.com/reference/cassert/assert/
July 30, 2014
"Wyatt"  wrote in message news:duoyilszsehayiffprls@forum.dlang.org...

> Something (possibly the thing where "For fastest executables, compile with the -O -release -inline -boundscheck=off" is standard advice to anyone asking about performance) tells me this point needs to be made MUCH more clear wherever possible or the ghost of Scott Meyers will haunt us all. But that it's even a problem tells me we're facing a pattern of human error.  Is there no good way to eliminate it?

Well, that will give you the fastest possible code.  But there is no guarantee that small mistakes won't blow up in your face.  It could be hidden behind another compiler switch (-release is really a terrible name, maybe -livefastdieyoung ?  -noparachute ? -drinkthemysteyliquidreadthelabellater ?) but chances are it will be abused no matter what. 

July 30, 2014
"Dicebot"  wrote in message news:kvxcdcbgjwyydrjgbijg@forum.dlang.org... 

> At the same time "release" is rather encouraging flag to use, it is not like it is called "-iamreadyfortheconsequences".

-idontcareificrashsolongasicrashfast
July 30, 2014
On Wed, Jul 30, 2014 at 06:18:22PM +0000, Wyatt via Digitalmars-d wrote: [...]
> It seems pretty clear that there's a class of runtime check that is for debugging only that can be eliminated because you believe the code will never be used for evil;

assert(...)


> and there's a class of check where, no matter what, if some condition isn't met the application should immediately halt and catch fire lest it do something horrible.

enforce(...)


> Additionally raised in this thread is a class of expression that's only evaluated at compile time for the sake of making optimisations where you're saying "It's all right, I made sure this is good, go to town".
[...]

The proposal is to fold this meaning into assert() as well. I see no
harm in doing this, because:

1) When compiling in non-release mode:
	assert(...) means "I believe condition X holds, if it doesn't I
		screwed up big time, my program should abort"
	assume(...) means as "I believe condition X holds, if it doesn't
		I screwed up big time, my program should abort"

2) When compiling in release/optimized mode:
	assert(...) means "Trust me, I've made sure condition X holds,
		please optimize my code by not bothering to check
		condition X again"
	assume(...) means "Trust me, I've made sure condition X holds,
		please optimize my code by making use of condition X"

Certainly, making assert==assume extends the current meaning of assert in (2), but I don't see the incompatibility. In both cases under (2) we are *assuming*, without proof or check, that X holds, and based on that we are making some optimizations of the generated code.

I can't think of a real-life scenario where you'd want to distinguish between the two kinds of optimizations in (2).  Sure, in theory there's a conceptual distinction between the two cases, but I don't see what difference this makes in practice. It's splitting hairs over philosophical issues that ultimately don't matter in practice.


T

-- 
Век живи - век учись. А дураком помрёшь.
July 30, 2014
On 7/30/2014 11:13 AM, Ary Borenszweig wrote:
> (sorry for the sarcasm, removing assert is wrong to me)

That's why it's optional and up to the developer.
July 30, 2014
On 7/30/2014 11:24 AM, H. S. Teoh via Digitalmars-d wrote:
> If you want the check to always be there, use enforce, not assert.

enforce is NOT for checking program logic bugs, it is for checking for possible environmental failures, like writing to a read-only file.

If you want an assert to be there even in release mode,

    assert(exp) => exp || assert(0)