www.digitalmars.com         C & C++   DMDScript  

D - Once again: generalized "if"-statements

reply Norbert Nemec <nobbi_at_theorie3.physik.uni-erlangen.de NOSPAM.COM> writes:
Hi there,

since my suggestion of "if"-statements outside of functions was somewhat 
ripped apart during the discussion and I begin to understand somewhat more 
now, I'll try to split out the core part and describe that again:

At the first sight, the generalized "if" statement offers exactly what 
"version" does already: Together with a "version"-expression evaluating to 
a boolean at compile-time:
        if(version(MYSYMBOL)) {
                ...
        } else {
                ...
        }
does exactly what
        version(MYSYMBOL) {
                ...
        } else {
                ...
        }
does at the moment. Anyway, since it would handle any kind of constant 
expressions, it would go far beyond that, effectively offering everything
the "#if" directive does in C.

It does so without any significant complication of the language definition. 
Actually, it might even make things simpler, since a "version"-expression 
seems to be somewhat less intruding than the "version" statement.

Anyway, the real power of the construction will really show up together with 
the expected "integers as template parameter" extension. Just a simple 
example:

-------------------
template (int N)
class Someclass {
        if(N<100) {
                dosomething() { simplealgorithm(); }
        } else {
                HashTable table;
                dosomething() { complexalgorithm(table); }
        };
};
-------------------

This will render most uses of partial specialization as in C++ unnecessary. 
Effectively, one could define completely different class contents for 
different parameters, to be determined at compile time.

One useful addition might be the guarantee, that even within functions, 
branches that will never be touched because compile-time-evaluable 
"if"-statements, will not be compiled at all (i.e. only syntax-check, but 
no symbol resolving) since the declaration of some symbols might have been 
dependant on such constants as well.

Ciao,
Nobbi
Jan 20 2003
parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
The only real problem is that the scope of everything defined inside the if
body would have to be moved outside of the if.

This is a C compatibility issue.  It's ok for version to do it since it has
no backward compatibility to deal with.  It might be ok, that everything in
the taken branch gets exposed and stuff in the non-taken branches stay
hidden.

version can also require a compile time constant expression.  With if,
you're never sure if it is, or isn't, a compile time constant.

Sean

"Norbert Nemec" <nobbi_at_theorie3.physik.uni-erlangen.de NOSPAM.COM> wrote
in message news:b0h34s$16qj$1 digitaldaemon.com...
 Hi there,

 since my suggestion of "if"-statements outside of functions was somewhat
 ripped apart during the discussion and I begin to understand somewhat more
 now, I'll try to split out the core part and describe that again:

 At the first sight, the generalized "if" statement offers exactly what
 "version" does already: Together with a "version"-expression evaluating to
 a boolean at compile-time:
         if(version(MYSYMBOL)) {
                 ...
         } else {
                 ...
         }
 does exactly what
         version(MYSYMBOL) {
                 ...
         } else {
                 ...
         }
 does at the moment. Anyway, since it would handle any kind of constant
 expressions, it would go far beyond that, effectively offering everything
 the "#if" directive does in C.

 It does so without any significant complication of the language
definition.
 Actually, it might even make things simpler, since a "version"-expression
 seems to be somewhat less intruding than the "version" statement.

 Anyway, the real power of the construction will really show up together
with
 the expected "integers as template parameter" extension. Just a simple
 example:

 -------------------
 template (int N)
 class Someclass {
         if(N<100) {
                 dosomething() { simplealgorithm(); }
         } else {
                 HashTable table;
                 dosomething() { complexalgorithm(table); }
         };
 };
 -------------------

 This will render most uses of partial specialization as in C++
unnecessary.
 Effectively, one could define completely different class contents for
 different parameters, to be determined at compile time.

 One useful addition might be the guarantee, that even within functions,
 branches that will never be touched because compile-time-evaluable
 "if"-statements, will not be compiled at all (i.e. only syntax-check, but
 no symbol resolving) since the declaration of some symbols might have been
 dependant on such constants as well.

 Ciao,
 Nobbi
Jan 20 2003
next sibling parent "Mike Wynn" <mike.wynn l8night.co.uk> writes:
I like the idea that a template can contain a compile time const as a param
but why must you insist on 'if' when version is already an 'if'

