Designing a new general-purpose language

How to implement asserts

I guess I haven't written in a while.  I had more to say on the last topic, but I will have to come back to it.  At the moment, my head is full of ideas inspired partly by a new D Programming Language feature (http://www.digitalmars.com/d/lazy-evaluation.html) and partly by this article ("Enforcements" http://www.ddj.com/dept/cpp/184403864) which I found for the first time a few days ago when I was reading about D's lazy evaluation (I know, it's an old article).

The Enforcements article gives extremely good coverage of how to use templates and macros in C++ to implement a rich "idiom" of code that enforces various conditions at runtime.  The article on D's lazy evaluation shows among other things how this feature can be used to improve upon the implementation of the enforcement idiom in D.  I want to take this a bit further and look at how readability and writeability of such idioms could be improved by building support for them into the language from the beginning.  Here are some initial observations and assumptions I have when approaching this problem:

  • Asserts are very commonly used and useful to developers, enough so on both points that I believe it makes sense to consider special support for them in the language.  This is not entirely unprecedented in modern language design ("assert" is a keyword in both Java and D for example).
  • From my experience, asserts can have a wide range of behavior between projects and occasionally even within projects.  If asserts in the language are not rich enough to enable this wide range of behaviors, many developers will not use them in favor of something hand-rolled.
  • Despite the wide range of behavior, asserts have fairly consistent semantics: if this fails, it is unexpected.
  • Asserts can have special meaning to analysis tools and even to the optimizer.

In addition, I was thinking about a broader goal:

  • A modern language should not need a preprocessor.  Many things that can be done with a preprocessor that can't be replicated with templates/mixins/inline functions are used almost exclusively for asserts and similar error detection/handling/control idioms.  By supporting these functions in a more intuitive way, specifically for asserts if necessary, we can knock a couple more things off the list of "why it is useful to have a preprocessor".

Among the preprocessor functions/tricks I am referring to are:

  • Coverting a macro parameter to a string (the # preprocessor operator in C and C++).  Assert macros often do this to turn the assert condition into a debugging message (and believe me, this is extremely helpful when debugging).
  • Having access to predefined macros such as __LINE__, __FUNCTION__, etc. at the point of expansion.
  • Being able to goto a label if that is how you do your error handling (I'm sure I will have a post on this later).  Actually, to be honest I don't think I've seen too much of this type of thing in an assert macro, but I have thought of using it myself, to provide a safe fallback to asserts and to help satisfy analysis tools.

I'll outline some of my ideas in the next post.

Published Saturday, September 09, 2006 12:15 AM by hartwil

Comments

No Comments
Anonymous comments are disabled

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker