Re: Optlink Contribution
On Wednesday, 30 July 2014 at 19:50:35 UTC, Jonathan Marler wrote: I like the discussion. I do want to remind everyone that OPTLINK is very fast and switching to a different linker will likely result performance hit. Wouldn't it be easier to optimize a linker written in D than tinker with optlink?
Re: Redesign of gdcproject.org
On 28 July 2014 17:04, w0rp via Digitalmars-d wrote: > On Monday, 28 July 2014 at 10:27:02 UTC, Iain Buclaw wrote: >> >> Hi, >> >> dlang.org isn't the only site being re-implemented using vibe.d - GDC's >> homepage is now getting a UI update. >> >> https://github.com/D-Programming-GDC/gdcproject/pull/6 >> https://github.com/D-Programming-GDC/gdcproject/pull/9 >> >> >> Staging area for the new look is found here: >> >> http://staging.dgnu.org >> >> Regards >> Iain. > > > I like it. There's very little you can say that's wrong with it, and that's > a decent measure of success. The download page won't display decently on > very small screen sizes, but I doubt you'd have much reason to look at GDC > downloads unless you're on a machine which can run GDC. I've tweaked the downloads page. It's not as fancy, but it should now keep consistency. Regards Iain
Re: Case for std.experimental
On 29 July 2014 18:34, David Nadlinger via Digitalmars-d wrote: > the DMD release cycle takes the "rapid" out of "rapid iteration". Sad but true.
Re: checkedint call removal
On 7/30/2014 10:19 PM, bearophile wrote: Walter Bright: No, it will break code that already is broken. I have probably lost the grasp of this part of the discussion. But I don't see what's broken in using assert to verify that a pointer is not null. Do you think that pointer comes from "outside"? Daniel wants his code to be in a valid state even if the assert is not true, i.e. he wants it to continue to operate as if the pointer might be null.
Re: checkedint call removal
On 7/30/2014 10:16 PM, bearophile wrote: Walter Bright: Show me a piece of code with different behavior. Start with the array bounds thing. People have already shown you code that behaves differently with assert and assume. I'd like to see what you are saying is different in a real example. But you have redefined "assert" to mean a mix of assume and assert. I haven't redefined anything. It's always been that way. It's used that way in C/C++ (see your Microsoft C++ link). So before me answering you have to switch back to use the common definition of assert(). I'm asking what your notion of what assert and assume are, and how that would affect the array bounds checking example.
Re: checkedint call removal
On Thursday, 31 July 2014 at 05:05:33 UTC, Walter Bright wrote: On 7/30/2014 8:09 PM, Tofu Ninja wrote: When is the appropriate time to use an assert? If an assert should not be used on input, then any thing that can't be statically known is considered an input and anything that is derived from an input is also an input... so when can we use an assert? The only things left it seems are things know at compile time and at that point what is the the point of having assert when we have static assert... Asserts are used to verify the logic of your code is correct: x = y + y; assert(x == 2 * y); If x and y are floats and y is nan then that assert will fail. That assert is implicitly verifying that the input y is not nan, that is a misuse of assert by your definition. Any assert made on a piece of data that is derived from inputs is verifying some aspect of that input, which is a misuse of assert according to the current definition. So I still state that according to current definitions, assert should only be used on things that are known at compile time. What is the use of that?
Re: checkedint call removal
On 7/30/2014 2:32 PM, Ary Borenszweig wrote: So if there's a logic in your program, in release mode it won't crash immediately but continue with undefined behaviour. That's right. I can't imagine any case where I would want this in my programs. Don't use -release, then.
Re: assume, assert, enforce, @safe
On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote: 2. The compiler can make use of assert expressions to improve optimization, even in -release mode. For the domain I'm currently working in - a very large codebase (> 1 MLOC, C/C++) for an application program, I have to echo what others said, and say I could not use such a feature. I think I can add a reason (though what's been said about the 'fuzzy middle' between assertions and input validation, certainly rings true for me too). If my asserts worked this way I would have to stop using them and build my own. The reason is that, while I tend to assert only things that should be true, this codebase is not well factored and so: a) we tend to write a lot of assertions, and b) occasionally we learn something from them (i.e. an assertion fires, we go "huh", and our understanding of the codebase improves). The point is that a priori, we can only guess whether a particular assertion we're considering adding is really "this program is screwed if this condition is true". I don't lose sleep over this because it is safe to add our kind of assertions. But if adding assertions could affect the optimizer's reasoning, then it would NOT be safe to add them, and we'd have to back way off. I'd be comfortable using such assertions only for very low-level components. I can see the appeal of allowing the optimizer to do this, but I don't understand the idea of making that the default behavior. To me that's like array bounds-checking being off by default. And speaking of which, this seems like a useful example: Surely any program which oversteps the bounds of array, is incorrect? It must have made some logic error (be it forgetting to validate inputs, or some internal reasoning that was erroneous). So we should put asserts on all our array accesses, asserting that they are within bounds! So... then the optimizer can optimize away all the bounds checks. Releae builds need no checks of any kind. Right? :) I'm not trying to be as facetious as that sounds, I'm saying that your position seems to me to lead logically to the conclusion that array bounds-checking should be off in release.
Re: checkedint call removal
Walter Bright: No, it will break code that already is broken. I have probably lost the grasp of this part of the discussion. But I don't see what's broken in using assert to verify that a pointer is not null. Do you think that pointer comes from "outside"? Bye, bearophile
Re: checkedint call removal
Walter Bright: Show me a piece of code with different behavior. Start with the array bounds thing. People have already shown you code that behaves differently with assert and assume. But you have redefined "assert" to mean a mix of assume and assert. So before me answering you have to switch back to use the common definition of assert(). Bye, bearophile
Re: checkedint call removal
On 7/30/2014 9:51 PM, bearophile wrote: Walter Bright: So we're back to assert and assume being the same thing. Ok. They aren't, and they shouldn't be, regardless the number of times you say they are. Show me a piece of code with different behavior. Start with the array bounds thing.
Re: checkedint call removal
On 7/30/2014 8:09 PM, Tofu Ninja wrote: When is the appropriate time to use an assert? If an assert should not be used on input, then any thing that can't be statically known is considered an input and anything that is derived from an input is also an input... so when can we use an assert? The only things left it seems are things know at compile time and at that point what is the the point of having assert when we have static assert... Asserts are used to verify the logic of your code is correct: x = y + y; assert(x == 2 * y);
Re: assume, assert, enforce, @safe
On Thursday, 31 July 2014 at 04:24:49 UTC, Andrei Alexandrescu wrote: There's this term "learned helplessness". You're a smart guy who can slice and dice things. -- Andrei This is one of those moments when I am not sure if you are trolling me yet again or being strangely serious. I am supposed to research and propose brand new approach to contract programming because I don't understand how existing one should work? And I am being told that by one of the authors of existing system? You are taking that "go try yourself" thing way out of proportion.
Re: checkedint call removal
On 7/30/2014 9:54 PM, bearophile wrote: That usage of assert is fine. D programs use it that way. (And you are going to break lot of D code if you will change the semantics of D assert). No, it will break code that already is broken.
Re: checkedint call removal
Walter Bright: So we're back to assert and assume being the same thing. Ok. They aren't, and they shouldn't be, regardless the number of times you say they are. Bye, bearophile
Re: checkedint call removal
Walter Bright: assert(x != NULL); if(x != NULL) { x->foo = 42; // ... } ... Your code is doomed to having problems using assert this way. That usage of assert is fine. D programs use it that way. (And you are going to break lot of D code if you will change the semantics of D assert). Bye, bearophile
Re: checkedint call removal
Walter Bright: That's a good point. You could reasonably argue that such an optimization should not happen. I agree. Turning D assert() in a kind of a assert-assume hybrid will be a mistake. I think you are still missing the essential difference between assume and assert. How does assume improve the situation? I didn't ask for an assume in this thread. See what I am asking for: http://forum.dlang.org/thread/jrxrmcmeksxwlyuit...@forum.dlang.org?page=22#post-kjqjompjdhmbmzyhbzbb:40forum.dlang.org The answer I've given to Andrei is generic, but I can give more details. Bye, bearophile
Re: Case for std.experimental
"Dicebot" Wrote in message: > What keeps bothering me is this: imagine something has not passed > vote for std.experimental inclusion. That means that some changes > will happen, one more voting and it will eventually get there one > release later. > > And if has passed the vote, effectively the same stuff happens - > changes are done, staging period prolonged and we get to the very > same point. Only difference is that earlier versions of the > module don't get wider user exposure. > > Now that I see several comments here seeking for certain > stability even in std.experimental and can understand why later > exposure can be a good thing. That, however, makes me even more > convinced that "experimental" is a terrible name for that package > and we are using it purely as staging are instead. > std.purgatory
Re: assume, assert, enforce, @safe
On 7/30/14, 9:01 PM, Dicebot wrote: On Thursday, 31 July 2014 at 03:52:55 UTC, Andrei Alexandrescu wrote: It would be awesome if you (a) documented formally the current behavior and (b) submit bug reports wherever you find egregious faults in it. -- Andrei It is documented at http://dlang.org/contracts.html As for bug reports - how can I file those if I have no clue how system is supposed to be used? I don't think it is necessarily bad or buggy, just can't fin the way to make good use of it. Or do you expect "please teach me use contracts" bug report? :) There's this term "learned helplessness". You're a smart guy who can slice and dice things. -- Andrei
Re: Case for std.experimental
"Dicebot" Wrote in message: > On Tuesday, 29 July 2014 at 17:35:34 UTC, Andrei Alexandrescu > wrote: >> I'd just want to have a simple litmus test that prevents >> std.experimental from becoming a dumping ground of unfinished >> work. Consider: >> >> "Folks, here's std.experimental.acme. I think it's usable and >> fairly stable but I'm sure I didn't think of all possible >> issues and use cases. Documentation could be also improved." >> >> vs >> >> "Folks, here's std.experimental.acme. The entire user-facing >> API is sure to change and it doesn't pass what some deem to be >> basic acceptance terms. Try it, but you can be sure you'll need >> to overhaul all use of it when it's done." > > What keeps bothering me is this: imagine something has not passed > vote for std.experimental inclusion. That means that some changes > will happen, one more voting and it will eventually get there one > release later. > > And if has passed the vote, effectively the same stuff happens - > changes are done, staging period prolonged and we get to the very > same point. Only difference is that earlier versions of the > module don't get wider user exposure. > > Now that I see several comments here seeking for certain > stability even in std.experimental and can understand why later > exposure can be a good thing. That, however, makes me even more > convinced that "experimental" is a terrible name for that package > and we are using it purely as staging are instead. > --
Re: assume, assert, enforce, @safe
On Thursday, 31 July 2014 at 03:52:55 UTC, Andrei Alexandrescu wrote: It would be awesome if you (a) documented formally the current behavior and (b) submit bug reports wherever you find egregious faults in it. -- Andrei It is documented at http://dlang.org/contracts.html As for bug reports - how can I file those if I have no clue how system is supposed to be used? I don't think it is necessarily bad or buggy, just can't fin the way to make good use of it. Or do you expect "please teach me use contracts" bug report? :)
Re: assume, assert, enforce, @safe
On 7/30/14, 6:15 PM, Dicebot wrote: On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote: I am not terribly good at writing formal legalese specifications for this. I welcome PR's to improve the specification along these lines, if you find any Aha! Gotcha! issues in it. Of course, implementation errors for this in DMD should be reported on bugzilla. What is missing is not formal specification but clear guidelines "how to use this system in production". Right now it is pretty clear that you have implemented something that non-zero amount of experienced D developers have no clue how to use without botching the application completely. This does indicate that something is wrong with the feature even you are perfectly right theoretically. Currently there is http://dlang.org/contracts.html but neither it nor any of referenced materials does explain to me: - how to distribute binary library packages in presence of contracts - how to organize your application to ensure that contracts can be removed in release builds - are those even applicable to majority of applications I am less concerned with just assert behavior because there are many ways to workaround it to get different semantics. But contract system... no clues. It would be awesome if you (a) documented formally the current behavior and (b) submit bug reports wherever you find egregious faults in it. -- Andrei
Re: checkedint call removal
On Thursday, 31 July 2014 at 02:53:11 UTC, Walter Bright wrote: Your code is doomed to having problems using assert this way. The behavior you desire here is easily handled by creating your own template to exhibit it. See the implementation of enforce() for how to do it. When is the appropriate time to use an assert? If an assert should not be used on input, then any thing that can't be statically known is considered an input and anything that is derived from an input is also an input... so when can we use an assert? The only things left it seems are things know at compile time and at that point what is the the point of having assert when we have static assert...
Re: checkedint call removal
On 7/30/2014 6:38 PM, Daniel Gibson wrote: I'm in favor of a "harmless" assert(). In C(++) I sometimes use things like assert(x != NULL); if(x != NULL) { x->foo = 42; // ... } I have that assertion to hopefully find bugs during development and fix them. However, no program is bug free and so it's totally possible that x *is* NULL in some circumstance in the wild (in a "release" mode binary), so I want to make sure it doesn't explode if that happens but handle the problem more gracefully. It would be rather unfortunate if the compiler removed that second check in release mode because the assertion made it assume that x can't be NULL. Your code is doomed to having problems using assert this way. The behavior you desire here is easily handled by creating your own template to exhibit it. See the implementation of enforce() for how to do it.
Re: assume, assert, enforce, @safe
On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote: 3. Use of assert to validate input is utterly wrong and will not be supported. Use such constructs at your own risk. When exactly is it 'ok' to use assert then? If asserts are not allowed to be used to verify inputs then by extension, they can not be used to verify any derivative of an input. So by that definition, asserts are only ok to use on any thing known at compile time... that makes them utterly useless
Re: discuss disqus
On Wednesday, 30 July 2014 at 17:23:19 UTC, Andrei Alexandrescu wrote: So why do you think disqus is bad? I've seen some rationale from others but quite honestly it doesn't seem very convincing. -- Andrei Convincing you is quite an achievement. I don't think I have managed to do this even once ;) I have several distinct concerns about it: 1) It is ugly and visually alien. iframe nature is too obvious because "it's not currently possible to apply custom CSS to the Disqus iFrame" (c) https://help.disqus.com/customer/portal/articles/545277-disqus-appearance-tweaks This looks especially bad on flat static pages like dlang.org documentation. 2) Quality of content. Either we don't require moderation and will inevitably get some confusing / misleading / wrong recommendations or do require it and it will be the same as with pull request - reviewer bottleneck. Former is more damaging than "do nothing", latter does not make any real difference. 3) Dog-fooding. It is completely out of the line with existing documentation and development ecosystem I'd like to see popularized among newcomers. We already have quick GitHub "improve this page" links - a lot of possibilities remain for integration with wiki.dlang.org and forum.dlang.org Adding disqus will harm those existing (and good) information sources for same reason why adding quick and dirty hack harm application long-term maintenance. And the fact that you don't own comment database makes it harder to later switch to own comment system once vibe.d based implementation is ready.
Re: checkedint call removal
On 07/31/14 02:12, Andrei Alexandrescu via Digitalmars-d wrote: > I think bounds checking is an intrinsic feature of the language, not > something easily configurable. The problem is with asserts that cause the runtime checks to be eliminated. An simple assert would be enough to bypass @safe. artur
Re: New Github Issues
On Tuesday, 29 July 2014 at 17:06:55 UTC, Brad Anderson wrote: Good start. The blocked ones are kind of long which is a slight problem because Github truncates them in the Pull Request list. Maybe rename them to "awaits decision" and "awaits dependency". I think "await" implies they are blocked fairly well. Yep, tweaked a bit to fit without truncation. I am slowly going through least recently updated pull requests and adding those labels.
Re: checkedint call removal
Am 31.07.2014 02:50, schrieb Tobias Müller: Walter Bright wrote: On 7/30/2014 3:53 PM, Artur Skawina via Digitalmars-d wrote: No, with the assert definition you're proposing, it won't. It would be allowed to optimize away the bounds check. And this is just one of many problems with the assert==assume approach. Please explain how assume would behave any differently. It wouldn't and that's the point. If you have (a more harmless) assert _and_ assume you can still use assert, which would then _not_ allow those optimization. Tobi I'm in favor of a "harmless" assert(). In C(++) I sometimes use things like assert(x != NULL); if(x != NULL) { x->foo = 42; // ... } I have that assertion to hopefully find bugs during development and fix them. However, no program is bug free and so it's totally possible that x *is* NULL in some circumstance in the wild (in a "release" mode binary), so I want to make sure it doesn't explode if that happens but handle the problem more gracefully. It would be rather unfortunate if the compiler removed that second check in release mode because the assertion made it assume that x can't be NULL. Cheers, Daniel
Re: checkedint call removal
On 7/30/2014 5:50 PM, Tobias Müller wrote: Walter Bright wrote: On 7/30/2014 3:53 PM, Artur Skawina via Digitalmars-d wrote: No, with the assert definition you're proposing, it won't. It would be allowed to optimize away the bounds check. And this is just one of many problems with the assert==assume approach. Please explain how assume would behave any differently. It wouldn't and that's the point. So we're back to assert and assume being the same thing. Ok.
Re: Case for std.experimental
On Wednesday, 30 July 2014 at 22:44:38 UTC, David Nadlinger wrote: Ok, I will keep those rules in mind for future reviews / voting even if I don't understand their merit :) My view on the purpose of std.experimental notwithstanding, maybe we should discuss the meaning of the _vote_: What about making the vote simply about whether the module is believed to be a) of enough importance to be in Phobos by the wider community, and b) close enough to the mark in terms of design and implementation that a solid result is reachable in the near future? (b) is a bit too vague. With something like std.logger full rewrite of API can be done in quite a small time being thus "reachable in the near future" :) Effectively it implies that Phobos reviewers "know better" when it comes to exposed API and this is something I disagree with (I am one of those reviewers after all and I won't trust myself). Voting is an opportunity to a future users to tell "this API looks so bad I'd better write one of my own than go with it". At the same time minor glitches and overall Phobos style compatibility has not been traditionally considered a voting blocker so far so it already partially works that way - going through normal PR review process is still expected.
Re: Getting the hash of any value easily?
Am 31.07.2014 03:07, schrieb Andrei Alexandrescu: A coworker asked about the idiomatic way to get the hash of a string in D, and somewhat surprisingly the best answer I could find is: "to get the hash of an lvalue x, call typeof(x).getHash(&x)." That's admittedly quite clunky and indirect. Is it worth it to simplify that by means of a template in object.di? Andrei I proposed something like the following in another thread and think it would be really useful (to implement toHash() amongst other things): hash_t createHash(T...)(T args) { // return a hash over all arguments } In that thread (I think it was "WAT: opCmp and opEquals woes") it was implied that currently the compiler generates a toHash() automagically by hashing all members (of a struct or class) - analogous to opEquals that just compares all members. I can't find any documentation on that behavior.. but if it indeed exists there must already be a sensible hash algorithm for multiple values of different types which could just be reused here. Of course hashing a single value is just a special case of this. Cheers, Daniel
Re: checkedint call removal
On 07/31/14 02:31, Walter Bright via Digitalmars-d wrote: > On 7/30/2014 3:53 PM, Artur Skawina via Digitalmars-d wrote: >> No, with the assert definition you're proposing, it won't. It would >> be allowed to optimize away the bounds check. And this is just one of >> many problems with the assert==assume approach. > > Please explain how assume would behave any differently. I'm not arguing for assume [1], just against allowing information derived from assert expressions being able leak and affect other parts of the program. That just can not work (sanely); it would cause more problems than C's undefined behavior abuse. Because the UB triggers are well defined - by the language - and relatively well known. Asserts are /user-defined/. One wouldn't be able to reason about code without considering every single assert expression that was evaluated before reaching the current expression/function. An incorrect or inexact assert() hidden away somewhere could silently affect unrelated code, disable important safety checks etc. artur [1] I don't think that introducing `assume` would make a significant difference at this point - there are many more important D issues needing attention... But it could be done, would need to be @system, and probably wouldn't require much work. In fact, it already exists in gdc-ese, kind of: static import gcc.attribute; enum inline = gcc.attribute.attribute("forceinline"); @inline void assume()(bool c) { import gcc.builtins; if (!c) __builtin_unreachable(); } bool plain_assert(int i) { assert(i<6); return i==9; } // => "cmpl $9, %edi; sete %al; ret" bool assume_instead_of_assert(int i) { assume(i<6); return i==9; } // => "xorl %eax, %eax; ret" `assume`, unlike `assert`, may affect codegen.
Re: assume, assert, enforce, @safe
On Wednesday, 30 July 2014 at 23:50:51 UTC, H. S. Teoh via Digitalmars-d wrote: But if you don't want to check ever to be removed, currently you have to write: if (!requiredCondition) assert(0); // compiler never removes this which IMO is relatively clear, and the use of assert(0) for forceful termination is consistent with existing practice in D code. Not helping. ``` import std.stdio; void foo() in { writeln("in contract"); } body { } void main() { foo(); } ``` Compile with -release and check the output.
Re: assume, assert, enforce, @safe
On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote: I am not terribly good at writing formal legalese specifications for this. I welcome PR's to improve the specification along these lines, if you find any Aha! Gotcha! issues in it. Of course, implementation errors for this in DMD should be reported on bugzilla. What is missing is not formal specification but clear guidelines "how to use this system in production". Right now it is pretty clear that you have implemented something that non-zero amount of experienced D developers have no clue how to use without botching the application completely. This does indicate that something is wrong with the feature even you are perfectly right theoretically. Currently there is http://dlang.org/contracts.html but neither it nor any of referenced materials does explain to me: - how to distribute binary library packages in presence of contracts - how to organize your application to ensure that contracts can be removed in release builds - are those even applicable to majority of applications I am less concerned with just assert behavior because there are many ways to workaround it to get different semantics. But contract system... no clues.
Getting the hash of any value easily?
A coworker asked about the idiomatic way to get the hash of a string in D, and somewhat surprisingly the best answer I could find is: "to get the hash of an lvalue x, call typeof(x).getHash(&x)." That's admittedly quite clunky and indirect. Is it worth it to simplify that by means of a template in object.di? Andrei
Re: checkedint call removal
Walter Bright wrote: > On 7/30/2014 3:53 PM, Artur Skawina via Digitalmars-d wrote: >> No, with the assert definition you're proposing, it won't. It would >> be allowed to optimize away the bounds check. And this is just one of >> many problems with the assert==assume approach. > > Please explain how assume would behave any differently. It wouldn't and that's the point. If you have (a more harmless) assert _and_ assume you can still use assert, which would then _not_ allow those optimization. Tobi
Re: assume, assert, enforce, @safe
On 7/30/14, 5:29 PM, Andrei Alexandrescu wrote: On 7/30/14, 4:51 PM, Tobias Müller wrote: With relatively 'dumb' compilers, this is not a big problem, but optimizers are more and more clever and will take profit of such assumptions if they can. That's true, and it seems like a growing trend. Relevant threads: https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/9S5jNRW-5wY http://www.spinics.net/lists/gcchelp/msg41714.html Recent versions of gcc and clang have become increasingly aggressive about optimizing code by taking advantage of making undefined behavior _really_ undefined. There's been a couple of posts in the news recently that I can't find at the moment. I think I found it: http://www.redfelineninja.org.uk/daniel/?p=307 Andreu
Re: checkedint call removal
On 7/30/2014 3:53 PM, Artur Skawina via Digitalmars-d wrote: No, with the assert definition you're proposing, it won't. It would be allowed to optimize away the bounds check. And this is just one of many problems with the assert==assume approach. Please explain how assume would behave any differently.
Re: checkedint call removal
On 7/30/2014 3:40 PM, bearophile wrote: Walter Bright: void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; } The compiler will insert array bounds checking for you. But if your "assert" is the same as an assume(), then the optimizer should remove bounds checks (otherwise it's a lousy implementation of assume()) and leave no tests whatsoever inside the function f. So now you now have a safe function that is unsafe. That's a good point. You could reasonably argue that such an optimization should not happen. I think you are still missing the essential difference between assume and assert. How does assume improve the situation?
Re: assume, assert, enforce, @safe
On 7/30/14, 4:51 PM, Tobias Müller wrote: With relatively 'dumb' compilers, this is not a big problem, but optimizers are more and more clever and will take profit of such assumptions if they can. That's true, and it seems like a growing trend. Relevant threads: https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/9S5jNRW-5wY http://www.spinics.net/lists/gcchelp/msg41714.html Recent versions of gcc and clang have become increasingly aggressive about optimizing code by taking advantage of making undefined behavior _really_ undefined. There's been a couple of posts in the news recently that I can't find at the moment. Andrei
Re: checkedint call removal
Andrei Alexandrescu wrote: > On 7/30/14, 7:55 AM, Tofu Ninja wrote: >> On Wednesday, 30 July 2014 at 14:51:34 UTC, Andrei Alexandrescu wrote: >>> Also, it's unclear to me what the optimizer would be supposed to do if >>> an assumption turns out to be false. >> >> Bad... bad... things... > > So then I see nothing that assume can do that assert can't. -- Andrei The point is that optimizations based on asserts can have a big impact because they are leaky. By having both, a dangerous assume and a mre harmless assert (that terminates in debug and does nothing in release), the programmer can use assert a lot without many consequences if there's an error. Only if optimizations are really necessary he can use assume, but he can use it with care. It's not that assert is not powerful enough. It too dangerous to be used frequently. Tobi
Re: checkedint call removal
On 7/30/14, 4:29 PM, Artur Skawina via Digitalmars-d wrote: On 07/31/14 01:14, Andrei Alexandrescu via Digitalmars-d wrote: On 7/30/14, 3:41 PM, David Nadlinger wrote: On Wednesday, 30 July 2014 at 22:30:59 UTC, Walter Bright wrote: On 7/30/2014 3:20 PM, Artur Skawina via Digitalmars-d wrote: void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; } The compiler will insert array bounds checking for you. Trying to understand what your position is: In release mode, but with bounds checking enabled, would the compiler a) be allowed to replace this with a RangeError or, say, ud2 or another halt()-type instruction? b) treat any call to f() as undefined behavior? I think that's a good example. My understanding (I know it wasn't me who was asked...): the presence of assert should not influence the introduction of bounds checks. But it would. Special casing just the built-in types would only avoid the problem for built-in types. User defined types that handle the bounds checks differently would still be affected (and @unsafe). I think bounds checking is an intrinsic feature of the language, not something easily configurable. -- Andrei
Re: assume, assert, enforce, @safe
On Wednesday, 30 July 2014 at 22:58:01 UTC, Andrei Alexandrescu wrote: On 7/30/14, 3:39 PM, Joseph Rushton Wakeling via Digitalmars-d wrote: On 31/07/14 00:01, Walter Bright via Digitalmars-d wrote: 7. using enforce() to check for program bugs is utterly wrong. enforce() is a library creation, the core language does not recognize it. A question on that. There are various places in Phobos where enforce() statements are used to validate function input or class constructor parameters. Yah, Phobos is a bit inconsistent about that. TDPL discusses the matter: if a library is deployed in separation from the program(s) it serves, it may as well handle arguments as "input". That's what e.g. the Windows API is doing - it consistently considers all function arguments "inputs", scrubs them, and returns error codes for all invalid inputs it detects. In contracts, the traditional libc/Unix interface does little checking, even a strlen(NULL) will segfault. Phobos is somewhere in the middle - sometimes it verifies arguments with enforce(), some other times it just uses assert(). Yeah, we're not entirely consistent with it. However, if it would definitely be a program bug for an argument to not pass a particular condition, then it should be an assertion, and if it's definitely likely to be program input (e.g. this is frequently the case with strings), then exceptions are the appropriate approach. It's the cases where it's not obviously program input that's more debatable. Forcing checks and throwing exceptions incurs overhead, but it can significantly reduce programming bugs, because it doesn't put the onus on the programmer to verify the arguments. Using assertions is more performant but can significantly increase the risk of bugs - particularly when the assertions will all be compiled out when Phobos is compiled into a library unless the function is templated. I know that Walter favors using assertions everywhere and then providing functions which do the checks so that the programmer can check and then throw if appropriate, but the check isn't forced. Personally, I much prefer being defensive and to default to checking the input and throwing on bad input but to provide a way to avoid the check if you've already validated the input and don't want the cost of the check. For instance, many of the functions in std.datetime throw (particularly constructors), because it's being defensive, but it's on my todo list to add functions to bypass some of the checks (e.g. a function which constructs the type without doing any checks in addition to having the normal constructors). Regardless, I think that using assertions as the go-to solution for validating function arguments is generally going to result in a lot more programming bugs. I'd much prefer to default to being safe but provide backdoors for speed when you need it (which is generally how D does things). But regardless of which approach you prefer, there are some cases where it's pretty clear whether an assertion or exception should be used, and there are other cases where it's highly debatable - primarily depending on whether you want to treat a function's arguments as user input or rely on the programmer to do all of the necessary validations first. - Jonathan M Davis
Re: assume, assert, enforce, @safe
Walter Bright wrote: > 2. The compiler can make use of assert expressions to improve > optimization, even in -release mode. I can see the benefits of that, but I consider it very dangerous. It similar to undefined behavior in C/C++. There the 'assume/assert' is implicit not explicit, but it's still the same effect. If the assume/assert is hidden somewhere in a function you basically introduce new traps for UB. Initially I was strong proponent of such optimizations: (a + a)/2 can be optimized to just a for signed integers, that's nice, the classic example. This inserts an implicit assume(a < INT_MAX/2). My opinion suddenly changed when I realized that such assumptions (explicit or implicit) can also propagate up/backwards and leak into a bigger context. A wrong assumption can introduce bugs in seemingly unrelated parts of the program that would actually be correct on their own. With relatively 'dumb' compilers, this is not a big problem, but optimizers are more and more clever and will take profit of such assumptions if they can. Tobi
Re: checkedint call removal
Andrei Alexandrescu: Far as I can understand yes, there is distinction between "assert" and "assume". I don't find it as material as it would need to be to make "assume" a language feature. I didn't ask for an assume() in this thread. I have suggested/discussed/asked the inclusion in D of means to allow library writers to create a struct type like a SafeInt (that inside calls intrinsic functions like muls()) that manages the values range about as well as built-in types like int. I have asked this to allow optimizations typical of built-ins with library-defined types too (in particular to replace the call to muls with a regular faster multiplication). Bye, bearophile
Re: assume, assert, enforce, @safe
On Wed, Jul 30, 2014 at 08:05:35PM -0300, Ary Borenszweig via Digitalmars-d wrote: > On 7/30/14, 7:01 PM, Walter Bright wrote: > >I'd like to sum up my position and intent on all this. > > > >7. using enforce() to check for program bugs is utterly wrong. enforce() > >is a library creation, the core language does not recognize it. > > What do you suggest to use to check program bugs? This is what assert is designed for. But if you don't want to check ever to be removed, currently you have to write: if (!requiredCondition) assert(0); // compiler never removes this which IMO is relatively clear, and the use of assert(0) for forceful termination is consistent with existing practice in D code. T -- Старый друг лучше новых двух.
Re: checkedint call removal
On 7/30/14, 3:42 PM, Timon Gehr wrote: I've seen mostly agreement so far, but mostly not from you and Walter. That's probably natural and healthy: contributors are trigger-happy about adding new and clever features, and Walter and I are conservative for good balance. I propose we all tone it down a notch. It's good to discuss potential features; conversely it's not as good to transgress in a scoring-points contest where everybody tries to out-sarcasm the previous one and have the last word. Far as I can understand yes, there is distinction between "assert" and "assume". I don't find it as material as it would need to be to make "assume" a language feature. We can refine assert's definition to reach a good compromise advantageous for all, which would be the best outcome of this discussion. I don't meant this as definitive or even prescriptive; I've been plenty wrong before. But I think everyone is in agreement that good discussion is that that pushes the state of D forward. Let's all focus on that. Thanks, Andrei
Re: checkedint call removal
On 07/31/14 01:14, Andrei Alexandrescu via Digitalmars-d wrote: > On 7/30/14, 3:41 PM, David Nadlinger wrote: >> On Wednesday, 30 July 2014 at 22:30:59 UTC, Walter Bright wrote: >>> On 7/30/2014 3:20 PM, Artur Skawina via Digitalmars-d wrote: void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; } >>> >>> The compiler will insert array bounds checking for you. >> >> Trying to understand what your position is: In release mode, but with >> bounds checking enabled, would the compiler >>a) be allowed to replace this with a RangeError or, say, ud2 or >> another halt()-type instruction? >>b) treat any call to f() as undefined behavior? > > I think that's a good example. My understanding (I know it wasn't me who was > asked...): the presence of assert should not influence the introduction of > bounds checks. But it would. Special casing just the built-in types would only avoid the problem for built-in types. User defined types that handle the bounds checks differently would still be affected (and @unsafe). artur
Re: checkedint call removal
On 7/30/14, 3:41 PM, David Nadlinger wrote: On Wednesday, 30 July 2014 at 22:30:59 UTC, Walter Bright wrote: On 7/30/2014 3:20 PM, Artur Skawina via Digitalmars-d wrote: void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; } The compiler will insert array bounds checking for you. Trying to understand what your position is: In release mode, but with bounds checking enabled, would the compiler a) be allowed to replace this with a RangeError or, say, ud2 or another halt()-type instruction? b) treat any call to f() as undefined behavior? I think that's a good example. My understanding (I know it wasn't me who was asked...): the presence of assert should not influence the introduction of bounds checks. Andrei
Re: checkedint call removal
On 07/31/2014 12:55 AM, bearophile wrote: So now you now have a safe function that is unsafe. Even in debug builds. Bye, bearophile Why?
Re: assume, assert, enforce, @safe
On 7/30/14, 7:01 PM, Walter Bright wrote: I'd like to sum up my position and intent on all this. 7. using enforce() to check for program bugs is utterly wrong. enforce() is a library creation, the core language does not recognize it. What do you suggest to use to check program bugs?
Re: checkedint call removal
On 07/31/2014 12:39 AM, Walter Bright wrote: On 7/30/2014 2:30 PM, Timon Gehr wrote: Did you read the article? http://en.wikipedia.org/wiki/Assertion_%28computing%29#Disabling_assertions '[...] disabling assertion checking can mean that a program that would have aborted will continue to run. This is sometimes preferable.' This is not what DMD does in -release where assertions are 'disabled'. It follows a diametrally opposite philosophy. Not at all. The Wikipedia article does not argue that the program will continue in a valid state. Then you must also hold the belief that continuing to run in an invalid state is sometimes preferable?
Re: assume, assert, enforce, @safe
On 7/30/14, 3:39 PM, Joseph Rushton Wakeling via Digitalmars-d wrote: On 31/07/14 00:01, Walter Bright via Digitalmars-d wrote: 7. using enforce() to check for program bugs is utterly wrong. enforce() is a library creation, the core language does not recognize it. A question on that. There are various places in Phobos where enforce() statements are used to validate function input or class constructor parameters. Yah, Phobos is a bit inconsistent about that. TDPL discusses the matter: if a library is deployed in separation from the program(s) it serves, it may as well handle arguments as "input". That's what e.g. the Windows API is doing - it consistently considers all function arguments "inputs", scrubs them, and returns error codes for all invalid inputs it detects. In contracts, the traditional libc/Unix interface does little checking, even a strlen(NULL) will segfault. Phobos is somewhere in the middle - sometimes it verifies arguments with enforce(), some other times it just uses assert(). Andrei
Re: checkedint call removal
So now you now have a safe function that is unsafe. Even in debug builds. Bye, bearophile
Re: checkedint call removal
On 07/31/14 00:31, Walter Bright via Digitalmars-d wrote: > On 7/30/2014 3:20 PM, Artur Skawina via Digitalmars-d wrote: >> On 07/30/14 23:42, Walter Bright via Digitalmars-d wrote: >>> @safe's promise is one of memory safety, not a promise of program >>> correctness. >> >> void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; } > > The compiler will insert array bounds checking for you. No, with the assert definition you're proposing, it won't. It would be allowed to optimize away the bounds check. And this is just one of many problems with the assert==assume approach. artur
Re: checkedint call removal
On Wednesday, 30 July 2014 at 22:30:59 UTC, Walter Bright wrote: On 7/30/2014 3:20 PM, Artur Skawina via Digitalmars-d wrote: void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; } The compiler will insert array bounds checking for you. Trying to understand what your position is: In release mode, but with bounds checking enabled, would the compiler a) be allowed to replace this with a RangeError or, say, ud2 or another halt()-type instruction? b) treat any call to f() as undefined behavior? Cheers, David
Re: checkedint call removal
Walter Bright: void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; } The compiler will insert array bounds checking for you. But if your "assert" is the same as an assume(), then the optimizer should remove bounds checks (otherwise it's a lousy implementation of assume()) and leave no tests whatsoever inside the function f. So now you now have a safe function that is unsafe. I think you are still missing the essential difference between assume and assert. Bye, bearophile
Re: checkedint call removal
On 07/31/2014 12:17 AM, Andrei Alexandrescu wrote: On 7/30/14, 3:06 PM, Timon Gehr wrote: On 07/30/2014 10:55 PM, Andrei Alexandrescu wrote: On 7/30/14, 11:31 AM, Timon Gehr wrote: On 07/30/2014 07:56 PM, Andrei Alexandrescu wrote: ... case for "assume" to the language creators. I think there was no such case (yet), only an unsuccessful attempt to clear up a misunderstanding based on terminology. My perception is you were arguing for a very subtle distinction, My perception is different. Why is this distinction so subtle? Because it created a long thread in which there's little agreement. ... I've seen mostly agreement so far, but mostly not from you and Walter. one that would hardly deserve a language feature. ... version(assert) is a slight generalisation of such a language feature and it is already there. I already noted how the distinction can be implemented approximately in current D, in fact I think this was my first action in this thread. version(assert) assert(...); // assert without effects on -release code generation. Maybe this is a misundersanding. I don't see how. version(assert) does not mean "assert is considered here, else it's completely ignored". It means "assert will effect a run-time check". ... Indeed. // original source: void main(){ int x=1; version(assert) assert(x==0); // ... } // after some lowering without the -release switch: void main(){ int x=1; assert(x==0); // version statement active, // check will be performed (and fail) // ... } // after some lowering with the -release switch: void main(){ int x=1; // version statement inactive, no check will be performed, // optimizer never sees the assertion // ... } I.e. no wrong assumptions are passed down to the optimizer under any circumstances if the assertion is guarded with version(assert).
Re: Case for std.experimental
On Wednesday, 30 July 2014 at 18:00:59 UTC, Dicebot wrote: On Wednesday, 30 July 2014 at 17:44:06 UTC, Andrei Alexandrescu wrote: No! The point here is we don't offer the guarantees. We just don't want std.experimental to devolve into "anything goes" territory. If a library has known significant work ahead of it, we shouldn't put it in std.experimental. -- Andrei Ok, I will keep those rules in mind for future reviews / voting even if I don't understand their merit :) My view on the purpose of std.experimental notwithstanding, maybe we should discuss the meaning of the _vote_: What about making the vote simply about whether the module is believed to be a) of enough importance to be in Phobos by the wider community, and b) close enough to the mark in terms of design and implementation that a solid result is reachable in the near future? A positive vote would then be a mandate for the contributor and the Phobos committers/reviewers to work on ironing out the remaining kinks to make the package suitable for shipping with the standard library. In other words, the vote would effectively put the pull request for the addition on a level with all the others that contain no or only minor changes to the public API. Cheers, David
Re: assume, assert, enforce, @safe
On 31/07/14 00:01, Walter Bright via Digitalmars-d wrote: 3. Use of assert to validate input is utterly wrong and will not be supported. Use such constructs at your own risk. ... 6. enforce() is meant to check for input errors (environmental errors are considered input). 7. using enforce() to check for program bugs is utterly wrong. enforce() is a library creation, the core language does not recognize it. A question on that. There are various places in Phobos where enforce() statements are used to validate function input or class constructor parameters. For example, in std.random.LinearCongruentialEngine, we have: void seed(UIntType x0 = 1) @safe pure { static if (c == 0) { enforce(x0, "Invalid (zero) seed for " ~ LinearCongruentialEngine.stringof); } _x = modulus ? (x0 % modulus) : x0; popFront(); } while in RandomSample we have this method which is called inside the constructor: private void initialize(size_t howMany, size_t total) { _available = total; _toSelect = howMany; enforce(_toSelect <= _available, text("RandomSample: cannot sample ", _toSelect, " items when only ", _available, " are available")); static if (hasLength!Range) { enforce(_available <= _input.length, text("RandomSample: specified ", _available, " items as available when input contains only ", _input.length)); } } 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?
Re: checkedint call removal
On 7/30/2014 2:30 PM, Timon Gehr wrote: Did you read the article? http://en.wikipedia.org/wiki/Assertion_%28computing%29#Disabling_assertions '[...] disabling assertion checking can mean that a program that would have aborted will continue to run. This is sometimes preferable.' This is not what DMD does in -release where assertions are 'disabled'. It follows a diametrally opposite philosophy. Not at all. The Wikipedia article does not argue that the program will continue in a valid state.
Re: checkedint call removal
On 7/30/2014 3:20 PM, Artur Skawina via Digitalmars-d wrote: On 07/30/14 23:42, Walter Bright via Digitalmars-d wrote: On 7/30/2014 2:34 PM, Timon Gehr wrote: He understands that and notes that this contradicts the promise of @safe. No, it does not. @safe never promises that "all your asserts are correct". @safe's promise is one of memory safety, not a promise of program correctness. void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; } The compiler will insert array bounds checking for you.
Re: checkedint call removal
On 07/30/2014 11:39 PM, Walter Bright wrote: On 7/30/2014 2:21 PM, Timon Gehr wrote: Because the compiler does not seem know that 'assert' never returns, they shove in an __assume after it. The critical bit of misunderstanding here is the C standard *requires* that assert be implemented as a macro, There is no such misunderstanding. I know this. and that NDEBUG will totally disable it. The example implementation based on NDEBUG there does not provide this, rather, NDEBUG leaves the optimizer hint in. Microsoft needed to add a builtin feature so that the correct assert semantics can be reliably obtained by the optimizer. ... What makes the second implementation with both assert and __assume there 'correct'? Does the C standard specify undefined behaviour if the assert expression has side-effects? It's a mistake to infer from that that assert and assume are different. I don't need to rely on the MSVC++ compiler to see this. (But the __assume they have can be used to pass hints to the optimizer even if it does not happen in the context of an assertion, which I think was bearophile's point.)
Re: checkedint call removal
On 7/30/14, 3:06 PM, Timon Gehr wrote: On 07/30/2014 10:55 PM, Andrei Alexandrescu wrote: On 7/30/14, 11:31 AM, Timon Gehr wrote: On 07/30/2014 07:56 PM, Andrei Alexandrescu wrote: On 7/30/14, 9:31 AM, Timon Gehr wrote: 'lazy', which denotes pass by name instead of pass by need. It's not pass by name. ... How so? Is it about failure to allocate a closure? void fun(lazy int a) { ... } int x = 42; fun(x + 2); "x + 2" doesn't have a name. ... You might just have been fooled by the name of a concept. http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name Oh, yah. I'd forgotten. Mea culpa. Thanks! Consider this: after considerable effort you are failing to explain your case for "assume" to the language creators. I think there was no such case (yet), only an unsuccessful attempt to clear up a misunderstanding based on terminology. My perception is you were arguing for a very subtle distinction, My perception is different. Why is this distinction so subtle? Because it created a long thread in which there's little agreement. one that would hardly deserve a language feature. ... version(assert) is a slight generalisation of such a language feature and it is already there. I already noted how the distinction can be implemented approximately in current D, in fact I think this was my first action in this thread. version(assert) assert(...); // assert without effects on -release code generation. Maybe this is a misundersanding. version(assert) does not mean "assert is considered here, else it's completely ignored". It means "assert will effect a run-time check". Andrei
Re: checkedint call removal
On 07/30/14 23:42, Walter Bright via Digitalmars-d wrote: > On 7/30/2014 2:34 PM, Timon Gehr wrote: >> He understands that and notes that this contradicts the promise of @safe. > > No, it does not. @safe never promises that "all your asserts are correct". > > @safe's promise is one of memory safety, not a promise of program correctness. void f(ubyte[] a) @safe { assert(a.length>99); a[88] = a[77]; } artur
Re: checkedint call removal
On 07/30/2014 11:42 PM, Walter Bright wrote: On 7/30/2014 2:34 PM, Timon Gehr wrote: He understands that and notes that this contradicts the promise of @safe. No, it does not. @safe never promises that "all your asserts are correct". @safe's promise is one of memory safety, Indeed it is. not a promise of program correctness. There is some interplay. void foo(size_t i,int[] a)@safe{ assert(iPass -release and the bounds check may be removed from the line annotated 'boom' based on the elided but assumed to be valid assertion, and your memory safety guarantee is out the window. Unless one thinks incorrect programs shouldn't get any guarantees from @safe, this is a problem.
Re: assume, assert, enforce, @safe
On 7/30/14, 3:01 PM, Walter Bright wrote: 7. using enforce() to check for program bugs is utterly wrong. enforce() is a library creation, the core language does not recognize it. GAA!
Re: checkedint call removal
On 07/30/2014 10:55 PM, Andrei Alexandrescu wrote: On 7/30/14, 11:31 AM, Timon Gehr wrote: On 07/30/2014 07:56 PM, Andrei Alexandrescu wrote: On 7/30/14, 9:31 AM, Timon Gehr wrote: 'lazy', which denotes pass by name instead of pass by need. It's not pass by name. ... How so? Is it about failure to allocate a closure? void fun(lazy int a) { ... } int x = 42; fun(x + 2); "x + 2" doesn't have a name. ... You might just have been fooled by the name of a concept. http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name Consider this: after considerable effort you are failing to explain your case for "assume" to the language creators. I think there was no such case (yet), only an unsuccessful attempt to clear up a misunderstanding based on terminology. My perception is you were arguing for a very subtle distinction, My perception is different. Why is this distinction so subtle? one that would hardly deserve a language feature. ... version(assert) is a slight generalisation of such a language feature and it is already there. I already noted how the distinction can be implemented approximately in current D, in fact I think this was my first action in this thread. version(assert) assert(...); // assert without effects on -release code generation. This then runs into the 'funny naming' issue etc., but this would be going in circles.
assume, assert, enforce, @safe
I'd like to sum up my position and intent on all this. 1. I can discern no useful, practical difference between the notions of assume and assert. 2. The compiler can make use of assert expressions to improve optimization, even in -release mode. 3. Use of assert to validate input is utterly wrong and will not be supported. Use such constructs at your own risk. 4. An assert failure is a non-recoverable error. The compiler may assume that execution does not proceed after one is tripped. The language does allow attempts to shut a program down gracefully after one is tripped, but that must not be misconstrued as assuming that the program is in a valid state at that point. 5. assert(0); is equivalent to a halt, and the compiler won't remove it. 6. enforce() is meant to check for input errors (environmental errors are considered input). 7. using enforce() to check for program bugs is utterly wrong. enforce() is a library creation, the core language does not recognize it. 8. @safe is a guarantee of memory safety. It is not a guarantee that a program passes all its assert expressions. -release does not disable @safe. 9. -noboundscheck does disable @safe's array bounds checks, however, the compiler may assume that the array index is within bounds after use, even without the array bounds check. I am not terribly good at writing formal legalese specifications for this. I welcome PR's to improve the specification along these lines, if you find any Aha! Gotcha! issues in it. Of course, implementation errors for this in DMD should be reported on bugzilla.
Re: checkedint call removal
On 7/30/2014 2:34 PM, Timon Gehr wrote: He understands that and notes that this contradicts the promise of @safe. No, it does not. @safe never promises that "all your asserts are correct". @safe's promise is one of memory safety, not a promise of program correctness.
Re: checkedint call removal
On 7/30/2014 2:21 PM, Timon Gehr wrote: Because the compiler does not seem know that 'assert' never returns, they shove in an __assume after it. The critical bit of misunderstanding here is the C standard *requires* that assert be implemented as a macro, and that NDEBUG will totally disable it. Microsoft needed to add a builtin feature so that the correct assert semantics can be reliably obtained by the optimizer. It's a mistake to infer from that that assert and assume are different.
Re: checkedint call removal
On 07/30/2014 11:28 PM, Walter Bright wrote: On 7/30/2014 1:56 PM, David Bregman wrote: Can you please address the fact that assume is not @safe? How do you propose to preserve memory safety in release mode if you remove runtime checks for asserts but still assume the condition for codegen? D's @safe feature is not semantically tied to D's assert expressions. He understands that and notes that this contradicts the promise of @safe.
Re: checkedint call removal
On 7/30/14, 5:47 PM, Walter Bright wrote: On 7/30/2014 7:36 AM, Ary Borenszweig wrote: Now, if you compile in release mode, according to Walter, all the "asserts" are gone (which, as a side note, is something I don't like: in every case it should throw an AssertError). So the question is: can the compiler still replace that writeln call? Yes. So if there's a logic in your program, in release mode it won't crash immediately but continue with undefined behaviour. I can't imagine any case where I would want this in my programs. I think I would always use enforce and never assert.
Re: checkedint call removal
On 07/30/2014 11:15 PM, Walter Bright wrote: On 7/30/2014 1:45 PM, "Ola Fosheim Grøstad" " wrote: Can you please read the Hoare article form 1969? This is getting really annoying. Ironically, your wikipedia entry on Hoare references http://en.wikipedia.org/wiki/Assertion_(computing) which is exactly what D's assert does. Did you read the article? http://en.wikipedia.org/wiki/Assertion_%28computing%29#Disabling_assertions '[...] disabling assertion checking can mean that a program that would have aborted will continue to run. This is sometimes preferable.' This is not what DMD does in -release where assertions are 'disabled'. It follows a diametrally opposite philosophy.
Re: Redesign of gdcproject.org
On 30 July 2014 17:15, Iain Buclaw wrote: > On 30 July 2014 16:51, Iain Buclaw wrote: >> On 28 July 2014 19:08, w0rp via Digitalmars-d >> wrote: >>> On Monday, 28 July 2014 at 17:31:49 UTC, Sönke Ludwig wrote: Am 28.07.2014 18:04, schrieb w0rp: > > On Monday, 28 July 2014 at 10:27:02 UTC, Iain Buclaw wrote: >> >> Hi, >> >> dlang.org isn't the only site being re-implemented using vibe.d - >> GDC's homepage is now getting a UI update. >> >> https://github.com/D-Programming-GDC/gdcproject/pull/6 >> https://github.com/D-Programming-GDC/gdcproject/pull/9 >> >> >> Staging area for the new look is found here: >> >> http://staging.dgnu.org >> >> Regards >> Iain. > > > I like it. There's very little you can say that's wrong with it, and > that's a decent measure of success. The download page won't display > decently on very small screen sizes, but I doubt you'd have much reason > to look at GDC downloads unless you're on a machine which can run GDC. I > like that you have links to AUR for Arch Linux, packages.debian.org for > Debian, etc. That's something which should go into the dlang.org > downloads page too. > > I'll have to look at whatever filesystem monitors you have written, etc. > I'll need to add filesystem monitors for Markdown files eventually. DirectoryWatcher for Linux has just been implemented by Martin Nowak (Win32 has been available already): https://github.com/rejectedsoftware/vibe.d/pull/743 The corresponding API is vibe.core.file.watchDirectory(). >>> >>> >>> Awesome, I'll use that at some point, then. There's been a pretty good >>> history of things appearing in vibe.d just slightly after I want them. >> >> >> FYI: >> https://github.com/ibuclaw/gdcproject/commit/03607e0c834e1950fa2b9c697b2cd17e38547812 >> >> Though you might do a better job than me. ;-) > > > I seem to be getting a SEGV in vibe.d on my server, but can't > reproduce it locally. It's happening in the source changed by Martin > for libev support. > > My dev machine is 64bit, the server is 32bit. > > Hmm Looks like was down to my server set-up. I had been using gdc w/ 2.065 on my own machine, but gdc w/ 2.064 on the server. Rebuilt on 2.065 and all is functional now. Site is now able to rebuild pages in the background on the fly, no recompilation/restart necessary. :o) Regards
Re: checkedint call removal
On 7/30/2014 1:56 PM, David Bregman wrote: Can you please address the fact that assume is not @safe? How do you propose to preserve memory safety in release mode if you remove runtime checks for asserts but still assume the condition for codegen? D's @safe feature is not semantically tied to D's assert expressions.
Re: checkedint call removal
On 07/30/2014 10:39 PM, Walter Bright wrote: On 7/30/2014 2:12 AM, bearophile wrote: Info about assume in Microsoft C++: http://msdn.microsoft.com/en-us/library/1b3fsfxw.aspx Note that document shows how assert Some random ASSERT macro with custom behaviour. That article shows a few alternatives for an ASSERT macro, one of which is basically what D's assert expression does. The primitives used are ( (e) || assert(__FILE__, __LINE__)) and __assume(e); Because the compiler does not seem know that 'assert' never returns, they shove in an __assume after it. #define ASSERT(e)( ((e) || assert(__FILE__, __LINE__)), __assume(e)) This is an implementation detail. One can just as well do e.g.: #ifdef DEBUG # define ASSERT(e)( ((e) || assert(__FILE__, __LINE__) ) #else # define ASSERT(e) #endif #define ASSUME(e) __assume(e) and this and similar options avoid undefined behaviour in non-DEBUG mode caused on ASSERT, while still having the possibility of giving optimization hints explicitly in the form of ASSUME. In this case, the distinction is important even operationally, and it would be a sane alternative to the current approach. There is no a priori absolute single true way when discussing alternatives, and frankly, this should be obvious. is implemented using assume. I.e. they are the same thing. ... Yes, and writeln is obviously the same thing as a hello world program. Intriguingly, the __assume(0) behavior is even special cased like D's assert(0). ... It is not special cased at all. It is documented specially, because not everyone seems to be that deep into logic.
Re: checkedint call removal
On 7/30/2014 2:06 PM, "Ola Fosheim Grøstad" " wrote: Pretty clear, now huh? I'm curious if you can find an existing computer language that implements both assume and assert and draws some sort of semantic distinction between them. bearophile's Microsoft C++ example isn't one of them, as it is nothing more than a workaround for the C Standard requiring assert to be a macro.
Re: checkedint call removal
On 7/30/2014 1:45 PM, "Ola Fosheim Grøstad" " wrote: Can you please read the Hoare article form 1969? This is getting really annoying. Ironically, your wikipedia entry on Hoare references http://en.wikipedia.org/wiki/Assertion_(computing) which is exactly what D's assert does.
Re: checkedint call removal
On Wednesday, 30 July 2014 at 20:47:30 UTC, Walter Bright wrote: On 7/30/2014 7:36 AM, Ary Borenszweig wrote: Now, if you compile in release mode, according to Walter, all the "asserts" are gone (which, as a side note, is something I don't like: in every case it should throw an AssertError). So the question is: can the compiler still replace that writeln call? Yes. This on the other hand is a terrible, terrible misuse of assert. You need distinguish between what is assumed to hold and what is proved to hold to chain together pieces of proven programs. So what one function require (preconditions) you need to assert before calling the function. On the other hand, what the function asserts you can assume to hold after the call. So: assert(X) function call to precompiled library code assume(X) ...statements assert(Y) function return from precompiled library code assume(Y) Pretty clear, now huh?
Re: checkedint call removal
Ola Fosheim Grøstad: Here is a set of examples of annotated programs that have been formally proved correct for those interested: http://toccata.lri.fr/gallery/why3.en.html I have started to read those pages, it looks interesting. From one of the first links (Sudoku solver): valid values are 0..9. 0 denotes an empty cell predicate valid_values (g:grid) = forall i. is_index i -> 0 <= g[i] <= 9 So can't they represent that the value 0 is an empty cell in the code instead of comments? (I think this is possible in Ada language). It's a bit sad that D1 has removed the literate programming feature of D1. In Haskell it's used all the time. Bye, bearophile
Re: checkedint call removal
On 7/30/14, 11:31 AM, Timon Gehr wrote: On 07/30/2014 07:56 PM, Andrei Alexandrescu wrote: On 7/30/14, 9:31 AM, Timon Gehr wrote: 'lazy', which denotes pass by name instead of pass by need. It's not pass by name. ... How so? Is it about failure to allocate a closure? void fun(lazy int a) { ... } int x = 42; fun(x + 2); "x + 2" doesn't have a name. 'pure' which denies access to mutable static variables and IO. That's the consequence of functional purity as defined by D. Somewhat debatable, but unworthy of debate. Then don't mention it. Consider this: after considerable effort you are failing to explain your case for "assume" to the language creators. I think there was no such case (yet), only an unsuccessful attempt to clear up a misunderstanding based on terminology. My perception is you were arguing for a very subtle distinction, one that would hardly deserve a language feature. How do you think you'll fare with newcomers? ... Hopefully, awesomely. Much less preconceptions. May you have less snarky users than I do :o). Andrei
Re: checkedint call removal
On Wednesday, 30 July 2014 at 09:11:31 UTC, Walter Bright wrote: On 7/30/2014 12:54 AM, David Bregman wrote: On Wednesday, 30 July 2014 at 03:32:50 UTC, Walter Bright wrote: I don't either. I still have no idea what the difference between assume(i<6) and assert(i<6) is supposed to be. 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). It still means the same thing as assert. The only relation between the two is that if a runtime check for (x) is inserted at some point, it is safe to insert an assume(x) statement afterwards, because x is known true at that point. I.e. they're the same thing. If assert degenerates to assume in release mode, any bugs in the program could potentially cause a lot more brittleness and unexpected/undefined behavior than they otherwise would have. In particular, code generation based on invalid assumptions could be memory unsafe. Which is why assert can also do a runtime check. I think you misread, none of that follows from what I wrote. Also, "Nuh-uh, they are too the same" is not a valid argument. Can you please address the fact that assume is not @safe? How do you propose to preserve memory safety in release mode if you remove runtime checks for asserts but still assume the condition for codegen?
Re: Value ranges for slices, and more enum preconditions
On 7/30/14, 11:51 AM, bearophile wrote: Just a curiosity of mine: Do you remember who originally proposed to add the value range analysis to D (and the link to the posts/discussion)? It was conceived by Walter, Brad, Bartosz Milewski, Eric Niebler, and myself during one of our infamous weekend meetings in Seattle. I vaguely recall Brad was the first to mention it or at least point out the connection with the compiler optimization. -- Andrei
Re: checkedint call removal
On Wednesday, 30 July 2014 at 20:33:41 UTC, Walter Bright wrote: assume(input!=0); If you want to specify that the input should be prevented from being zero, you do this: if(input!=0){ assert(input!=0); } Now you're trying to use assert to validate user input. This is a terrible, terrible misunderstanding of assert. Can you please read the Hoare article form 1969? This is getting really annoying. I am not trying to use assert to validate user input. I am verifying that the program is in compliance with the specification. Basically doing a partial proof of the theorem in the assert on the fly. Example 1: assume(x!=0) // define an axiom "x!=0" Example 2: if(x!=0){ assert(x!=0) // prove theorem "x!=0" (successful) } Example 3: assert(x!=0) // prove theorem "x!=0" (failure) Example 4: assume(x!=0); // define "x!=0" (impose constraint) assert(x!=0); // prove theorem "x!=0" (successful) I can't do better than this! Think of assume() as preconditions and assert() as postconditions. Note also that you could use an existing theorem prover to prove a function correct, then machine translate it into D code with assume() and assert() and other machinery needed for provable correct programming in D. Don't dismiss the distinction without thinking about it. Read Hoare's article, it is pretty well written.
Re: checkedint call removal
On 7/30/2014 7:36 AM, Ary Borenszweig wrote: Now, if you compile in release mode, according to Walter, all the "asserts" are gone (which, as a side note, is something I don't like: in every case it should throw an AssertError). So the question is: can the compiler still replace that writeln call? Yes.
Re: Voting: std.logger
On 7/30/14, 11:23 AM, linkrope wrote: Yes: most of the time I should be happy with the default log object. Call it "log" and the uses look great: log.error("something went wrong"); Yah but then we have stuttering such as log.log("ehm") which is oddly the same as log("ehm"). -- Andrei
Re: checkedint call removal
On 7/30/2014 2:12 AM, bearophile wrote: Info about assume in Microsoft C++: http://msdn.microsoft.com/en-us/library/1b3fsfxw.aspx Note that document shows how assert is implemented using assume. I.e. they are the same thing. Intriguingly, the __assume(0) behavior is even special cased like D's assert(0). C++ continues to adopt D features :-)
Re: checkedint call removal
On 7/30/2014 5:52 AM, "Ola Fosheim Grøstad" " wrote: On Wednesday, 30 July 2014 at 09:12:56 UTC, bearophile wrote: And assume() and assert() are two different things, used for different purposes. Do not give the same name to two so different features, if you want to keep a language sane. Exactly. If you want to establish that the provided input is never zero and that the program doesn't need to be correct in that case, you do this: assume(input!=0); If you want to specify that the input should be prevented from being zero, you do this: if(input!=0){ assert(input!=0); } Now you're trying to use assert to validate user input. This is a terrible, terrible misunderstanding of assert.
Re: checkedint call removal
On 7/30/2014 2:12 AM, bearophile wrote: The optimizer can certainly use asserts to provide semantic information (even though the dmd one doesn't at the moment). This is not a good idea. That's the job for assume(), not for assert. The two are without distinction. In general assert() verifies something is true, and if it's false, the program just raises an assert error, that is even recoverable. No, it is not recoverable. assert() can be used freely in your code, to make sure you have not done a mistake. assume() is only for special situations where you know something is true, that the compiler can't prove by itself. Again, everything you say is true for assume is true for assert, and vice versa.
Re: How Optlink works
On Wednesday, 30 July 2014 at 19:23:03 UTC, Walter Bright wrote: http://i.imgur.com/iRNrBE4.gif For those who missed it when it was posted last year: "How compilers work: http://imgur.com/OnMc8HO";
Re: checkedint call removal
Here is a set of examples of annotated programs that have been formally proved correct for those interested: http://toccata.lri.fr/gallery/why3.en.html The advantage of formally separating what is proven from what is to be proved is quite obvious. You can generate annotated bindings for libraries and frameworks that can both increase correctness and provide semantic information that can be relied on (for optimization and other purposes).
Re: checkedint call removal
On Wednesday, 30 July 2014 at 14:36:30 UTC, Ary Borenszweig wrote: Could you show an example that's a bit more complex and useful? I'm with Walter that I don't see any difference between assert and assume. assume provide additional axioms to the ones implicit in the program. assert provide theorems to be proven. assume provide claims that already are proven (or just defined as a requirement imposed on the environment). For instance after a system call, you might have a specification that states exactly what you can assume after it returns. That specification you can specify as assume() and you can optimize on those, safely. assert() you cannot optimize on safely. Those are theorems that are yet to be proven.
Re: Optlink Contribution
I like the discussion. I do want to remind everyone that OPTLINK is very fast and switching to a different linker will likely result performance hit. There are advantages to using COFF as it seems more compilers use that format and D would be more interoperable with other compilers and languages. I think every peice of software has it's own goals which determine what tradeoffs to chose. In my view, the linker should 1) always work and 2) be as fast as possible. OPTLINK passes number 2 with flying colors but is does have bugs. This is obviously due to the fact that it is written in assembly but keep in mind that the performance of the linker affects everyone who uses D. Any performance hit on the linker will be seen in every single build of any D program. Adding 1 second to link time will add 1 second to build time since this process cannot be parallelized (as far as I know). That being said, if it were up to me I wouldn't abandon OPTLINK so quickly. I would spend time creating a test suite for OPTLINK, and try to comment the code a little better to encourage other developers to contribute. Then I would consider adding support in DMD to generate COFF output files for those who want to link D object files with another linker. I wouldn't make this a huge priority though as one can use an OMF to COFF converter if they really needed it.
Re: Optlink Contribution
What makes it craziest is that there's a COFF32 branch lying around that nobody merges: http://forum.dlang.org/thread/mailman.1560.1323886804.24802.digitalmar...@puremagic.com?page=9#post-llldfc:242q6p:241:40digitalmars.com Same procedure as every year.
Re: checkedint call removal
On Wednesday, 30 July 2014 at 18:13:07 UTC, Ary Borenszweig wrote: I tried the program in debug mode in thousands of ways and apparently no assert triggers. So I'll just compile in release mode, release it and let anyone find bugs in it and allow to bypass any security or safety I put in my program with those "assert" statmenets, that would probably just take 1 nanosecond to execute anyway. Sounds really nice. (sorry for the sarcasm, removing assert is wrong to me) Use enforce...
Re: 64-bit DMD for windows?
Is there a PR now?
Re: checkedint call removal
On 07/30/2014 09:16 PM, H. S. Teoh via Digitalmars-d wrote: On Wed, Jul 30, 2014 at 07:09:41PM +, via Digitalmars-d wrote: On Wednesday, 30 July 2014 at 18:25:43 UTC, H. S. Teoh via Digitalmars-d wrote: If you want the check to always be there, use enforce, not assert. Doesn't help: module a; void bar(int x) { assert(x > 0); writeln("x = ", x); } // module b; import a; void foo(int x) { enforce(x > 0); bar(x); } If `assert` is treated like `assume` (under Ola's definitions), then `enforce` can be optimized away. Wait, what? I thought the whole point of enforce is that it will *not* be removed by the compiler, no matter what? T That's approximately the crux of the matter, yes. :-)
Re: Optlink Contribution
I don't think dmd comes with a COFF64 linker now, users are just told to install Visual Studio or the Windows SDK for a linker. No reason you can't do the same with COFF32. Optlink can stick around with OMF for a couple releases. I suspect nobody would use it when given the choice of COFF32 support. Anybody seriously programming on Windows uses VS anyway. But at least for 32 bit http://lld.llvm.org/windows_support.html could be packaged.