www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Assert

reply "David B. Held" <dheld codelogicconsulting.com> writes:
I think assert() will get fixed when we get AST macros.  It won't get 
fixed by Walter, of course, but rather, by us.  Everyone will invent 
their favorite assert(), and the builtin will only get called by Phobos. 
  And then, 10 years down the road, Walter will be writing "The Design 
and Evolution of D", where he will have to explain why assert(o) doesn't 
do the obvious thing, even though everyone else's does. ;>

Dave
Jun 28 2007
next sibling parent reply Reiner Pope <some address.com> writes:
David B. Held wrote:
 I think assert() will get fixed when we get AST macros.  It won't get 
 fixed by Walter, of course, but rather, by us.  Everyone will invent 
 their favorite assert(), and the builtin will only get called by Phobos. 
  And then, 10 years down the road, Walter will be writing "The Design 
 and Evolution of D", where he will have to explain why assert(o) doesn't 
 do the obvious thing, even though everyone else's does. ;>
 
 Dave

Sounds exciting. (although the prospect of accepting that assert is wrong just because it can be fixed is thoughtless.) I know we're deep in const at the moment, but is there any news/thoughts on AST macros, to whet our appetites? -- Reiner
Jun 28 2007
next sibling parent Don Clugston <dac nospam.com.au> writes:
Reiner Pope wrote:
 David B. Held wrote:
 I think assert() will get fixed when we get AST macros.


 I know we're deep in const at the moment, but is there any news/thoughts 
 on AST macros, to whet our appetites?

Why would you bother? Using DMD 1.015, the code to generate an AST is *very* short (less than 2 lines of code per operator). <g> It's far more flexible than a built-in solution would be. All we need is a bit of syntactic sugar to allow us to generate mixin(func(`x+y`, `"abc"`)); when we type func(x+y, "abc"); We can do everything else already. <g>
Jun 28 2007
prev sibling parent "David B. Held" <dheld codelogicconsulting.com> writes:
Reiner Pope wrote:
 [...]
 I know we're deep in const at the moment, but is there any news/thoughts 
 on AST macros, to whet our appetites?

Not really. Just that Walter is as excited about them as you are, and wants to get to it Real Soon Now(TM). Dave
Jun 28 2007
prev sibling parent reply BCS <ao pathlink.com> writes:
Reply to David,

 I think assert() will get fixed when we get AST macros.  It won't get
 fixed by Walter, of course, but rather, by us.  Everyone will invent
 their favorite assert(), and the builtin will only get called by
 Phobos.
 And then, 10 years down the road, Walter will be writing "The Design
 and Evolution of D", where he will have to explain why assert(o)
 doesn't
 do the obvious thing, even though everyone else's does. ;>
 
 Dave
 

what is there to fix? (that is not a rhetorical question)
Jun 28 2007
parent reply "David B. Held" <dheld codelogicconsulting.com> writes:
BCS wrote:
 Reply to David,
 
 I think assert() will get fixed when we get AST macros.  It won't get
 fixed by Walter, of course, but rather, by us.  Everyone will invent
 their favorite assert(), and the builtin will only get called by
 Phobos.
 And then, 10 years down the road, Walter will be writing "The Design
 and Evolution of D", where he will have to explain why assert(o)
 doesn't
 do the obvious thing, even though everyone else's does. ;>

what is there to fix? (that is not a rhetorical question)