template stuff ( int N ) {
    class Someclass {
        version( N < 100 ) {
                dosomething() { simplealgorithm(); }
           } else {
            HashTable table;
                dosomething() { complexalgorithm(table); }
            } // version
    } // class
} // template

stuff(1) will be a different instance to stuff(2)  (although I'm sure some
smart ast processing might determine if they can be runtime version of the
same basic template).


"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
news:b0hf9e$1egr$1 digitaldaemon.com...
 The only real problem is that the scope of everything defined inside the
if
 body would have to be moved outside of the if.

 This is a C compatibility issue.  It's ok for version to do it since it
has
 no backward compatibility to deal with.  It might be ok, that everything
in
 the taken branch gets exposed and stuff in the non-taken branches stay
 hidden.

 version can also require a compile time constant expression.  With if,
 you're never sure if it is, or isn't, a compile time constant.

 Sean

 "Norbert Nemec" <nobbi_at_theorie3.physik.uni-erlangen.de NOSPAM.COM>
wrote
 in message news:b0h34s$16qj$1 digitaldaemon.com...
 Hi there,

 since my suggestion of "if"-statements outside of functions was somewhat
 ripped apart during the discussion and I begin to understand somewhat
more
 now, I'll try to split out the core part and describe that again:

 At the first sight, the generalized "if" statement offers exactly what
 "version" does already: Together with a "version"-expression evaluating
to
 a boolean at compile-time:
         if(version(MYSYMBOL)) {
                 ...
         } else {
                 ...
         }
 does exactly what
         version(MYSYMBOL) {
                 ...
         } else {
                 ...
         }
 does at the moment. Anyway, since it would handle any kind of constant
 expressions, it would go far beyond that, effectively offering
everything
 the "#if" directive does in C.

 It does so without any significant complication of the language
definition.
 Actually, it might even make things simpler, since a
"version"-expression
 seems to be somewhat less intruding than the "version" statement.

 Anyway, the real power of the construction will really show up together
with
 the expected "integers as template parameter" extension. Just a simple
 example:

 -------------------
 template (int N)
 class Someclass {
         if(N<100) {
                 dosomething() { simplealgorithm(); }
         } else {
                 HashTable table;
                 dosomething() { complexalgorithm(table); }
         };
 };
 -------------------

 This will render most uses of partial specialization as in C++
unnecessary.
 Effectively, one could define completely different class contents for
 different parameters, to be determined at compile time.

 One useful addition might be the guarantee, that even within functions,
 branches that will never be touched because compile-time-evaluable
 "if"-statements, will not be compiled at all (i.e. only syntax-check,
but
 no symbol resolving) since the declaration of some symbols might have
been
 dependant on such constants as well.

 Ciao,
 Nobbi
Jan 20 2003
prev sibling parent Norbert Nemec <nobbi_at_theorie3.physik.uni-erlangen.de NOSPAM.COM> writes:
Sean L. Palmer wrote:

 The only real problem is that the scope of everything defined inside the
 if body would have to be moved outside of the if.
 
 This is a C compatibility issue.  It's ok for version to do it since it
 has
 no backward compatibility to deal with.  It might be ok, that everything
 in the taken branch gets exposed and stuff in the non-taken branches stay
 hidden.
 
 version can also require a compile time constant expression.  With if,
 you're never sure if it is, or isn't, a compile time constant.
OK, you've got a point there! Guess, I have to drop that "if"-idea. Maybe, the better way to go would then be to generalize the "version" statement instead? Right now, it only takes version symbols that are something completely different from normal symbols. I can't see any straightforward way to extend that syntax for compile time boolean expressions. If the version statement were to take expressions, then the version symbols would have to be encapsulated in a defined(...) expression (like in C). This would break compatibility to the current syntax, changing from version(SYMBOL) { ... } to version(defined(SYMBOL)) { ... } Not really a pleasant idea, but the end result would be the cleanest can think of. Alternatively, one could introduce a new statement: conditional(somexpression) { ... } behaving just like version, except that it accepts an expression instead. Anyway, this would mean an unnecessarily complicated language definition for reasons of backward compatibility. In any case, this effectively comes back to the same thing I proposed for "if", only that runtime-if and compiletime-if get two different keywords. Up to discussion whether compiletime-if should be called "version" or something else. Ciao, Nobbi
Jan 21 2003