Re: assume, assert, enforce, @safe
On 23/09/2014 19:35, H. S. Teoh via Digitalmars-d wrote: it game will crash on ANY bug, it will contain alot less bugs. 'cause even the dumbiest QA full of monkeys will not let the game which crashes once in a ten seconds to go out of the door. When doing QA, that's a whole different thing than when playing normally. +1. When the game blatantly crashes on every little thing, there is pressure on the coders to actually fix the problem. Ignored errors == convenient excuse for coders to evade work (it's*only* a minor display glitch!, the deadline's tomorrow, we don't have time to fix this, it's 5pm, I need to go home and feed my goldfish, besides, it still works anyway, more or less, etc.). I would invite you to buy a *retail copy* of Elder Scrolls 3 : Morrowind for PC and try playing that. The game did exactly what Walter and you guys suggested: when an assertion tripped, it would crash straight away to the desktop, with only a message dialog saying that an assertion had failed (with info on the source and line of the assertion, and an extra message). I couldn't play that game, it would crash too often. And saving wasn't quick enough that I could in practice be manually saving every 15 min. or so. Only when several iterations of patches game out, several months after release, did the game become stable enough to be played enjoyably. (in fairness, if the assertions where about core game logic, I too would prefer a crash rather then possible corruption of game state. But IIRC there was a few assertions crashes that seemed related to textures, directx, or shader stuff - for that I could have lived without a game crash) Sometimes even with known bugs the game is shipped, because of management pressure and/or huge delays already. (especially with pressures to do multi-platform releases). -- Bruno Medeiros https://twitter.com/brunodomedeiros
Re: assume, assert, enforce, @safe
On Monday, 29 September 2014 at 13:01:19 UTC, Bruno Medeiros wrote: On 23/09/2014 19:35, H. S. Teoh via Digitalmars-d wrote: it game will crash on ANY bug, it will contain alot less bugs. 'cause even the dumbiest QA full of monkeys will not let the game which crashes once in a ten seconds to go out of the door. When doing QA, that's a whole different thing than when playing normally. +1. When the game blatantly crashes on every little thing, there is pressure on the coders to actually fix the problem. Ignored errors == convenient excuse for coders to evade work (it's*only* a minor display glitch!, the deadline's tomorrow, we don't have time to fix this, it's 5pm, I need to go home and feed my goldfish, besides, it still works anyway, more or less, etc.). I would invite you to buy a *retail copy* of Elder Scrolls 3 : Morrowind for PC and try playing that. The game did exactly what Walter and you guys suggested: when an assertion tripped, it would crash straight away to the desktop, with only a message dialog saying that an assertion had failed (with info on the source and line of the assertion, and an extra message). I couldn't play that game, it would crash too often. And saving wasn't quick enough that I could in practice be manually saving every 15 min. or so. Only when several iterations of patches game out, several months after release, did the game become stable enough to be played enjoyably. (in fairness, if the assertions where about core game logic, I too would prefer a crash rather then possible corruption of game state. But IIRC there was a few assertions crashes that seemed related to textures, directx, or shader stuff - for that I could have lived without a game crash) Sometimes even with known bugs the game is shipped, because of management pressure and/or huge delays already. (especially with pressures to do multi-platform releases). And the right attitude as consumer is to ask for the money back, not to wait patiently for the day those bugs eventually get fixed. If everyone did that, the quality in IT would be much better. -- Paulo
Re: assume, assert, enforce, @safe
On Monday, 29 September 2014 at 13:41:33 UTC, Paulo Pinto wrote: And the right attitude as consumer is to ask for the money back, not to wait patiently for the day those bugs eventually get fixed. If everyone did that, the quality in IT would be much better. The mobile freemium model where you try before you buy kind of offsets this position though. But if the game saves frequently and reloads quickly it is less annoying. After watching the initial years of MMO I also think people are willing to live with bugs, nerfing and other upsetting events until the Next Big Thing comes along. There probably is some value in having something common to complain about. :-)
Re: assume, assert, enforce, @safe
On 9/29/2014 6:01 AM, Bruno Medeiros via Digitalmars-d wrote: I would invite you to buy a *retail copy* of Elder Scrolls 3 : Morrowind for PC and try playing that. The game did exactly what Walter and you guys suggested: when an assertion tripped, it would crash straight away to the desktop, with only a message dialog saying that an assertion had failed (with info on the source and line of the assertion, and an extra message). I couldn't play that game, it would crash too often. And saving wasn't quick enough that I could in practice be manually saving every 15 min. or so. Only when several iterations of patches game out, several months after release, did the game become stable enough to be played enjoyably. (in fairness, if the assertions where about core game logic, I too would prefer a crash rather then possible corruption of game state. But IIRC there was a few assertions crashes that seemed related to textures, directx, or shader stuff - for that I could have lived without a game crash) Sometimes even with known bugs the game is shipped, because of management pressure and/or huge delays already. (especially with pressures to do multi-platform releases). The problem isn't the use of asserts and quick exiting of the app, though. The problem is releasing an app of horrible quality. The assert based reporting just makes it super obvious. There's no way to say how bad the game would have been with try and continue anyway code.
Re: assume, assert, enforce, @safe
On 18/09/2014 17:49, H. S. Teoh via Digitalmars-d wrote: On Thu, Sep 18, 2014 at 05:05:31PM +0100, Bruno Medeiros via Digitalmars-d wrote: On 01/08/2014 05:12, Walter Bright wrote: On 7/31/2014 2:21 PM, Sean Kelly wrote: Thoughts? If a process detects a logic error, then that process is in an invalid state that is unanticipated and unknown to the developer. The only correct solution is to halt that process, and all processes that share memory with it. Anything less is based on faith and hope. If it is medical, flight control, or banking software, I submit that operating on faith and hope is not acceptable. If it's a dvr or game, who cares :-) My dvr crashes regularly needing a power off reboot. If it's a game, who cares - Oh let's see... let's say I'm playing a game, and then there's a bug (which happens often). What would I prefer to happen: * a small (or big) visual glitch, like pixels out of place, corrupted textures, or 3D model of an object becoming deformed, or the physics of some object behaving erratically, or some broken animation. * the whole game crashes, and I lose all my progress? [...] What if the program has a bug that corrupts your save game file, but because the program ignores these logic errors, it just bumbles onward and destroys all your progress *without* you even knowing about it until much later? (I have actually experienced this firsthand, btw. I found it *far* more frustrating than losing all my progress -- at least I can restore the game to the last savepoint, and have confidence that it isn't irreparably corrupted! I almost threw the computer out the window once when after a game crash I restored the savefile, only to discover a few hours later that due to a corruption in the savefile, it was impossible to win the game after all. Logic errors should *never* have made it past the point of detection.) T I never implied a program should try to recover or ignore *all* bugs that an assertion triggers. Sometimes it is better to crash the whole program straight away, yes. But sometimes ignoring the bug and keep going (or throwing an exception) is perfectly fine, and far better than the alternative (full program crash). And since when you're working with assertion checks you know if they relate to game logic (the equivalent to business model), or to presentation (UI, 3D, graphics, sound, etc.), you could define if the program tries to continue running or not. Under Walter's idea, you'd always crash the program. Even if I had to choose between an occasional savefile corruption that would render a game impossible to win, and having my games crash every time ANY bug happened, I would still prefer the former. Because of all the games I played in my life (I'm 31 and I like gaming, so I've played quite a few), I've encountered maybe 3 games where that happened, that I can remember (*). But I've seen visual glitches in nearly all games I've played, and in maybe 60-75% of them those glitches happened *often enough* that it would render the game virtually unplayable. BTW, the same doesn't apply just to games. Same thing for other desktop applications: IDEs, browsers, etc.. For example, in an IDE a bug in a parser might bring some visual or behavior glitch ing the current editor, but the whole IDE doesn't need to crash because of that! * If anyone is curious: Elder Scrolls 2 - Daggerfall: one of the possible endings, the one I was trying to go for, became impossible to achieve due to a main quest bug. Fallout 2: an big side quest in a town became completely unresolvable. Ultima VII- The Black Gate : with a certain magical spell you can sneak into a cave by a point that was meant only for exit. The problem is that the cave was only meant to be entered in a different place, and much later in the storyline. As such, in the cave you start to find dialogues, and notes that are clues to a *murder* that hadn't even happened yet! Unfortunately I only realized I was not meant to be the cave after several hours of gameplay (battling high level monsters took a while)... and even after that, I not only lost those hours, but I had a big twist and a massive chunk of the game's storyline spoiled... -- Bruno Medeiros https://twitter.com/brunodomedeiros
Re: assume, assert, enforce, @safe
On Tue, 23 Sep 2014 15:19:56 +0100 Bruno Medeiros via Digitalmars-d digitalmars-d@puremagic.com wrote: Even if I had to choose between an occasional savefile corruption that would render a game impossible to win, and having my games crash every time ANY bug happened, I would still prefer the former. it game will crash on ANY bug, it will contain alot less bugs. 'cause even the dumbiest QA full of monkeys will not let the game which crashes once in a ten seconds to go out of the door. yet game that renders itself unbeatable after some bug can sucessfully pass even the very good QA. so it's easy: bug -- crash. oh, this game has only savepoint save system and last save was long ago? designers of this game are lazy dumbs, don't buy their games anymore. signature.asc Description: PGP signature
Re: assume, assert, enforce, @safe
On Tue, Sep 23, 2014 at 09:25:51PM +0300, ketmar via Digitalmars-d wrote: On Tue, 23 Sep 2014 15:19:56 +0100 Bruno Medeiros via Digitalmars-d digitalmars-d@puremagic.com wrote: Even if I had to choose between an occasional savefile corruption that would render a game impossible to win, and having my games crash every time ANY bug happened, I would still prefer the former. it game will crash on ANY bug, it will contain alot less bugs. 'cause even the dumbiest QA full of monkeys will not let the game which crashes once in a ten seconds to go out of the door. +1. When the game blatantly crashes on every little thing, there is pressure on the coders to actually fix the problem. Ignored errors == convenient excuse for coders to evade work (it's *only* a minor display glitch!, the deadline's tomorrow, we don't have time to fix this, it's 5pm, I need to go home and feed my goldfish, besides, it still works anyway, more or less, etc.). T -- Life is complex. It consists of real and imaginary parts. -- YHL
Re: assume, assert, enforce, @safe
On 18/09/14 18:49, H. S. Teoh via Digitalmars-d wrote: What if the program has a bug that corrupts your save game file, but because the program ignores these logic errors, it just bumbles onward and destroys all your progress *without* you even knowing about it until much later? Happened to me with Assassin's Creed 3, twice. It did crash and when I started the game again the save files where corrupted. Although, I have no way of knowing if it crashed when the bug happened or much later. -- /Jacob Carlborg
Re: assume, assert, enforce, @safe
On Thursday, 18 September 2014 at 16:55:33 UTC, H. S. Teoh via Digitalmars-d wrote: On Thu, Sep 18, 2014 at 07:13:48PM +0300, ketmar via Digitalmars-d wrote: On Thu, 18 Sep 2014 17:05:31 +0100 Bruno Medeiros via Digitalmars-d digitalmars-d@puremagic.com wrote: * a small (or big) visual glitch, like pixels out of place, corrupted textures, or 3D model of an object becoming deformed, or the physics of some object behaving erratically, or some broken animation. or the whole game renders itself unbeatable due to some correpted data, but you have no way to know it until you made it to the Final Boss and can never win that fight. ah, so charming! Exactly Seriously, this philosophy of ignoring supposedly minor bugs in software is what led to the sad state of software today, where nothing is reliable and people have come to expect that software will inevitably crash, and that needing to reboot an OS every now and then just to keep things working is acceptable. Yet, strangely enough, people will scream bloody murder if a car behaved like that. T Fully agree. I support the idea that software companies should be accountable by their products the same way as other industries. Just like when you buy a car the car dealer will be accountable for any defect. Sure it will make software development a bit more expensive, but it will also end with a lot of cowboy programming, updates that only work in full moon, ... -- Paulo
Re: assume, assert, enforce, @safe
On Thursday, 18 September 2014 at 16:05:32 UTC, Bruno Medeiros wrote: If it's a game, who cares - Oh let's see... let's say I'm playing a game, and then there's a bug (which happens often). What would I prefer to happen: * a small (or big) visual glitch, like pixels out of place, corrupted textures, or 3D model of an object becoming deformed, or the physics of some object behaving erratically, or some broken animation. * the whole game crashes, and I lose all my progress? So Walter, which one do you think I prefer? Me, and the rest of the million gamers out there? Don't worry. A shipped game would have been built with -release set because it's a release build. No one cares about the reliability of released software, only test builds. /rant
Re: assume, assert, enforce, @safe
On Thursday, 18 September 2014 at 16:55:33 UTC, H. S. Teoh via Digitalmars-d wrote: Seriously, this philosophy of ignoring supposedly minor bugs in software is what led to the sad state of software today, where nothing is reliable and people have come to expect that software will inevitably crash, and that needing to reboot an OS every now and then just to keep things working is acceptable. Yet, strangely enough, people will scream bloody murder if a car behaved like that. A car did behave like that--the Toyota Prius. It would randomly accelerate out of control because of a bug in the car's software. People died. And yes, bloody murder was screamed. I used to work for the telephone company, and telcos are a bit weird because they're considered an essential service. If martial law were enacted in the US, telephone workers would still be allowed on the street because the telephone system must work. There was one instance when I was working that I had to get to the switch for maintenance during a horrible storm where the police had closed the roads. No problem--they let me through. Network services are rapidly approaching this point. People depend on the internet for communication these days as much or more than they do on telephone calls. I suspect/hope that it won't be long before communications software is held to standards similar to telephone, which will require a huge adjustment on the part of programmers. People in this industry still tend to not think of things in terms of 5+ nines of uptime for their service, despite that being the expectation of their users.
Re: assume, assert, enforce, @safe
On Friday, 19 September 2014 at 13:56:14 UTC, Sean Kelly wrote: I suspect/hope that it won't be long before communications software is held to standards similar to telephone, which will require a huge adjustment on the part of programmers. People in this industry still tend to not think of things in terms of 5+ nines of uptime for their service, despite that being the expectation of their users. Oh, just to clarify one thing though. The typical way that a lot of network services work for reasons of performance is via asynchronous event-based models (fancy versions of the Unix poll() routine). If a logic error results in a transaction failure and I can be sure that the scope of this error is limited to the state of that one transaction, I don't necessarily want to terminate the process as it will result in thousands of failed transactions. Functional languages like Erlang tend to support this model really well, because a process is actually just a thread of execution in the VM. The process (thread) is terminated and the VM soldiers on because there's no logical way for the state of the VM to have been corrupted. I'm still unsure how I feel about D in this regard. Clients will retry if a request fails, and so terminating the entire process and failing thousands of transactions would be bad but possibly still invisible to users. At least unless the logic error occurs in a common path of execution, in which case terminating the entire process on a logic error becomes a potential attack vector to bring down the entire system. I suspect that what I'll be doing with D is moving away from asserts and throwing Errors to give myself the latitude to handle situations in whatever manner I feel is appropriate. I'm still not sure about this, but I'm leaning towards feeling that the D approach is possibly too draconian for multi-user systems. Perhaps it's possible to split each transaction off to be handled by a separate process (via unix domain sockets, for example, or IPC), but I suspect this won't scale to the degree that's needed. This is how web servers used to work, for example, and I'm pretty sure none of them do this any more. But I want to think more on the problem, as I do like the motivation behind these rules.
Re: assume, assert, enforce, @safe
On Tuesday, 16 September 2014 at 00:33:47 UTC, Steven Schveighoffer wrote: The cost for this is tremendous. You may as well not use classes. Looks like ldc has a separate option to turn off invariants.
Re: assume, assert, enforce, @safe
On Thu, 18 Sep 2014 08:57:20 -0400, Kagamin s...@here.lot wrote: On Tuesday, 16 September 2014 at 00:33:47 UTC, Steven Schveighoffer wrote: The cost for this is tremendous. You may as well not use classes. Looks like ldc has a separate option to turn off invariants. That's a good thing. I'm actually thinking this should be in DMD as well. invariants, always called by default, when almost no object defines one, is really costly. It's also a virtual call, which means any inlining is not possible. -Steve
Re: assume, assert, enforce, @safe
On 01/08/2014 05:12, Walter Bright wrote: On 7/31/2014 2:21 PM, Sean Kelly wrote: Thoughts? If a process detects a logic error, then that process is in an invalid state that is unanticipated and unknown to the developer. The only correct solution is to halt that process, and all processes that share memory with it. Anything less is based on faith and hope. If it is medical, flight control, or banking software, I submit that operating on faith and hope is not acceptable. If it's a dvr or game, who cares :-) My dvr crashes regularly needing a power off reboot. If it's a game, who cares - Oh let's see... let's say I'm playing a game, and then there's a bug (which happens often). What would I prefer to happen: * a small (or big) visual glitch, like pixels out of place, corrupted textures, or 3D model of an object becoming deformed, or the physics of some object behaving erratically, or some broken animation. * the whole game crashes, and I lose all my progress? So Walter, which one do you think I prefer? Me, and the rest of the million gamers out there? So yeah, we care, and we are the consumers of an industry worth more than the movie industry. As a software developer, to dismiss these concerns is silly and unprofessional. -- Bruno Medeiros https://twitter.com/brunodomedeiros
Re: assume, assert, enforce, @safe
On Thu, 18 Sep 2014 17:05:31 +0100 Bruno Medeiros via Digitalmars-d digitalmars-d@puremagic.com wrote: * a small (or big) visual glitch, like pixels out of place, corrupted textures, or 3D model of an object becoming deformed, or the physics of some object behaving erratically, or some broken animation. or the whole game renders itself unbeatable due to some correpted data, but you have no way to know it until you made it to the Final Boss and can never win that fight. ah, so charming! signature.asc Description: PGP signature
Re: assume, assert, enforce, @safe
On Thu, Sep 18, 2014 at 05:05:31PM +0100, Bruno Medeiros via Digitalmars-d wrote: On 01/08/2014 05:12, Walter Bright wrote: On 7/31/2014 2:21 PM, Sean Kelly wrote: Thoughts? If a process detects a logic error, then that process is in an invalid state that is unanticipated and unknown to the developer. The only correct solution is to halt that process, and all processes that share memory with it. Anything less is based on faith and hope. If it is medical, flight control, or banking software, I submit that operating on faith and hope is not acceptable. If it's a dvr or game, who cares :-) My dvr crashes regularly needing a power off reboot. If it's a game, who cares - Oh let's see... let's say I'm playing a game, and then there's a bug (which happens often). What would I prefer to happen: * a small (or big) visual glitch, like pixels out of place, corrupted textures, or 3D model of an object becoming deformed, or the physics of some object behaving erratically, or some broken animation. * the whole game crashes, and I lose all my progress? [...] What if the program has a bug that corrupts your save game file, but because the program ignores these logic errors, it just bumbles onward and destroys all your progress *without* you even knowing about it until much later? (I have actually experienced this firsthand, btw. I found it *far* more frustrating than losing all my progress -- at least I can restore the game to the last savepoint, and have confidence that it isn't irreparably corrupted! I almost threw the computer out the window once when after a game crash I restored the savefile, only to discover a few hours later that due to a corruption in the savefile, it was impossible to win the game after all. Logic errors should *never* have made it past the point of detection.) T -- People tell me I'm stubborn, but I refuse to accept it!
Re: assume, assert, enforce, @safe
On Thu, Sep 18, 2014 at 07:13:48PM +0300, ketmar via Digitalmars-d wrote: On Thu, 18 Sep 2014 17:05:31 +0100 Bruno Medeiros via Digitalmars-d digitalmars-d@puremagic.com wrote: * a small (or big) visual glitch, like pixels out of place, corrupted textures, or 3D model of an object becoming deformed, or the physics of some object behaving erratically, or some broken animation. or the whole game renders itself unbeatable due to some correpted data, but you have no way to know it until you made it to the Final Boss and can never win that fight. ah, so charming! Exactly Seriously, this philosophy of ignoring supposedly minor bugs in software is what led to the sad state of software today, where nothing is reliable and people have come to expect that software will inevitably crash, and that needing to reboot an OS every now and then just to keep things working is acceptable. Yet, strangely enough, people will scream bloody murder if a car behaved like that. T -- Skill without imagination is craftsmanship and gives us many useful objects such as wickerwork picnic baskets. Imagination without skill gives us modern art. -- Tom Stoppard
Re: assume, assert, enforce, @safe
The point is that using these enforce() statements means that these methods cannot be nothrow, which doesn't seem particularly nice if it can be avoided. Now, on the one hand, one could say that, quite obviously, these methods cannot control their input. But on the other hand, it's reasonable to say that these methods' input can and should never be anything other than 100% controlled by the programmer. My take is that, for this reason, these should be asserts and not enforce() statements. What are your thoughts on the matter? Assert's are disable by -release option. If you want to do check, and don't want to raise exception you can define special function like this: import std.stdio; void enforceNoThrow(bool pred, string msg, string file = __FILE__, uint line = __LINE__) { if (!pred) { stderr.writefln(Fatal error: %s at %s:%s, msg, file, line); assert(0); } } void doSomething(int min, int middle, int max) { enforceNoThrow(middle = min middle = max, middle out of bounds); } doSomething(1, 5, 3); //prints error message into stderr and terminate programm execution This way is better for library code then asserts. Asserts should be used for catching internal bugs, but incorrect code is external bug (for extern library)
Re: assume, assert, enforce, @safe
On Tuesday, 16 September 2014 at 00:33:47 UTC, Steven Schveighoffer wrote: You may as well not use classes. Always a good idea ;)
Re: assume, assert, enforce, @safe
On Fri, 01 Aug 2014 01:07:55 -0400, Jonathan M Davis jmdavisp...@gmx.com wrote: On Thursday, 31 July 2014 at 20:49:18 UTC, Timon Gehr wrote: On 07/31/2014 09:37 PM, Jonathan M Davis wrote: disable contracts, turn assert(0) into a halt instruction, and disable bounds checking in @system and @trusted code. So, if you want to keep the assertions and contracts and whatnot in, Unfortunately, if used pervasively, assertions and contracts and whatnot may actually hog the speed of a program in a way that breaks the deal. Disabling assertions (and whatnot), assuming assertions to be true (and disabling whatnot) and leaving all assertions and whatnot in are different trade-offs, of which assuming all assertions to be true is the most dangerous one. Why hide this behaviour in '-release'? I'm afraid that I don't see the problem. If you want assertions left in in your release/production builds, then don't use -release. If you want them removed, then use -release. Are you objecting to the fact that the compiler can do further optimizations based on the fact that the assertions are presumed to be true if they're removed? I really don't see any problem with that. You're screwed regardless if the assertions would have failed. By their very nature, if an assertion would have failed, your program is an invalid state, so if you don't want to risk having code run that would have failed an assertion, then just don't compile with -release. And if you are willing to assume that the assertions won't fail and have them disabled in your release build, then you might as well gain any extra optimizations that can be made from assuming that the assertion is true. You're already making that assumption anyway and potentially letting your program enter an invalid state. This is not tenable. I realized when developing a library with classes, that not doing -release, means every virtual call is preceded and followed by a call to assert(obj), which calls Object.invariant -- a virtual call. Even if you don't define any invariant, it's still called (maybe final classes are better, but I'm not sure). The cost for this is tremendous. You may as well not use classes. -Steve
Re: assume, assert, enforce, @safe
On Tuesday, 5 August 2014 at 16:35:42 UTC, Andrew Godfrey wrote: out, but in general if the compiler keeps track of properties of things then it could start making algorithmic-level performance decisions that today we always have to make by hand. To me that's interesting. I think the most potent source for optimization is getting expressive formalisms in place for allowing axioms and theorems to pass through foreign function calls. That would allow you to call custom C functions/machine language in a loop with less penalties.
Re: assume, assert, enforce, @safe
On Monday, 4 August 2014 at 00:59:10 UTC, Andrei Alexandrescu wrote: For my money, consider Walter's response: What I see is Microsoft attempting to bring D's assert semantics into C++. :) As I've mentioned before, there is inexorable pressure for this to happen, and it will happen. I find it to the point, clear, and funny. Yeah, it was funny because: ( http://msdn.microsoft.com/en-us/library/1b3fsfxw.aspx ) «Caution: A program must not contain an invalid __assume statement on a reachable path. If the compiler can reach an invalid __assume statement, the program might cause unpredictable and potentially dangerous behavior.» Please note «if the compiler can reach», not «if a path can be executed». And «inexorable»: ( https://www.google.no/search?q=inexorable ) - the seemingly inexorable march of new technology - (of a person) impossible to persuade; unrelenting. Of course, being unrelenting goes with the territory of single-handedly building a c++ competitor. So it is not a bad trait. The bad thing here is not making compile assert as assume an experimental feature, but making it the default. People who are autodidact also sometimes find new ways of doing things because they are more likely to go explore new paths. But I don't think this path is all that new… so I hope Walter, if he continues walking down this path, remains unrelenting and keeps walking past assert as assume until he finds truly new territory in the realm of formal methods. That could happen and bring great features to D. There is a significant difference between going down a path to see what you can find on the other end and turning the path into a goal, a priori.
Re: assume, assert, enforce, @safe
On Tuesday, 5 August 2014 at 09:42:26 UTC, Ola Fosheim Grøstad wrote: On Monday, 4 August 2014 at 00:59:10 UTC, Andrei Alexandrescu wrote: For my money, consider Walter's response: I feel a bit confused about the mixture between compiler and optimizer. While I agree the compiler does the optimization and the two are intrinsically linked, the languages (or the instructions) for them seem to me to belong to quite different paradigms: - compiler language is imperative programming - optimizer language is declarative programming It is wise to mix them to such degree as to no longer distinguish them? For me, assume and the like shall rather go with the annotations.
Re: assume, assert, enforce, @safe
On Tuesday, 5 August 2014 at 10:00:55 UTC, eles wrote: It is wise to mix them to such degree as to no longer distinguish them? For me, assume and the like shall rather go with the annotations. That's one of the reasons I think it is not new territory, since letting assert have side effects basically sounds like constraints programming/logic programming. I do think that constraints programming has a place in support for generic programming and other things that can be known to evaluate at compile time. So I think imperative programming languages are going to become hybrids over time. Also, if you think about the new field program synthesis, where you specify the constraints to generate/fill out boiler code in an imperative program, then the distinction becomes blurry. Rather than saying sort(x) you just specify that the outcome should be sorted in the post condition, but don't care why it ended up that way. So the compiler will automatically add sort(x) if needed. Sounds like a powerful way to get rid of boring programming parts. Another point, when you think about it, Program Verification and Optimization are conceptually closely related. S = specification // asserts is a weak version of this P = program E = executable ProgramVerification: Prove( S(x)==P(x) for all x ) Optimization Invariant: Prove( P(x)==E(x) for all x )
Re: assume, assert, enforce, @safe
On Monday, 4 August 2014 at 00:59:10 UTC, Andrei Alexandrescu wrote: I can totally relate to people who hold a conviction strong enough to have difficulty acknowledging a contrary belief as even remotely reasonable Yes, it's difficult to acknowledge a belief, reason for which wasn't provided, but instead we have nothing to add reply was given.
Re: assume, assert, enforce, @safe
On Tuesday, 5 August 2014 at 09:42:26 UTC, Ola Fosheim Grøstad wrote: But I don't think this path is all that new… so I hope Walter, if he continues walking down this path, remains unrelenting and keeps walking past assert as assume until he finds truly new territory in the realm of formal methods. That could happen and bring great features to D. This! +1000! This is what I've been feeling too: Walter is wrong - astonishingly wrong in fact - but in a very interesting direction that may have something very 'right' on the other side of it. I don't know what form it will take, but the example someone gave, of keeping track of when a range is sorted vs. not known to be sorted, to me gives a hint of where this may lead. I can't quite imagine that particular example playing out, but in general if the compiler keeps track of properties of things then it could start making algorithmic-level performance decisions that today we always have to make by hand. To me that's interesting.
Re: assume, assert, enforce, @safe
On Monday, 4 August 2014 at 00:59:10 UTC, Andrei Alexandrescu wrote: On 8/3/14, 11:55 AM, Kagamin wrote: On Saturday, 2 August 2014 at 17:36:46 UTC, David Bregman wrote: OK, I'm done. It's clear now that you're just being intellectually dishonest in order to win what amounts to a trivial argument. So much for professionalism. Haha, this time it's not as bad as it was in catch syntax discussion. I even thought then they are blackmailed or something like that. It's really only this kind of stuff that has Walter and myself worried. We understand spirits can get heated during a debate but the problem with such comebacks that really hold no punches is they instantly degrade the level of conversation, invite answers in kind, and are very difficult to respond to in meaningful ways. From what I can tell after many years of having at this, there's a sort of a heat death of debate in which questions are asked in a definitive, magisterial manner (bearing an odd implied binding social contract), and any response except the desired one is instantly dismissed as simply stupid, intellectually dishonest, or, as it were, coming under duress. I can totally relate to people who hold a conviction strong enough to have difficulty acknowledging a contrary belief as even remotely reasonable, as I've fallen for that many times and I certainly will in the future. Improving awareness of it only improves the standing of debate for everyone involved. For my money, consider Walter's response: What I see is Microsoft attempting to bring D's assert semantics into C++. :) As I've mentioned before, there is inexorable pressure for this to happen, and it will happen. I find it to the point, clear, and funny. Expanded it would go like I see more similarities than differences, and a definite convergence dictated by market pressure. I find it highly inappropriate to qualify that response as intellectually dishonest even after discounting for a variety of factors, and an apology would be in order. It's easy to get a very different impression from his post: I don't want to counter your arguments, so I just pick a random snippet from your post and make a funny mostly irrelevant comment, while ignoring everything else you wrote. Now, I don't believe that this was Walter's intention, but in the end it had the same effect :-( This is very bad, because I feel this discussion is important, so it matters for both sides to understand where the others are coming from. We can't achieve this by evading questions and discussion. And it wasn't just this one post; if you look at the discussion, there are entire sub-threads where people were obviously just talking past each other. But for me it's not easy to see _why_ they were doing it, i.e. what exactly the misunderstanding is.
Re: assume, assert, enforce, @safe
On Monday, 4 August 2014 at 00:59:10 UTC, Andrei Alexandrescu wrote: I find it to the point, clear, and funny. Expanded it would go like I see more similarities than differences, and a definite convergence dictated by market pressure. I find this to be a non-sequitur. Firstly, making a joke to avoid answering a direct question is hardly what I'd call to the point, regardless of how funny it may be. Secondly, even if I interpreted it as you did, it still misses the point. The discussion was about strict logical semantic equivalence of two concepts, assert and assume. How can I see more similarities than differences, and a definite convergence dictated by market pressure be a response to a black and white question about semantic equivalence? I find it highly inappropriate to qualify that response as intellectually dishonest even after discounting for a variety of factors, and an apology would be in order. Sure, that post alone isn't sufficient, but Walter argued much of the discussion in an unfair manner: dismissive one liners, fallacious arguments, strawman, even straight up begging the question. We are talking about several dozens of posts here. There was more than enough time spent to converge on agreement, if both sides intended to do so. Anyways I know this is all completely pointless to say, no one is going to believe it for one second because it just sounds like poor sportsmanship. For anyone who actually cares, you just need to read the threads and judge for yourself. From where I stand though, no apology is required.
Re: assume, assert, enforce, @safe
On Sunday, 3 August 2014 at 02:27:16 UTC, Jonathan M Davis wrote: On Saturday, 2 August 2014 at 09:46:57 UTC, Marc Schütz wrote: On Friday, 1 August 2014 at 21:50:59 UTC, Jonathan M Davis wrote: And why is that a problem? By definition, if an assertion fails, your code is in an invalid state, Only in an ideal world. In practice, the condition in the assertion could itself be incorrect. It could be a leftover after a refactoring, for instance. Then it's a bug, and bugs make programs do wrong and invalid things. I certainly don't see any reason to not optimize based on assertions just in case someone screwed up their assertion any more than I see a reason to avoid optimizing based on something that's wrong in normal code. Yes, it's a bug. The purpose of asserts is to detect these kinds of bugs, not to make it harder to detect them, and their effects worse.
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 16:04:21 UTC, Daniel Murphy wrote: Johannes Pfau wrote in message news:lrgar7$1vrr$1...@digitalmars.com... Do you know if linkers actually guarantee that behaviour? AFAICS dmd doesn't do anything special, it always emits weak symbols and just calls gcc to link. The linker usually uses the first symbol it sees, but I have not seen any guarantees for that. Yes, they do. Or at least, it's the classic linker behaviour and I expect they all implement it. It's relied upon for nofloat and a few other things. It's one of the reasons linkers are hard to parallelize. Though your linker specification is not the same as Johannes said. Also what happens if your main application doesn't use the template, but two libraries use the same template. Then which instances are actually used? I'd guess those from the 'first' library? Well, the first one that it encounters after getting the undefined reference. That's just how ld ended up working, and it's known to be pretty stupid in comparison with other linkers. And it's used rather stupidly, e.g. gcc just repeats libs several times to ensure ld sees all symbols it needs. eg module application { undef x ... } lib1: module a { undef tmpl def a } module tmpl { def tmpl } lib2: module x { undef tmpl def x } module tmpl { def tmpl } Here nothing that the application references will cause the tmpl in lib1 to get pulled in, but when it processes lib2 it will pull in x, and then tmpl. lib2: module x { undef tmpl def x } phobos: module tmpl { def tmpl } Then tmpl is picked from phobos instead of your code. Template emission optimization is a simple tool: if you realistically link against a module, which already has an instantiated template, template emission can be skipped and the linker will reasonably link whatever it finds.
Re: assume, assert, enforce, @safe
On Saturday, 2 August 2014 at 17:36:46 UTC, David Bregman wrote: OK, I'm done. It's clear now that you're just being intellectually dishonest in order to win what amounts to a trivial argument. So much for professionalism. Haha, this time it's not as bad as it was in catch syntax discussion. I even thought then they are blackmailed or something like that.
Re: assume, assert, enforce, @safe
On 8/3/14, 11:55 AM, Kagamin wrote: On Saturday, 2 August 2014 at 17:36:46 UTC, David Bregman wrote: OK, I'm done. It's clear now that you're just being intellectually dishonest in order to win what amounts to a trivial argument. So much for professionalism. Haha, this time it's not as bad as it was in catch syntax discussion. I even thought then they are blackmailed or something like that. It's really only this kind of stuff that has Walter and myself worried. We understand spirits can get heated during a debate but the problem with such comebacks that really hold no punches is they instantly degrade the level of conversation, invite answers in kind, and are very difficult to respond to in meaningful ways. From what I can tell after many years of having at this, there's a sort of a heat death of debate in which questions are asked in a definitive, magisterial manner (bearing an odd implied binding social contract), and any response except the desired one is instantly dismissed as simply stupid, intellectually dishonest, or, as it were, coming under duress. I can totally relate to people who hold a conviction strong enough to have difficulty acknowledging a contrary belief as even remotely reasonable, as I've fallen for that many times and I certainly will in the future. Improving awareness of it only improves the standing of debate for everyone involved. For my money, consider Walter's response: What I see is Microsoft attempting to bring D's assert semantics into C++. :) As I've mentioned before, there is inexorable pressure for this to happen, and it will happen. I find it to the point, clear, and funny. Expanded it would go like I see more similarities than differences, and a definite convergence dictated by market pressure. I find it highly inappropriate to qualify that response as intellectually dishonest even after discounting for a variety of factors, and an apology would be in order. Andrei
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 20:22:39 UTC, Tofu Ninja wrote: On Friday, 1 August 2014 at 20:16:29 UTC, eles wrote: Yes, but is the same for the C apps. There, you have no assertion in the release build, the release build is optimized (I imagine very few would use -O0 on it...), then the sefault happens. In c the assert is just a check, no assume, the Microsoft compiler even has its own __assume separate from assert. Because the assert is in the library, not in the language. The compiler can make only limited use of it.
Re: assume, assert, enforce, @safe
On Saturday, 2 August 2014 at 06:01:52 UTC, Timon Gehr wrote: On 08/02/2014 07:56 AM, eles wrote: On Friday, 1 August 2014 at 20:22:39 UTC, Tofu Ninja wrote: On Friday, 1 August 2014 at 20:16:29 UTC, eles wrote: It's part of the language standard. The compiler can make as much use of it as possible while still conforming to the spec. If you put it like that, then you could put *everything* into the library. Classes were once defined as a layer over C and they could be defined as standard. Still, the concept went into the compiler. What will the optimizer do if you don't link against the standard library?
Re: assume, assert, enforce, @safe
On 08/02/2014 07:56 AM, eles wrote: On Friday, 1 August 2014 at 20:22:39 UTC, Tofu Ninja wrote: On Friday, 1 August 2014 at 20:16:29 UTC, eles wrote: Yes, but is the same for the C apps. There, you have no assertion in the release build, the release build is optimized (I imagine very few would use -O0 on it...), then the sefault happens. In c the assert is just a check, no assume, the Microsoft compiler even has its own __assume separate from assert. Because the assert is in the library, not in the language. The compiler can make only limited use of it. It's part of the language standard. The compiler can make as much use of it as possible while still conforming to the spec.
Re: assume, assert, enforce, @safe
On 8/1/2014 5:57 PM, Dicebot wrote: `enforce` does have overload which allows to use pre-allocated exception instance. Or, alternatively, we may need a similar helper wich does `if (!condition) abort()` with no interaction with -release or optimizer. It still throws a *recoverable* exception, which requires the call stack to be populated with exception handling frames. Worse, it implies that program bugs are recoverable errors, when they are not. 1) one can always `enforce` with a pre-allocated Error, will druntime handle that as expected? I don't know, but I don't see why not. 2) There is certain class of applications where even programming bugs can (and must be) considered recoverable. Network services that don't yet have full scale high availability infrastructure (and thus can't afford downtime of restarting the app) are quite likely to only terminate connection fibers when programming bug is found - it does not affect serving any other connections. It may be fundamentally wrong but is is pragmatical working approach. These questions are not theoretical - we regularly have discussion about how contracts may / should be used at work with no clear understanding / agreement so far. I am interested in simple set of guidelines that won't turn writing every single function in a guessing game (does a contract fit here?) Putting it another way, consider the rules: 1. A newbie follows the rules because he's told to 2. A master follows the rules because he knows why the rules are good 3. A guru breaks the rules because he knows when the rules don't apply As to the substance of your question, I can't do it proper justice in a few lines. It's an important issue, and it is worthwhile to thoroughly understand it, especially for the kind of programming you do and the leading role you have in it. For that I recommend Object Oriented Software Construction by Meyers. http://www.amazon.com/Object-Oriented-Software-Construction-Book-CD-ROM/dp/0136291554/ Don't let the OOP title throw you off. It is a very thorough treatment of contract programming, and the rules and their rationales, but in a readable manner. You won't be sorry you read it. It's only $34 used, a bargain.
Re: assume, assert, enforce, @safe
On 08/02/2014 07:35 AM, Walter Bright wrote: On 8/1/2014 7:13 PM, David Bregman wrote: OK, I think I have an idea how to be more convincing (I wish I'd thought of this earlier): is this http://www.cplusplus.com/reference/cassert/assert/ the same as this? http://msdn.microsoft.com/en-us/library/1b3fsfxw.aspx can you see the difference now? What I see is Microsoft attempting to bring D's assert semantics into C++. :-) Note, regardless of the validity or invalidity of your point: You evaded the question. As I've mentioned before, there is inexorable pressure for this to happen, and it will happen. And when it does happen, criminals will rejoice, right?
Re: assume, assert, enforce, @safe
On 08/02/2014 08:04 AM, eles wrote: On Saturday, 2 August 2014 at 06:01:52 UTC, Timon Gehr wrote: On 08/02/2014 07:56 AM, eles wrote: On Friday, 1 August 2014 at 20:22:39 UTC, Tofu Ninja wrote: On Friday, 1 August 2014 at 20:16:29 UTC, eles wrote: It's part of the language standard. The compiler can make as much use of it as possible while still conforming to the spec. If you put it like that, then you could put *everything* into the library. Classes were once defined as a layer over C and they could be defined as standard. Still, the concept went into the compiler. What will the optimizer do if you don't link against the standard library? IIRC there are bits of the standard that allow the optimizer to assume that you will, but don't take my word for it.
Re: assume, assert, enforce, @safe
On 8/1/2014 11:08 PM, Timon Gehr wrote: You evaded the question. Those have been posted here before, and I responded in detail to them, more than once. I have nothing new to say about it.
Re: assume, assert, enforce, @safe
Jonathan M Davis wrote in message news:zbkvnbibbmcfwhjvm...@forum.dlang.org... IMO the correct solution is for the compiler to insert preconditions at the calling site, rather than the callee. If we had that, I'd actually start using in blocks. As it is, I think that they're useless except when inheritance is involved, and they're more verbose than just putting the assertions at the top of the function, so I don't bother with the in block. What do you think about https://github.com/D-Programming-Language/dmd/pull/3799 ? Basically, turn obviously invalid failing function calls into compile-time errors. IMO this pushes in-contracts well out of the useless area.
Re: assume, assert, enforce, @safe
Daniel Murphy: What do you think about https://github.com/D-Programming-Language/dmd/pull/3799 ? Basically, turn obviously invalid failing function calls into compile-time errors. IMO this pushes in-contracts well out of the useless area. I like compile-time tests, you can see it from several of my last posts, but: 1) It's better to be able to express general tests using CTFE, instead of covering a limited but growing list of cases. The general solution needs only half page of text to be explained in a next version of the TDPL, while your proposal will need a growing list of cases; 2) For reasons Walter has explained elsewhere, those tests need to be explicit, even syntactically-wise (and Walter has a strong opinion on this, so it's unlikely you will change his mind. And I agree with him on this). So far I've seen only one proposal to do this (the Enum Preconditions), and it too has some limits (caused by compilation units, that can be removed turning the Enum Preconditions into things handled like templates). Bye, bearophile
Re: assume, assert, enforce, @safe
On Saturday, 2 August 2014 at 06:44:48 UTC, Walter Bright wrote: On 8/1/2014 11:08 PM, Timon Gehr wrote: You evaded the question. Those have been posted here before, and I responded in detail to them, more than once. I have nothing new to say about it. Honestly, how can you be so comfortable with adding a feature that can be used to so easily cause undefined behavior
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 21:50:59 UTC, Jonathan M Davis wrote: On Friday, 1 August 2014 at 20:30:19 UTC, Daniel Gibson wrote: Am 01.08.2014 22:16, schrieb eles: On Friday, 1 August 2014 at 17:43:27 UTC, Timon Gehr wrote: On 08/01/2014 07:19 PM, Sebastiaan Koppe wrote: The debug and the release build may be subjected to different input and hence traverse different traces of abstract states. It is not valid to say that an assertion will never fail just because it hasn't failed yet. Yes, but is the same for the C apps. There, you have no assertion in the release build, the release build is optimized (I imagine very few would use -O0 on it...), then the sefault happens. But there checks are not optimized away because of assert. assert(x != NULL); if(x != NULL) { ... } in C the if check won't be optimized away in NDEBUG builds, in equivalent D code it would, because the assert would make the compiler assume that x will never be NULL at that point. And why is that a problem? By definition, if an assertion fails, your code is in an invalid state, Only in an ideal world. In practice, the condition in the assertion could itself be incorrect. It could be a leftover after a refactoring, for instance. and by compiling out assertions, you're basically assuming that they all pass, so you're code's already screwed if the assertion would have failed had it been compiled in. I don't see how having the compiler then use that assertion for optimizations really costs you anything. Worst case, it just makes already invalid code more invalid. You're screwed regardless if the assertion would have failed. And if it would have succeeded, then you just got an efficiency boost thanks to the assertion. Thinking about it, I'm actually wondering if I should use assertions _more_ so that the compiler might be able to do better optimizations in -release. The extra cost in non-release builds could be worth that extra boost in -release, and as far as correctness goes, it never hurts to have more assertions. - Jonathan M Davis
Re: assume, assert, enforce, @safe
On Saturday, 2 August 2014 at 06:01:30 UTC, Walter Bright wrote: As to the substance of your question, I can't do it proper justice in a few lines. It's an important issue, and it is worthwhile to thoroughly understand it, especially for the kind of programming you do and the leading role you have in it. For that I recommend Object Oriented Software Construction by Meyers. http://www.amazon.com/Object-Oriented-Software-Construction-Book-CD-ROM/dp/0136291554/ Don't let the OOP title throw you off. It is a very thorough treatment of contract programming, and the rules and their rationales, but in a readable manner. You won't be sorry you read it. It's only $34 used, a bargain. Thanks, will read!
Re: assume, assert, enforce, @safe
bearophile wrote in message news:hnbybyssdlwaomesc...@forum.dlang.org... I like compile-time tests, you can see it from several of my last posts, but: 1) It's better to be able to express general tests using CTFE, instead of covering a limited but growing list of cases. The general solution needs only half page of text to be explained in a next version of the TDPL, while your proposal will need a growing list of cases; This doesn't need a lot of text to explain either: when possible, the compiler will check preconditions at compile time 2) For reasons Walter has explained elsewhere, those tests need to be explicit, even syntactically-wise (and Walter has a strong opinion on this, so it's unlikely you will change his mind. And I agree with him on this). I'm really only interested in Walter's opinion when it's coming from Walter. I've responded to Walter's objections and we'll see where that goes. So far I've seen only one proposal to do this (the Enum Preconditions), and it too has some limits (caused by compilation units, that can be removed turning the Enum Preconditions into things handled like templates). I feel like you're confusing this pull request with another enhancement. The discussion should be about whether this exact feature is worthwhile, not if some other feature would solve some other problems. Do you really think the compiler opportunistically checking preconditions would be a bad thing for D?
Re: assume, assert, enforce, @safe
Daniel Murphy: This doesn't need a lot of text to explain either: when possible, the compiler will check preconditions at compile time What defines possible? A compiler switch that allows to define the amount of compile time? I feel like you're confusing this pull request with another enhancement. The discussion should be about whether this exact feature is worthwhile, not if some other feature would solve some other problems. The comparison of the two ideas is useful, because they try to solve the same problem. Do you really think the compiler opportunistically checking preconditions would be a bad thing for D? I think that adding an undefined, growing, compiled-dependent list of static checks that can cause unpredictable compilation times is not a good idea. A more general solution has some advantages: - It allows the user to choose what to run at compile-time and what at run-time; - You can defined _exactly_ what it does in a book, unlike the growing list; - Will not grow in features and implementation complexity as compilers improve (and I think it's sufficiently simple); - It's going to be mostly the same in all D compilers; - It allows to specify and run arbitrary tests in CTFE instead of a set of predefined by unknown simple tests. So you can use it for SafeIntegers literals, and many other future and unpredictable purposes; - It's explicitly visible in the code, because there is a syntax to denote such static testing parts in the code. Implementing a special-cased solution instead of a more general and principled solution could make the implementation of the better solution more unlikely :-) Bye, bearophile
Re: assume, assert, enforce, @safe
By the way, I will be absent for more than a week. My comments or answers in bug reports and threads will have to wait. Bye, bearophile
Re: assume, assert, enforce, @safe
bearophile wrote in message news:nadqefjfnjfzghope...@forum.dlang.org... What defines possible? A compiler switch that allows to define the amount of compile time? At the moment it's the criteria I listed in the bug report. Beyond this, it will be limited by what constfolding is capable of. What the exact limitations of constfolding are is an evolving part of the language. I feel like you're confusing this pull request with another enhancement. The discussion should be about whether this exact feature is worthwhile, not if some other feature would solve some other problems. The comparison of the two ideas is useful, because they try to solve the same problem. I don't think they do. If you force evaluation of preconditions at compile time, you force arguments (or properties of arguments) to be known at compile time. With best-effort checking, you simply get to promote run-time errors to compile-time. I think that adding an undefined, growing, compiled-dependent list of static checks that can cause unpredictable compilation times is not a good idea. A more general solution has some advantages: - It allows the user to choose what to run at compile-time and what at run-time; Again, these are orthagonal. I don't care if you define conditions that must be met at compile-time, these are about promoting run-time conditions to compile time. - You can defined _exactly_ what it does in a book, unlike the growing list; IMO this is only a mild problem. If they can't be caught at compile time, they will still be caught at run-time. - Will not grow in features and implementation complexity as compilers improve (and I think it's sufficiently simple); I don't understand this. You don't want static checking to improve over time? This is simply a type of static checking. - It's going to be mostly the same in all D compilers; Again, it's a promotion. It doesn't matter if every frontend doesn't implement it, lesser frontends will just mean you catch it at runtime. - It allows to specify and run arbitrary tests in CTFE instead of a set of predefined by unknown simple tests. So you can use it for SafeIntegers literals, and many other future and unpredictable purposes; - It's explicitly visible in the code, because there is a syntax to denote such static testing parts in the code. This has nothing to do with promoting run-time checks to compile-time. Implementing a special-cased solution instead of a more general and principled solution could make the implementation of the better solution more unlikely :-) Maybe. But I think you should be seeing this a stepping stone, not competition. eg all developers like it when the compiler points out guaranteed wrong code: ubyte x = 0xFFF; but many (including me) find it very annoying when the compiler makes you alter code that it thinks _might_ be wrong: ubyte x = y; // where y is a uint, that you know to be 256
Re: assume, assert, enforce, @safe
On Saturday, 2 August 2014 at 05:35:26 UTC, Walter Bright wrote: On 8/1/2014 7:13 PM, David Bregman wrote: OK, I think I have an idea how to be more convincing (I wish I'd thought of this earlier): is this http://www.cplusplus.com/reference/cassert/assert/ the same as this? http://msdn.microsoft.com/en-us/library/1b3fsfxw.aspx can you see the difference now? What I see is Microsoft attempting to bring D's assert semantics into C++. :-) OK, I'm done. It's clear now that you're just being intellectually dishonest in order to win what amounts to a trivial argument. So much for professionalism. As I've mentioned before, there is inexorable pressure for this to happen, and it will happen. What will happen is you will find out the hard way whether code breakage, undefined behavior and security holes are a worthy tradeoff for some trivial performance gains which likely can't even be measured except in toy benchmarks.
Re: assume, assert, enforce, @safe
On 8/1/2014 4:24 PM, bearophile wrote: H. S. Teoh: IMO the correct solution is for the compiler to insert preconditions at the calling site, I have seen this suggestion tens of times, but nothing has happened. (delegates make the management of contract blame more compex). There's a bugzilla issue on it, considerable discussion there, and consensus that it's the correct solution. But nobody has implemented it yet.
Re: assume, assert, enforce, @safe
On 8/1/2014 3:58 PM, Jonathan M Davis wrote: But even if I could think of a better name, I think that we're stuck with -debug at this point. One thing that people hate even more than breaking existing code is breaking their makefile (or equivalent). Makefiles typically are cutpasted from some other project, with the switches copied over without review. Worse, the switches sometimes come in from macros, and scripts are written to drive the makefiles, and it becomes a wholly unmaintainable tangle. Programmers have gotten a lot better about writing clear, maintainable code, but I can't say the same for the build process. Those are worse than ever. https://www.youtube.com/watch?v=CHgUN_95UAw
Re: assume, assert, enforce, @safe
Am Sat, 02 Aug 2014 12:34:54 -0700 schrieb Walter Bright newshou...@digitalmars.com: On 8/1/2014 3:58 PM, Jonathan M Davis wrote: But even if I could think of a better name, I think that we're stuck with -debug at this point. One thing that people hate even more than breaking existing code is breaking their makefile (or equivalent). Makefiles typically are cutpasted from some other project, with the switches copied over without review. Worse, the switches sometimes come in from macros, and scripts are written to drive the makefiles, and it becomes a wholly unmaintainable tangle. Programmers have gotten a lot better about writing clear, maintainable code, but I can't say the same for the build process. Those are worse than ever. https://www.youtube.com/watch?v=CHgUN_95UAw Wait - are you arguing that we can't change the name of a compiler flag because users would have to do a 'searchreplace' in their Makefiles, but breaking existing code (assert/assume) which will be very hard to track down for users is OK, cause 'that code was broken anyway'? We could also argue that Makefiles using '-debug' are broken anyway, cause the name debug doesn't match the behavior of the compiler and users will likely expect a different behavior.
Re: assume, assert, enforce, @safe
On Saturday, 2 August 2014 at 09:46:57 UTC, Marc Schütz wrote: On Friday, 1 August 2014 at 21:50:59 UTC, Jonathan M Davis wrote: And why is that a problem? By definition, if an assertion fails, your code is in an invalid state, Only in an ideal world. In practice, the condition in the assertion could itself be incorrect. It could be a leftover after a refactoring, for instance. Then it's a bug, and bugs make programs do wrong and invalid things. I certainly don't see any reason to not optimize based on assertions just in case someone screwed up their assertion any more than I see a reason to avoid optimizing based on something that's wrong in normal code. - Jonathan M Davis
Re: assume, assert, enforce, @safe
On Thursday, 31 July 2014 at 21:29:59 UTC, Sean Kelly wrote: On Thursday, 31 July 2014 at 21:11:17 UTC, Walter Bright wrote: On 7/31/2014 1:52 PM, Sean Kelly wrote: Could you expand on what you consider input? All state processed by the program that comes from outside the program. That would include: 1. user input 2. the file system 3. uninitialized memory 4. interprocess shared memory 5. anything received from system APIs, device drivers, and DLLs that are not part of the program 6. resource availability and exhaustion So effectively, any factor occurring at runtime. If I create a library, it is acceptable to validate function parameters using assert() because the user of that library knows what the library expects and should write their code accordingly. That's fair. Yes. It basically comes down to whether you would consider incorrect input to the function to be an outright program error that should _never_ occur (in which case, you use assertions) or whether you consider it reasonable for bad input to be given some of the time or unreasonable to require that the caller never give bad input (in which case, you use exceptions). Also, if efficiency is of great concern and it's possible for the caller to guarantee that the input is valid (which wouldn't be the case with something like files, because even if the input was validated, it could become invalid afterwords), then using assertions might be a better approach. On the other hand, if correctness is of greater concern, then it might make more sense to use exceptions, because then it makes sure that the programmer is never able to give bad input (though if it really makes more sense to treat that as program bug - e.g. giving an invalid index - then using Errors or assert(0) might make more sense, since they'd stay in but be immediately fatal). All in all, while some cases are very clear-cut as to whether assertions or exceptions should be used, many of other cases are highly subjective, at which point it generally comes down to whether bad input to the function should be considered a programming error or whether it makes more sense for the function to throw and allow the program to try and recover from the problem. - Jonathan M Davis
Re: assume, assert, enforce, @safe
On Thursday, 31 July 2014 at 19:31:51 UTC, Jonathan M Davis wrote: The whole type is templated, so the assertions will be compiled in based on whether the user's code is compiled with -released or not. Sounds tricky. Doesn't the compiler optimize template instantiation? If it finds an already compiled template instance somewhere, it will use it instead of generating new one.
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 06:53:17 UTC, Kagamin wrote: On Thursday, 31 July 2014 at 19:31:51 UTC, Jonathan M Davis wrote: The whole type is templated, so the assertions will be compiled in based on whether the user's code is compiled with -released or not. Sounds tricky. Doesn't the compiler optimize template instantiation? If it finds an already compiled template instance somewhere, it will use it instead of generating new one. Since all template instantiations must happen when you compile your program rather than in any libraries you're linking against, why would it matter? If you compile your program without -release, then all assertions in all templates that your program uses will be enabled. The only cases where it wouldn't be would be when a library that you're linking against uses that template internally, but then it's that library's code and not yours, so it's probably out of your hands to deal with assertion failures in it anyway. Any template reuse that occurred would be reuse within your program and thus use the same flags. The only way that I can think of that that could be screwed up is if you're compiling each module separately and use different flags for each, but then each module which was compiled with -release wouldn't have assertions and those that weren't would. The compiler would never try to share any template instantiations across them. They wouldn't even be involved with each other until the linker was run on them, so the compiler wouldn't even have the chance to try and share anything between them. - Jonathan M Davis
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 01:20:04 UTC, Walter Bright wrote: On 7/31/2014 3:07 PM, David Bregman wrote: On Thursday, 31 July 2014 at 18:58:11 UTC, Walter Bright wrote: On 7/31/2014 4:28 AM, David Bregman wrote: Sigh. Of course you can assume the condition after a runtime check has been inserted. You just showed that assert(x); assume(x); is semantically equivalent to assert(x); as long as the runtime check is not elided. (no -release) No. I showed that you cannot have an assert without the assume. That makes them equivalent that direction. That is only true if assert always generates a runtime check. i.e. it is not true for C/C++ assert (and so far, D assert) in release mode. For the other direction, adding in a runtime check for an assume is going to be expected of an implementation. No. It is expected that assume does /not/ have a runtime check. Assume is used to help the compiler optimize based on trusted facts, doing a runtime check could easily defeat the purpose of such micro optimizations. I'm rather astonished you'd take that position. It opens a huge door wide for undefined behavior, and no obvious way of verifying that the assume() is correct. It's not a position. I'm just giving you the definition of assume so you can understand the difference from assert. I'm confident that if D introduced such behavior, the very first comment would be I need it to insert a runtime check on demand. And, in fact, since the runtime check won't change the semantics if the assume is correct, they are equivalent. Right, only if the assume is correct. So they aren't equivalent if it isn't correct. Q.E.D. ? I'm not buying those uncheckable semantics as being workable and practical. I don't know what this means. Are you saying that you refuse to admit the difference between assert and assume because you exclude the possibility of the expression being false (buggy)? But you still want to assert to become assume in release mode? How will you handle the safety issue? I don't know yet. I would think the easiest way is to just not inject the assumption when inside @safe code, but I don't know anything about the compiler internals. Even for @system code, I'm on the fence about whether asserts should affect codegen in release, it doesn't seem like a clear tradeoff to make: safety vs some dubious optimization gains. So why do you want assume() with no checking whatsoever? Does anybody want that? Why are we even discussing such a misfeature? Ever since my first reply, I've only been trying to a) help you to understand the difference between the two, and b) to highlight the safety issue with assume (and the proposal for assert to become assume in release mode). Whether I want assume or not is beside the point. If you've interpreted my posts as some kind of lobbying for the addition of assume() to D, that is not the case. If you want my opinion on that, I think it would be a good thing to have assume and assert separate, for safety and clarity reasons. However the importance I would assign to adding assume() is low because it is only useful for very specific micro optimizations, and is always a tradeoff with its unsafety. In C, I typically use it only a couple times in a large code base, compared to assert which I use all over the place. Do we really want to go down the same road as C with undefined behavior? So you don't want assume()? Who does? I do want assume to some extent (see above), but it wasn't my point.
Re: assume, assert, enforce, @safe
On Thursday, 31 July 2014 at 21:29:59 UTC, Sean Kelly wrote: So effectively, any factor occurring at runtime. If I create a library, it is acceptable to validate function parameters using assert() because the user of that library knows what the library expects and should write their code accordingly. That's fair. He should, but what if he doesn't and the library is phobos or druntime (which are compiled in release mode)? BTW, druntime can't use enforce and doesn't verify its input.
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 04:12:40 UTC, Walter Bright wrote: On 7/31/2014 2:21 PM, Sean Kelly wrote: Thoughts? If a process detects a logic error, then that process is in an invalid state that is unanticipated and unknown to the developer. The only correct solution is to halt that process, and all processes that share memory with it. Anything less is based on faith and hope. If it is medical, flight control, or banking software, I submit that operating on faith and hope is not acceptable. The release version of software is compiled in release mode, asserts are removed and everything will continue to operate just fine, thankfully.
Re: assume, assert, enforce, @safe
On Thursday, 31 July 2014 at 22:21:46 UTC, Daniel Gibson wrote: Am 31.07.2014 23:59, schrieb Walter Bright: On 7/31/2014 10:40 AM, Daniel Gibson wrote: It's a major PITA to debug problems that only happen in release builds. Debugging optimized code was a well known problem even back in the 70's. Nobody has solved it, and nobody wants unoptimized code. Yeah, and because of this I'd like optimizations not to cause different behavior if at all possible to keep these kind of bugs as low as possible. And I agree with your stance on those fine-grained optimization switches from your other post. GCC currently has 191 flags the influence optimization[1] (+ a version that negates them for most), and I don't understand what most of them do, so it would be hard for me to decide which optimizations I want and which I don't want. However, what about an extra flag for unsafe optimizations? I'd like the compiler to do inlining, replacing int multiplications with powers of two with shifts and other safe optimizations that don't change the semantics of my program (see the examples in the post you quoted), but I *don't* want it to e.g. remove writes to memory that isn't read afterwards or make assumptions based on assertions (that are disabled in the current compile mode). And maybe a warning mode that tells me about dead/superfluous code that would be eliminated in an optimized build so I can check if that would break anything for me in that respect without trying to understand the asm output would be helpful. A compiler is a program that turns code in one programming language to equivalent machine code, according to a language specification. There are obviously many different equivalent machine code programs corresponding to any sufficiently complex higher-level program. Classifying them into optimized and unoptimized ones is rather arbitrary. The same goes for safe vs. unsafe optimizations. To achieve what you want, the compiler would have to ignore the actual language specification and use a different one that is tweaked according to your criteria. I don't think this is desirable. If the official language specification has parts that can lead to the errors you want to avoid, then it's not the compiler's fault, and therefore the compiler should not be changed to workaround it. Instead, deficiencies in the specification should be fixed there.
Re: assume, assert, enforce, @safe
Am Fri, 01 Aug 2014 07:01:48 + schrieb Jonathan M Davis jmdavisp...@gmx.com: Since all template instantiations must happen when you compile your program rather than in any libraries you're linking against, why would it matter? If you compile your program without That's not true, template instances emit weak symbols. If you link against a compiled library which also has instantiated the same templates this library provides the same weak symbols. Which symbols are actually used in the final executable is up to the linker and not standardized.
Re: assume, assert, enforce, @safe
Am 01.08.2014 12:03, schrieb Marc Schütz schue...@gmx.net: A compiler is a program that turns code in one programming language to equivalent machine code, according to a language specification. There are obviously many different equivalent machine code programs corresponding to any sufficiently complex higher-level program. Classifying them into optimized and unoptimized ones is rather arbitrary. The same goes for safe vs. unsafe optimizations. To achieve what you want, the compiler would have to ignore the actual language specification and use a different one that is tweaked according to your criteria. I don't think this is desirable. If the official language specification has parts that can lead to the errors you want to avoid, then it's not the compiler's fault, and therefore the compiler should not be changed to workaround it. Instead, deficiencies in the specification should be fixed there. I'd prefer language specifications *not* to include such parts. C wouldn't be any worse without the you can eliminate writes to code that's not read afterwards part, for example. So I wish D could resist adding such dangerous/unexpected things to the standard and only allow such optimizations in an unsafe optimization mode. Cheers, Daniel
Re: assume, assert, enforce, @safe
On Thursday, 31 July 2014 at 21:11:17 UTC, Walter Bright wrote: On 7/31/2014 1:52 PM, Sean Kelly wrote: Could you expand on what you consider input? All state processed by the program that comes from outside the program. That would include: 1. user input 2. the file system 3. uninitialized memory 4. interprocess shared memory 5. anything received from system APIs, device drivers, and DLLs that are not part of the program 6. resource availability and exhaustion For example, if a function has an in contract that validates input parameters, is the determination that a parameter is invalid a program bug or simply invalid input? An in contract failure is a program bug. Contracts are ASSERTIONS ABOUT THE CORRECTNESS OF THE PROGRAM LOGIC. They are not assertions about the program's input. If you consider this invalid input that should be checked by enforce(), can you explain why? This says it better than I can: http://en.wikipedia.org/wiki/Design_by_contract ok, can this be considered a good summary of using assertions/contracts for services where risk of entering undefined state is unacceptable? 1) never use `assert` or contracts in actual application code, use `enforce` instead 2) never use `enforce` in library code unless it does actual I/O, use contracts instead 3) always distribute both release and debug builds of libraries and always run tests in both debug and release mode Does it make sense? Your actual recommendation contradict each other but it is best what I was able to combine them into.
Re: assume, assert, enforce, @safe
Johannes Pfau wrote in message news:lrfqqt$1jem$1...@digitalmars.com... Which symbols are actually used in the final executable is up to the linker and not standardized. Isn't it? dmd will set it up so the definitions in the library will only get pulled in if undefined, and this will usually mean any definitions in the main object files will override the library ones. It should work this way on all platforms. Of course, definitions in different object files will be subject to comdat folding and that is not standardized.
Re: assume, assert, enforce, @safe
Daniel Gibson wrote in message news:lrg0k5$1nl1$1...@digitalmars.com... I'd prefer language specifications *not* to include such parts. C wouldn't be any worse without the you can eliminate writes to code that's not read afterwards part, for example. Of course it would, that's why that's in there!!! int *x = 0; // initialize just to be safe ... x = ...; You've just wasted a write. Your program is now slower than it needs to be. struct MyStruct s; mystruct_init(s); s-field = something; s-otherfield = somethingElse(); mystruct_init has to initialize all fields of s (to keep programmer suicide rates down) and yet you've just written over some of the values! The compiler can clearly see that you never read from field and otherfield between the first write and the second.
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 01:41:40 UTC, Daniel Gibson wrote: Yep, also a good point. (Actually it's 187 -f* options, the rest is -O* which can't be combined of course and some of them most probably imply many of the -f* switches, but it'll still be an unmanageable/untestable amount of possible configurations) Actually, it's much worse than that. ;) All of the -O switches in GCC have a set of -f switches that they enable or disable. What they DON'T tell you up front is that set of switches also enables other optimisations. [0] I encountered a situation a couple months ago where this actually mattered (i.e. runtime segfault) for one particular C file if you built it with levels above -O0, but enabling every single -f switch worked fine (still not sure why; solved by switching to Clang and it compiles and runs at all -O levels with no warnings). -Wyatt [0] https://gcc.gnu.org/wiki/FAQ#Is_-O1_.28-O2.2C-O3_or_-Os.29_equivalent_to_individual_-foptimization_options.3F
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 08:21:28 UTC, Kagamin wrote: On Thursday, 31 July 2014 at 21:29:59 UTC, Sean Kelly wrote: So effectively, any factor occurring at runtime. If I create a library, it is acceptable to validate function parameters using assert() because the user of that library knows what the library expects and should write their code accordingly. That's fair. He should, but what if he doesn't and the library is phobos or druntime (which are compiled in release mode)? BTW, druntime can't use enforce and doesn't verify its input. Druntime uses contracts and asserts in places. Which are of course removed because we ship only a release build. Once again, the worst naming for a compiler switch ever. What I really want is a way to ship release and non-release builds (ie. checked and unchecked) and have the proper one chosen at link time based on build flags. Basically toss the -defaultlib and -debuglib and replace it with -checkedlib and -uncheckedlib.
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 14:10:14 UTC, Sean Kelly wrote: Druntime uses contracts and asserts in places. Which are of course removed because we ship only a release build. Once again, the worst naming for a compiler switch ever. What I really want is a way to ship release and non-release builds (ie. checked and unchecked) and have the proper one chosen at link time based on build flags. Basically toss the -defaultlib and -debuglib and replace it with -checkedlib and -uncheckedlib. As a consequence of this thread I think I am going to change the way DMD is packaged on Arch Linux to at least use -debuglib :) Right we don't provide even that...
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 07:01:49 UTC, Jonathan M Davis wrote: Since all template instantiations must happen when you compile your program rather than in any libraries you're linking against, why would it matter? AFAIK, there's no distinction between a library and a program in D, only modules and packages. How would it differentiate them? And I didn't see any documented guarantee for template instantiation optimization behavior. The compiler would never try to share any template instantiations across them. They wouldn't even be involved with each other until the linker was run on them, so the compiler wouldn't even have the chance to try and share anything between them. Nobody cares about intermediate files, only what gets into the final executable matters, and that is decided by the linker, and it will remove redundant template instances.
Re: assume, assert, enforce, @safe
On 8/1/14, 12:40 AM, David Bregman wrote: It's not a position. I'm just giving you the definition of assume so you can understand the difference from assert. After reading your posts I still can't understand what your definition of assume is. Here's what I found: assert: is a runtime check of the condition. is a debugging/correctness checking feature. is used when the expression is believed true, but is not proven so. (if it was proven, then there is no purpose in asserting it with a redundant runtime check that is guaranteed to never activate.) assume: passes a hint to the optimizer to allow better code generation. is used when the expression is proven to be true (by the programmer, like @trusted). There are a few corrections needed for assert, i.e. is a runtime check of the condition in debug mode. The whole believed true but not proven so is... odd, seeing as assert takes expressions that are considered tautological within the design, and sometimes provable automatically (e.g. after inlining). Anyhow, if assume is to be taken at face value the its semantics has always been what Walter intended for assert. (Again proven to be true is an eyebrow raiser because when one thinks of proof of semantics of programs one thinks of state analysis or progress and preservation and such.) You may dislike what Walter wanted assert to be, but really this has been it from the beginning. Back in the day when I joined him I questioned the validity of making assert a keyword. He explained that he wanted it to be magic in the same way he discusses in this thread. Andrei
Re: assume, assert, enforce, @safe
Am Fri, 1 Aug 2014 23:20:02 +1000 schrieb Daniel Murphy yebbliesnos...@gmail.com: Johannes Pfau wrote in message news:lrfqqt$1jem$1...@digitalmars.com... Which symbols are actually used in the final executable is up to the linker and not standardized. Isn't it? dmd will set it up so the definitions in the library will only get pulled in if undefined, and this will usually mean any definitions in the main object files will override the library ones. It should work this way on all platforms. Do you know if linkers actually guarantee that behaviour? AFAICS dmd doesn't do anything special, it always emits weak symbols and just calls gcc to link. The linker usually uses the first symbol it sees, but I have not seen any guarantees for that. Also what happens if your main application doesn't use the template, but two libraries use the same template. Then which instances are actually used? I'd guess those from the 'first' library? Of course, definitions in different object files will be subject to comdat folding and that is not standardized.
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 14:26:35 UTC, Dicebot wrote: On Friday, 1 August 2014 at 14:10:14 UTC, Sean Kelly wrote: Druntime uses contracts and asserts in places. Which are of course removed because we ship only a release build. Once again, the worst naming for a compiler switch ever. What I really want is a way to ship release and non-release builds (ie. checked and unchecked) and have the proper one chosen at link time based on build flags. Basically toss the -defaultlib and -debuglib and replace it with -checkedlib and -uncheckedlib. As a consequence of this thread I think I am going to change the way DMD is packaged on Arch Linux to at least use -debuglib :) Right we don't provide even that... Wasn't it a common practice? See e.g. http://wxwidgets.blogspot.com/2012/08/how-to-use-294-wxmsw-binaries.html
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 15:23:03 UTC, Kagamin wrote: On Friday, 1 August 2014 at 14:26:35 UTC, Dicebot wrote: On Friday, 1 August 2014 at 14:10:14 UTC, Sean Kelly wrote: Druntime uses contracts and asserts in places. Which are of course removed because we ship only a release build. Once again, the worst naming for a compiler switch ever. What I really want is a way to ship release and non-release builds (ie. checked and unchecked) and have the proper one chosen at link time based on build flags. Basically toss the -defaultlib and -debuglib and replace it with -checkedlib and -uncheckedlib. As a consequence of this thread I think I am going to change the way DMD is packaged on Arch Linux to at least use -debuglib :) Right we don't provide even that... Wasn't it a common practice? See e.g. http://wxwidgets.blogspot.com/2012/08/how-to-use-294-wxmsw-binaries.html Right now I mostly mimic content of basic .zip distribution and it does not provide debug phobos builds.
Re: assume, assert, enforce, @safe
Am 01.08.2014 16:58, schrieb Andrei Alexandrescu: You may dislike what Walter wanted assert to be, but really this has been it from the beginning. Back in the day when I joined him I questioned the validity of making assert a keyword. He explained that he wanted it to be magic in the same way he discusses in this thread. I'm a bit surprised that back then your reaction was not well, that's a neat idea, but people must know about it, so let's make it explicit in the documentation. This seems to be the main problem here: people assumed that assert() behaves like in in C, where it's defined to be a noop when they're deactivated, which pretty much forbids using them for optimizations. So they wanted an assume() that gives the compiler hints about what it can assume a variable to be. Of course it would be desirable if in debug builds assume() would imply assert() so one can find out if those assumptions are not met while testing. With that (C style) mindset, one would not be surprised if the program behaves in an undefined way if an assume() condition is not met at runtime - but one is very much surprised about undefined behavior when a (deactivated!) assert() condition is not met. If assert() would have been documented or even advertised as can be used for optimizations by compilers in release mode from day one, this discussion wouldn't have started or at least would have been over very soon. Cheers, Daniel
Re: assume, assert, enforce, @safe
Johannes Pfau wrote in message news:lrgar7$1vrr$1...@digitalmars.com... Do you know if linkers actually guarantee that behaviour? AFAICS dmd doesn't do anything special, it always emits weak symbols and just calls gcc to link. The linker usually uses the first symbol it sees, but I have not seen any guarantees for that. Yes, they do. Or at least, it's the classic linker behaviour and I expect they all implement it. It's relied upon for nofloat and a few other things. It's one of the reasons linkers are hard to parallelize. dmd does split single d modules into multiple object modules when compiling with -lib, although I think that's fairly standard. Also what happens if your main application doesn't use the template, but two libraries use the same template. Then which instances are actually used? I'd guess those from the 'first' library? Well, the first one that it encounters after getting the undefined reference. eg module application { undef x ... } lib1: module a { undef tmpl def a } module tmpl { def tmpl } lib2: module x { undef tmpl def x } module tmpl { def tmpl } Here nothing that the application references will cause the tmpl in lib1 to get pulled in, but when it processes lib2 it will pull in x, and then tmpl.
Re: assume, assert, enforce, @safe
On 08/01/2014 06:36 AM, Walter Bright wrote: On 7/31/2014 6:37 PM, H. S. Teoh via Digitalmars-d wrote: But if we do that, then assume() starts to sound more and more like assert()... I see that my posts are starting to work :-) No, you are suffering from confirmation bias.
Re: assume, assert, enforce, @safe
On 08/01/2014 06:42 AM, Tofu Ninja wrote: On Friday, 1 August 2014 at 04:36:13 UTC, Walter Bright wrote: On 7/31/2014 6:37 PM, H. S. Teoh via Digitalmars-d wrote: But if we do that, then assume() starts to sound more and more like assert()... I see that my posts are starting to work :-) I don't think we are arguing for the addition of assume, we are arguing about the redefinition of assert to act like assume in -release. Yes, I think what he fails to appreciate is that he is arguing for the introduction of 'assume' in -release mode as a stealth operation by redefining the conventional meaning of 'assert', and that arguing against the introduction of 'assume' because it is redundant with the new 'assert' is not relevant.
Re: assume, assert, enforce, @safe
On 08/01/2014 04:58 PM, Andrei Alexandrescu wrote: assume: passes a hint to the optimizer to allow better code generation. is used when the expression is proven to be true (by the programmer, like @trusted). There are a few corrections needed for assert, i.e. is a runtime check of the condition in debug mode. The whole believed true but not proven so is... odd, seeing as assert takes expressions that are considered tautological within the design, Maybe _somebody_ does not know what the entire design actually is, or what all its implications are. and sometimes provable automatically (e.g. after inlining). ... Sometimes. Anyhow, if assume is to be taken at face value the its semantics has always been what Walter intended for assert. Even then, such a semantics is non-standard and almost nobody else knew. Why break 'assert' now, now that it actually behaves as I and many others expect (even some of those who argued for the (apparently, even inofficially) new and opposite design)? (Again proven to be true is an eyebrow raiser because when one thinks of proof of semantics of programs I think he was using a very relaxed notion of proof, and he exemplified that by drawing an analogy to @trusted. one thinks of state analysis or progress and preservation and such.) Progress and preservation are about soundness of the type system of the programming language, not program correctness. @safe may be seen to strive for progress and preservation conditional on it holding for @trusted functions. Your position has always been that @safe and @trusted represent a useful distinction, and this case is analogous (if different!).
Re: assume, assert, enforce, @safe
Daniel Gibson wrote in message news:lrgcei$211u$1...@digitalmars.com... I'm a bit surprised that back then your reaction was not well, that's a neat idea, but people must know about it, so let's make it explicit in the documentation. Haha, I think back then there were much more serious issues with D, like abundant segfaults and a development team of ~2. If assert() would have been documented or even advertised as can be used for optimizations by compilers in release mode from day one, this discussion wouldn't have started or at least would have been over very soon. I expect that even if it had been documented, people would have completely ignored it, and would still be arguing for the exact same positions.
Re: assume, assert, enforce, @safe
Sean Kelly wrote in message news:tngnltzwxprebpbcd...@forum.dlang.org... Druntime uses contracts and asserts in places. Which are of course removed because we ship only a release build. Once again, the worst naming for a compiler switch ever. What I really want is a way to ship release and non-release builds (ie. checked and unchecked) and have the proper one chosen at link time based on build flags. Basically toss the -defaultlib and -debuglib and replace it with -checkedlib and -uncheckedlib. While shipping a debug version of druntime would be useful, I think the real problem is that checking preconditions is disabled by the callee! If preconditions are violated, the error is in the caller, and checking should be enabled based on the application's flags.
Re: assume, assert, enforce, @safe
Am 01.08.2014 18:47, schrieb Daniel Murphy: Daniel Gibson wrote in message news:lrgcei$211u$1...@digitalmars.com... I'm a bit surprised that back then your reaction was not well, that's a neat idea, but people must know about it, so let's make it explicit in the documentation. Haha, I think back then there were much more serious issues with D, like abundant segfaults and a development team of ~2. It's not like adding two sentences describing this would take forever. If assert() would have been documented or even advertised as can be used for optimizations by compilers in release mode from day one, this discussion wouldn't have started or at least would have been over very soon. I expect that even if it had been documented, people would have completely ignored it, and would still be arguing for the exact same positions. They could be told look, it's written in the language spec (and has been for a long time), deal with it. Maybe there still would be /some/ discussion, but certainly not as much as we're currently seeing - and it could be ignored of a good reason. Cheers, Daniel
Re: assume, assert, enforce, @safe
If assertions are disabled in release builds, and you specifically instruct the compiler to build one, are you not assuming that the assertions will hold? Then what is wrong with extending those assumptions to the optimizer? Unless the assertions trigger in debug build, you will not end up with bugs in the release.
Re: assume, assert, enforce, @safe
On 8/1/14, 2:19 PM, Sebastiaan Koppe wrote: If assertions are disabled in release builds, and you specifically instruct the compiler to build one, are you not assuming that the assertions will hold? Then what is wrong with extending those assumptions to the optimizer? Unless the assertions trigger in debug build, you will not end up with bugs in the release. If assertions don't trigger in debug build then assertions don't trigger in release. That's false.
Re: assume, assert, enforce, @safe
On 8/1/14, 9:25 AM, Timon Gehr wrote: Even then, such a semantics is non-standard and almost nobody else knew. This notion of standard has been occasionally mentioned in this discussion. I agree that D's assert is different from traditional C and C++ assert, and I also agree that might surprise some, but I think the meaning of D's assert is well within the intent of the larger notion. Why break 'assert' now, now that it actually behaves as I and many others expect (even some of those who argued for the (apparently, even inofficially) new and opposite design)? I don't see any breakage of assert, more like realizing more of its latent potential. Clearly the documentation could be better, which is something we should focus on. I do agree there's stuff that some may find unexpected, such as: assert(x 42); if (x = 42) { // let me also handle this conservatively ... } else { // all good, proceed ... } The D optimizer might actually deem the entire then path unreachable in the future, and only compile in the else path. Some may find that surprising. For my money I never write code like this, and I consider it incorrect if I review it. You either assert something, or you check it dynamically. I don't remember having to ding anyone in a code review at Facebook for something like that in almost five years of tenure, and we use assert all over the place. Yesterday I changed a bunch of assert in hhvm (https://github.com/facebook/hhvm) with BSSERT having the following definition: #ifdef NDEBUG #define BSSERT(e) do { if (e) {} else __builtin_unreachable(); } while (0) #else #define BSSERT(e) do { assert(e); } while (0) #endif That's a 2MLOC project. I was hoping I'd measure a slight improvement based on the hints to gcc's optimizer. Tests passed but alas there was an 1.4% CPU time increase (which at our scale we consider a large performance regression); not sure what's causing it (it does sometimes happen that certain gcc optimization end up generating larger code which spills the I-Cache more often, something gcc's optimizer is not very good at controlling). Better, clearer language definition and documentation is the real cure for this particular matter. Sure enough we need to introduce any future optimizations with due care and diligence; that's a given. We also have a bunch of issues very important and very urgent to tend to, starting with finalizing the new release. Getting into this holier-than-thou contest, dinging people for using exponential casually, or discouraging them to express approval with the language leader is not only a waste of time, it's a net negative for everyone involved. It makes us look bad among ourselves and also to the larger community. Andrei
Re: assume, assert, enforce, @safe
On 08/01/2014 07:19 PM, Sebastiaan Koppe wrote: If assertions are disabled in release builds, and you specifically instruct the compiler to build one, are you not assuming that the assertions will hold? ... It would often be foolish to simply assume so, and disabling of the assertions can be motivated differently (and not all motivations are valid; _they don't need to be_.) Then what is wrong with extending those assumptions to the optimizer? ... To appreciate this better, simply imagine you are the guy who needs to track down the bug (which you don't reproduce locally, there can be many reasons for that) but who is not responsible for it. Unless the assertions trigger in debug build, you will not end up with bugs in the release. The debug and the release build may be subjected to different input and hence traverse different traces of abstract states. It is not valid to say that an assertion will never fail just because it hasn't failed yet.
Re: assume, assert, enforce, @safe
On 08/01/2014 07:39 PM, Andrei Alexandrescu wrote: ... I did what I though was right. Do what you like. I'm off.
Re: assume, assert, enforce, @safe
On Fri, Aug 01, 2014 at 06:58:16PM +0200, Daniel Gibson via Digitalmars-d wrote: Lines: 29 Am 01.08.2014 18:47, schrieb Daniel Murphy: Daniel Gibson wrote in message news:lrgcei$211u$1...@digitalmars.com... I'm a bit surprised that back then your reaction was not well, that's a neat idea, but people must know about it, so let's make it explicit in the documentation. Haha, I think back then there were much more serious issues with D, like abundant segfaults and a development team of ~2. It's not like adding two sentences describing this would take forever. Seriously, this thread has gone on way too long with no real work being done. So I decided to actually do something about it. https://github.com/D-Programming-Language/dlang.org/pull/624 There, now the deed is done. Now let the destruction proceed. :-P T -- Being able to learn is a great learning; being able to unlearn is a greater learning.
Re: assume, assert, enforce, @safe
On Fri, Aug 01, 2014 at 10:39:44AM -0700, Andrei Alexandrescu via Digitalmars-d wrote: On 8/1/14, 9:25 AM, Timon Gehr wrote: Even then, such a semantics is non-standard and almost nobody else knew. This notion of standard has been occasionally mentioned in this discussion. I agree that D's assert is different from traditional C and C++ assert, and I also agree that might surprise some, but I think the meaning of D's assert is well within the intent of the larger notion. Why break 'assert' now, now that it actually behaves as I and many others expect (even some of those who argued for the (apparently, even inofficially) new and opposite design)? I don't see any breakage of assert, more like realizing more of its latent potential. Clearly the documentation could be better, which is something we should focus on. And to help with said focus, here's where y'all may direct your energy: https://github.com/D-Programming-Language/dlang.org/pull/624 ;-) I do agree there's stuff that some may find unexpected, such as: assert(x 42); if (x = 42) { // let me also handle this conservatively ... } else { // all good, proceed ... } The D optimizer might actually deem the entire then path unreachable in the future, and only compile in the else path. Some may find that surprising. For my money I never write code like this, and I consider it incorrect if I review it. You either assert something, or you check it dynamically. Exactly. T -- Winners never quit, quitters never win. But those who never quit AND never win are idiots.
Re: assume, assert, enforce, @safe
On 8/1/2014 6:12 AM, Dicebot wrote: ok, can this be considered a good summary of using assertions/contracts for services where risk of entering undefined state is unacceptable? 1) never use `assert` or contracts in actual application code, use `enforce` instead 2) never use `enforce` in library code unless it does actual I/O, use contracts instead 3) always distribute both release and debug builds of libraries and always run tests in both debug and release mode Does it make sense? Your actual recommendation contradict each other but it is best what I was able to combine them into. What makes me hesitate about use of enforce() is its high runtime cost. It's not just the computation, but the call stack above it is affected by enforce() being throwable and allocating via the GC. Secondly, enforce() is about recoverable errors. Program bugs are simply NOT recoverable errors, and I cannot recommend using them for that purpose. I've argued for decades with people who insist that they can write code that recovers from unknown programming bugs.
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 19:47:35 UTC, Tofu Ninja wrote: Having your augment consistently dismissed by I see no *argument not augment :/
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 17:53:03 UTC, Timon Gehr wrote: On 08/01/2014 07:39 PM, Andrei Alexandrescu wrote: ... I did what I though was right. Do what you like. I'm off. I feel you, this whole thread is extremely frustrating. Having your augment consistently dismissed by I see no difference or That is misuse is frustrating to say the least.
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 17:19:09 UTC, Sebastiaan Koppe wrote: If assertions are disabled in release builds, and you specifically instruct the compiler to build one, are you not assuming that the assertions will hold? Then what is wrong with extending those assumptions to the optimizer? Unless the assertions trigger in debug build, you will not end up with bugs in the release. To support: it seems to me that assert() is nothing more than an assume() with a check. Why the check bothers you if the assumption is still true? Compiler just like to do overwork in debug builds, let's grant that pleasure to it.
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 17:43:27 UTC, Timon Gehr wrote: On 08/01/2014 07:19 PM, Sebastiaan Koppe wrote: The debug and the release build may be subjected to different input and hence traverse different traces of abstract states. It is not valid to say that an assertion will never fail just because it hasn't failed yet. Yes, but is the same for the C apps. There, you have no assertion in the release build, the release build is optimized (I imagine very few would use -O0 on it...), then the sefault happens. Good luck with the debugger and find the bug in the source code This is why debug builds exist, to reproduce problems and to investigate the bugs.
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 20:16:29 UTC, eles wrote: Yes, but is the same for the C apps. There, you have no assertion in the release build, the release build is optimized (I imagine very few would use -O0 on it...), then the sefault happens. In c the assert is just a check, no assume, the Microsoft compiler even has its own __assume separate from assert.
Re: assume, assert, enforce, @safe
Am 01.08.2014 22:16, schrieb eles: On Friday, 1 August 2014 at 17:43:27 UTC, Timon Gehr wrote: On 08/01/2014 07:19 PM, Sebastiaan Koppe wrote: The debug and the release build may be subjected to different input and hence traverse different traces of abstract states. It is not valid to say that an assertion will never fail just because it hasn't failed yet. Yes, but is the same for the C apps. There, you have no assertion in the release build, the release build is optimized (I imagine very few would use -O0 on it...), then the sefault happens. But there checks are not optimized away because of assert. assert(x != NULL); if(x != NULL) { ... } in C the if check won't be optimized away in NDEBUG builds, in equivalent D code it would, because the assert would make the compiler assume that x will never be NULL at that point. Cheers, Daniel
Re: assume, assert, enforce, @safe
On 8/1/2014 12:47 PM, Tofu Ninja wrote: Having your augment consistently dismissed by I see no difference or That is misuse is frustrating to say the least. I repeatedly gave detailed rationales for that.
Re: assume, assert, enforce, @safe
On 8/1/14, 5:16 PM, eles wrote: On Friday, 1 August 2014 at 17:43:27 UTC, Timon Gehr wrote: On 08/01/2014 07:19 PM, Sebastiaan Koppe wrote: The debug and the release build may be subjected to different input and hence traverse different traces of abstract states. It is not valid to say that an assertion will never fail just because it hasn't failed yet. Yes, but is the same for the C apps. There, you have no assertion in the release build, the release build is optimized (I imagine very few would use -O0 on it...), then the sefault happens. Good luck with the debugger and find the bug in the source code This is why debug builds exist, to reproduce problems and to investigate the bugs. The problem is then trying to copy everything C and C++ does and putting it in D...
Re: assume, assert, enforce, @safe
On Friday, 1 August 2014 at 14:10:14 UTC, Sean Kelly wrote: On Friday, 1 August 2014 at 08:21:28 UTC, Kagamin wrote: On Thursday, 31 July 2014 at 21:29:59 UTC, Sean Kelly wrote: So effectively, any factor occurring at runtime. If I create a library, it is acceptable to validate function parameters using assert() because the user of that library knows what the library expects and should write their code accordingly. That's fair. He should, but what if he doesn't and the library is phobos or druntime (which are compiled in release mode)? BTW, druntime can't use enforce and doesn't verify its input. Druntime uses contracts and asserts in places. Which are of course removed because we ship only a release build. Once again, the worst naming for a compiler switch ever. What I really want is a way to ship release and non-release builds (ie. checked and unchecked) and have the proper one chosen at link time based on build flags. Basically toss the -defaultlib and -debuglib and replace it with -checkedlib and -uncheckedlib. Well, to be fair, it's pretty standard practice to remove all assertions in release builds in other languages. If anything, leaving them in is highly abnormal. Sure, there are reasons to do it, but most folks don't. So, while I can see why you don't like the switch being called -release, it's behavior matches what most people would do for release builds. If anything, I think that -debug is the switch that's problematic, because people think that it's the opposite of release when it's completely unrelated (and useless for most code, because most people aren't going to be using debug blocks - especially if they don't understand the -debug switch). But we probably would be better off if none of the switches had names like -release or -debug so that folks actually had to figure out what they did before using them rather than simply assuming that one is for release builds and the other is for debug builds. - Jonathan M Davis
Re: assume, assert, enforce, @safe
On Fri, Aug 01, 2014 at 09:42:06PM +, Jonathan M Davis via Digitalmars-d wrote: On Friday, 1 August 2014 at 14:10:14 UTC, Sean Kelly wrote: [...] But we probably would be better off if none of the switches had names like -release or -debug so that folks actually had to figure out what they did before using them rather than simply assuming that one is for release builds and the other is for debug builds. [...] Great. So let's rename all of dmd's command-line options to -a, -b, -c, -d, -e, -f, ... (in arbitrary order). As long as we document it all, it will work just perfectly fine, right? After all, it *does* force users to *really* know what each option does. :-D T -- Gone Chopin. Bach in a minuet.