Well, for one, the fact that "assert(obj)" doesn't do what 99% of noobs (including me!) expect it to do. Two, you can't write a custom assert() that has non-standard messaging. For instance, there is an extremely common idiom in all languages (that support exceptions) that basically looks like this: if (!everything_ok) { throw SomeException("Helpful message"); } Andrei happens to call this micro-pattern "enforce()", which I think is a perfectly reasonable name for it. What we would like to do is something like so: #define enforce(cond, message) \ if (!cond) throw SomeException(#cond + ": " + message); Bar* ptr = foo(); enforce(ptr != null, "foo() failed"); Obviously there's a thousand ways to riff on that basic idea, but try writing this function in D. As you can see, it's essentially a form of assert(). Dave
Jun 28 2007
next sibling parent Derek Parnell <derek nomail.afraid.org> writes:
On Thu, 28 Jun 2007 23:08:45 -0700, David B. Held wrote:


 something like so:
 
 #define enforce(cond, message) \
      if (!cond) throw SomeException(#cond + ": " + message);
 
 Bar* ptr = foo();
 enforce(ptr != null, "foo() failed");

Isn't ... assert(ptr !is null, "foo() failed to supply a valid Bar pointer"); okay to use? -- Derek (skype: derek.j.parnell) Melbourne, Australia 29/06/2007 4:52:03 PM
Jun 28 2007
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
David B. Held wrote:
 BCS wrote:
 Reply to David,

 I think assert() will get fixed when we get AST macros.  It won't get
 fixed by Walter, of course, but rather, by us.  Everyone will invent
 their favorite assert(), and the builtin will only get called by
 Phobos.
 And then, 10 years down the road, Walter will be writing "The Design
 and Evolution of D", where he will have to explain why assert(o)
 doesn't
 do the obvious thing, even though everyone else's does. ;>

what is there to fix? (that is not a rhetorical question)

Well, for one, the fact that "assert(obj)" doesn't do what 99% of noobs (including me!) expect it to do. Two, you can't write a custom assert() that has non-standard messaging. For instance, there is an extremely common idiom in all languages (that support exceptions) that basically looks like this: if (!everything_ok) { throw SomeException("Helpful message"); } Andrei happens to call this micro-pattern "enforce()", which I think is a perfectly reasonable name for it. What we would like to do is something like so: #define enforce(cond, message) \ if (!cond) throw SomeException(#cond + ": " + message); Bar* ptr = foo(); enforce(ptr != null, "foo() failed"); Obviously there's a thousand ways to riff on that basic idea, but try writing this function in D. As you can see, it's essentially a form of assert().

Seems like the main problem is that assert is compiled out in release builds, correct? Throwing a custom message and such already works. Sean
Jun 29 2007
parent reply "David B. Held" <dheld codelogicconsulting.com> writes:
Sean Kelly wrote:
 [...]
 Seems like the main problem is that assert is compiled out in release 
 builds, correct?  Throwing a custom message and such already works.

No, you guys are missing the important point: *stringizing the condition*. That is what is impossible without repeating the condition or having macros. Dave
Jun 29 2007
parent reply Lutger <lutger.blijdestijn gmail.com> writes:
David B. Held wrote:
 Sean Kelly wrote:
 [...]
 Seems like the main problem is that assert is compiled out in release 
 builds, correct?  Throwing a custom message and such already works.

No, you guys are missing the important point: *stringizing the condition*. That is what is impossible without repeating the condition or having macros. Dave

Not impossible, but ugly: char[] enforce(char[] cond, char[] msg) { return "if (!(" ~ cond ~ ")) throw new Exception(\"" ~ cond ~ ": " ~ msg ~ "\");"; } mixin(enforce("ptr != null", "foo() failed"));
Jun 30 2007
parent reply "David B. Held" <dheld codelogicconsulting.com> writes:
Lutger wrote:
 [...]
 Not impossible, but ugly:
 
 char[] enforce(char[] cond, char[] msg)
 {
     return "if (!(" ~ cond ~ "))
             throw new Exception(\"" ~ cond ~ ": " ~ msg ~ "\");";
 }
 
 mixin(enforce("ptr != null", "foo() failed"));

Well, "stringizing by hand" isn't exactly in the repertoire of possibility that I was considering, given that we can write any code we want in a mixin statement. Clearly, this kind of solution is less than ideal. Dave
Jun 30 2007
parent reply Don Clugston <dac nospam.com.au> writes:
David B. Held wrote:
 Lutger wrote:
 [...]
 Not impossible, but ugly:

 char[] enforce(char[] cond, char[] msg)
 {
     return "if (!(" ~ cond ~ "))
             throw new Exception(\"" ~ cond ~ ": " ~ msg ~ "\");";
 }

 mixin(enforce("ptr != null", "foo() failed"));

Well, "stringizing by hand" isn't exactly in the repertoire of possibility that I was considering, given that we can write any code we want in a mixin statement. Clearly, this kind of solution is less than ideal.

Yes, but it's really only syntactic sugar that's lacking. The functionality is almost identical to what you'd want from a macro. We're _so_ close.
 
 Dave

Jun 30 2007
parent "Bent Rasmussen" <incredibleshrinkingsphere gmail.com> writes:
True. This string mixin semantics is powerful, if not quite as discrete as 
could be wished.

It removes redundancy here, but leaves a small syntactic footprint.

"Don Clugston" <dac nospam.com.au> wrote in message 
news:f66c1k$40g$1 digitalmars.com...
 Yes, but it's really only syntactic sugar that's lacking. The 
 functionality is almost identical to what you'd want from a macro. We're 
 _so_ close.

Jul 06 2007
prev sibling next sibling parent reply Georg Wrede <georg nospam.org> writes:
David B. Held wrote:
 BCS wrote:
 Reply to David,

 I think assert() will get fixed when we get AST macros.



Yes, it looks that way.
 It won't get fixed by Walter, of course, but rather, by us.
 Everyone will invent their favorite assert(), and the builtin
 will only get called by Phobos.



"the builtin will only get called by Phobos" sounds a bit ominous.
 And then, 10 years down the road, Walter will be writing "The Design
 and Evolution of D", where he will have to explain why assert(o)
 doesn't do the obvious thing, even though everyone else's does. ;>



Hmm. Unfortunately I agree.
 what is there to fix? (that is not a rhetorical question)

Well, for one, the fact that "assert(obj)" doesn't do what 99% of noobs (including me!) expect it to do. Two, you can't write a custom assert() that has non-standard messaging. For instance, there is an extremely common idiom in all languages (that support exceptions) that basically looks like this: if (!everything_ok) { throw SomeException("Helpful message"); } Andrei happens to call this micro-pattern "enforce()", which I think is a perfectly reasonable name for it.

DAVID, please, take note: enforce might not be the optimum word for it. I'd rather suggest "ensure". (Yes, David and not Andrei, because I assume English is David's mother tongue, so he's got some influence on Andrei about this.) IMHO, "enforce" is like holding somebody at gunpoint, while "ensure" is like an "ultimate check". In other words, "enforce" ends up (in the real world) in coercing, while "ensure" ends up in "double check this, and if it doesn't work, ask your boss".
 What we would like to do is 
 something like so:
 
 #define enforce(cond, message) \
     if (!cond) throw SomeException(#cond + ": " + message);
 
 Bar* ptr = foo();
 enforce(ptr != null, "foo() failed");
 
 Obviously there's a thousand ways to riff on that basic idea, but try 
 writing this function in D.  As you can see, it's essentially a form of 
 assert().

Yes. And if nothing else, this should convince Walter to not have assert() to be inconsistent.
Jun 30 2007
parent reply "David B. Held" <dheld codelogicconsulting.com> writes:
Georg Wrede wrote:
 [...]
 DAVID, please, take note: enforce might not be the optimum word for it. 
 I'd rather suggest "ensure". (Yes, David and not Andrei, because I 
 assume English is David's mother tongue, so he's got some influence on 
 Andrei about this.)
 
 IMHO, "enforce" is like holding somebody at gunpoint, while "ensure" is 
 like an "ultimate check". In other words, "enforce" ends up (in the real 
 world) in coercing, while "ensure" ends up in "double check this, and if 
 it doesn't work, ask your boss".
 [...]

I agree that denotationally, "ensure" is probably more correct, but connotationally, I think "enforce" is better. "Ensure" has a pansy tone to it that I wouldn't take very seriously; but when I see "enforce", I think "Oh, I'd better take a look at what this is doing." Dave
Jun 30 2007
parent Sean Kelly <sean f4.ca> writes:
David B. Held wrote:
 Georg Wrede wrote:
 [...]
 DAVID, please, take note: enforce might not be the optimum word for 
 it. I'd rather suggest "ensure". (Yes, David and not Andrei, because I 
 assume English is David's mother tongue, so he's got some influence on 
 Andrei about this.)

 IMHO, "enforce" is like holding somebody at gunpoint, while "ensure" 
 is like an "ultimate check". In other words, "enforce" ends up (in the 
 real world) in coercing, while "ensure" ends up in "double check this, 
 and if it doesn't work, ask your boss".
 [...]

I agree that denotationally, "ensure" is probably more correct, but connotationally, I think "enforce" is better. "Ensure" has a pansy tone to it that I wouldn't take very seriously; but when I see "enforce", I think "Oh, I'd better take a look at what this is doing."

I've used "predicate" for this before. Sean
Jul 01 2007
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
David B. Held wrote:
 Obviously there's a thousand ways to riff on that basic idea, but try 
 writing this function in D.  As you can see, it's essentially a form of 
 assert().

Done: T Enforce(T)(T p, lazy char[] msg) { if (!p) throw new Exception(msg()); return p; } http://www.digitalmars.com/d/1.0/lazy-evaluation.html
Jul 01 2007
parent "David B. Held" <dheld codelogicconsulting.com> writes:
Walter Bright wrote:
 David B. Held wrote:
 Obviously there's a thousand ways to riff on that basic idea, but try 
 writing this function in D.  As you can see, it's essentially a form 
 of assert().

Done: T Enforce(T)(T p, lazy char[] msg) { if (!p) throw new Exception(msg()); return p; } http://www.digitalmars.com/d/1.0/lazy-evaluation.html

Yeah, that's what everyone else said. But what it is missing is *stringizing of the condition*, so that you can put it into the message. For Enforce(), that's not as important; but for a custom assert(), it is. Dave
Jul 01 2007