Thread overview
Once again: generalized "if"-statements
Jan 20, 2003
Norbert Nemec
Jan 20, 2003
Sean L. Palmer
Jan 20, 2003
Mike Wynn
Jan 21, 2003
Norbert Nemec
January 20, 2003
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

January 20, 2003
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
>


January 20, 2003
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
> >
>
>


January 21, 2003
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