June 23, 2010 Re: Why assert is in the language? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tomek Sowiński | Tomek Sowiński wrote:
> There's a better way:
>
> void assert_(string file = __FILE__, uint line = __LINE__)(bool pred, lazy
> string msg = null) {
> version(unittest)
> if (!pred)
> throw new AssertError(msg, file, line);
> }
>
> If unittesting is off, it is inlined and all calls vanish.
>
> Someone mentioned the assert(0) special case. That could be implemented
> like:
>
> void fail() {
> asm {
> // HLT instruction...
> }
> }
>
> Following benefits spring to mind:
> - It's clear that fail is something different than assert. Unlike assert
> vs. assert(0).
> - The compiler can be made aware of fail() to recognize and refuse to
> compile dead code.
> - Documentation can be added with no additional effort; newbies can read
> it straight from a tooltip provided by the IDE.
> - Curious users are free to introspect the implementation.
>
> So I ask again -- what benefits on top of that list can having assert in the language give?
>
>
> Tomek
1. The compiler itself uses assert. Given that it uses assert, even if assert isn't a keyword, you won't be able to use it for anything else. Either it's going to be a keyword or it's going to be like Object and be something defined that's always defined, so you can't use the name for anything else. At that point, it might as well be a keyword - on top of which making it a keyword makes it so that IDEs are likely to highlight it accordingly, and it will be more obvious in the code.
2. It's almost certainly more efficient as a keyword. As a keyword, there likely aren't any function calls going on beyond what's being asserted. If it were an actual function, given that it's used primarily in debug mode, it almost certainly wouldn't be inlined, and it would slow down the code that much more.
3. Making assert a keyword makes it easier for the compiler to treat it specially. It knows about assert and what to do with it without having to examine every function to see whether it's assert and therefore have to treat it differently. The closest to anything, that I'm aware of, which is treated specially in that manner is Object, and unlike examining each function to see whether it should treat it specially, it will be quite straightforward with Object because it only has to deal with it specially when dealing with class declarations, and since it _always_ inserts the Object stuff in that case, it's a no-brainer. Having to look at each function to see whether it's on the list of functions to treat specially would have to slow compilation down. Not to mention, Walter's trying to keep D such that it's fairly easy to compile so that tools (including the compiler) will have a much easier time handling it and are less likely to be buggy. If it starts having to treat functions in a special way, then that's just going to have to complicate things.
4. Given that Walter is definitely pushing design by contracts and unit tests - both of which need assertions - it makes perfect sense to include assertions in the language itself.
5. I see _0_ downsides to assert being in the language itself. Sure, there may be ways to make assert better, but that doesn't require it to be done in library code. We might as well put it in the language itself and give the compiler the chance to deal with it specially.
- Jonathan M Davis
|
June 24, 2010 Re: Why assert is in the language? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tomek Sowiński | On Wed, 23 Jun 2010 16:06:48 -0400, Tomek Sowiński <just@ask.me> wrote: > Dnia 22-06-2010 o 23:55:29 Michal Minich <michal.minich@gmail.com> napisał(a): > >> On Tue, 22 Jun 2010 17:30:23 -0400, Steven Schveighoffer wrote: >> >>> On Tue, 22 Jun 2010 17:07:02 -0400, Tomek Sowiński <just@ask.me> wrote: >>> >>>> Yes, why? It could be implemented in object.d in a similar fashion as >>>> std.contracts.enforce. Does it do anything special that a library >>>> function couldn't? >>> >>> all calls to assert are removed by the compiler in release mode. I >>> don't think there's a way to implement that via a library (it would be >>> nice though!) >>> >>> -Steve >> >> modifying 'debug' attribute which decorate a function, which new meaning >> that all calls to it are removed in release mode, might do the trick :) >> it also could be useful for logging. That means you have to compile with -debug switch. Assert is enabled without any switches. >> >> AFAIK, now the attribute means that the function does not exists in debug >> mode, but that also means that you must mark all calls to it with 'debug' >> which I don't find so much useful... > > There's a better way: > > void assert_(string file = __FILE__, uint line = __LINE__)(bool pred, lazy string msg = null) { > version(unittest) > if (!pred) > throw new AssertError(msg, file, line); > } > > If unittesting is off, it is inlined and all calls vanish. Only if you specify -inline on the command line... Not a good option. > Someone mentioned the assert(0) special case. That could be implemented like: > > void fail() { > asm { > // HLT instruction... > } > } > > Following benefits spring to mind: > - It's clear that fail is something different than assert. Unlike assert vs. assert(0). > - The compiler can be made aware of fail() to recognize and refuse to compile dead code. > - Documentation can be added with no additional effort; newbies can read it straight from a tooltip provided by the IDE. > - Curious users are free to introspect the implementation. > > So I ask again -- what benefits on top of that list can having assert in the language give? Well, first, you can't implement it in the library as currently designed without requiring special switches for normal compilation. No need to have any more reasons. What are the drawbacks? "keyword bloat" is an academic measure, and doesn't count ;) -Steve |
June 24, 2010 Re: Why assert is in the language? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Dnia 24-06-2010 o 01:39:35 Jonathan M Davis <jmdavisProg@gmail.com> napisał(a):
> Tomek Sowiński wrote:
>
>> There's a better way:
>>
>> void assert_(string file = __FILE__, uint line = __LINE__)(bool pred, lazy
>> string msg = null) {
>> version(unittest)
>> if (!pred)
>> throw new AssertError(msg, file, line);
>> }
>>
>> If unittesting is off, it is inlined and all calls vanish.
>>
>> Someone mentioned the assert(0) special case. That could be implemented
>> like:
>>
>> void fail() {
>> asm {
>> // HLT instruction...
>> }
>> }
>>
>> Following benefits spring to mind:
>> - It's clear that fail is something different than assert. Unlike assert
>> vs. assert(0).
>> - The compiler can be made aware of fail() to recognize and refuse to
>> compile dead code.
>> - Documentation can be added with no additional effort; newbies can read
>> it straight from a tooltip provided by the IDE.
>> - Curious users are free to introspect the implementation.
>>
>> So I ask again -- what benefits on top of that list can having assert in
>> the language give?
>>
>>
>> Tomek
>
> 1. The compiler itself uses assert. Given that it uses assert, even if
> assert isn't a keyword, you won't be able to use it for anything else.
> Either it's going to be a keyword or it's going to be like Object and be
> something defined that's always defined, so you can't use the name for
> anything else. At that point, it might as well be a keyword - on top of
> which making it a keyword makes it so that IDEs are likely to highlight it
> accordingly, and it will be more obvious in the code.
>
> 2. It's almost certainly more efficient as a keyword. As a keyword, there
> likely aren't any function calls going on beyond what's being asserted. If
> it were an actual function, given that it's used primarily in debug mode, it
> almost certainly wouldn't be inlined, and it would slow down the code that
> much more.
>
> 3. Making assert a keyword makes it easier for the compiler to treat it
> specially. It knows about assert and what to do with it without having to
> examine every function to see whether it's assert and therefore have to
> treat it differently. The closest to anything, that I'm aware of, which is
> treated specially in that manner is Object, and unlike examining each
> function to see whether it should treat it specially, it will be quite
> straightforward with Object because it only has to deal with it specially
> when dealing with class declarations, and since it _always_ inserts the
> Object stuff in that case, it's a no-brainer. Having to look at each
> function to see whether it's on the list of functions to treat specially
> would have to slow compilation down. Not to mention, Walter's trying to keep
> D such that it's fairly easy to compile so that tools (including the
> compiler) will have a much easier time handling it and are less likely to be
> buggy. If it starts having to treat functions in a special way, then that's
> just going to have to complicate things.
>
> 4. Given that Walter is definitely pushing design by contracts and unit
> tests - both of which need assertions - it makes perfect sense to include
> assertions in the language itself.
>
> 5. I see _0_ downsides to assert being in the language itself. Sure, there
> may be ways to make assert better, but that doesn't require it to be done in
> library code. We might as well put it in the language itself and give the
> compiler the chance to deal with it specially.
>
> - Jonathan M Davis
OK, I get it. Thanks for your elaborate answer.
Tomek
|
Copyright © 1999-2021 by the D Language Foundation