Jump to page: 1 2
Thread overview
Suggestion: "if" outside of function blocks (and much more)
Jan 17, 2003
Norbert Nemec
Jan 17, 2003
Evan McClanahan
Jan 17, 2003
Norbert Nemec
Jan 17, 2003
Mike Wynn
Jan 18, 2003
Norbert Nemec
Jan 18, 2003
Mike Wynn
Jan 18, 2003
Norbert Nemec
Jan 18, 2003
Mike Wynn
Jan 18, 2003
Daniel Yokomiso
Jan 18, 2003
Mike Wynn
Jan 18, 2003
Sean L. Palmer
January 17, 2003
Hi there,

just a quick and dirty suggestion:

How about allowing "if"-"else"-blocks outside of function blocks? Of course, the argument will have to be computable at compile time.

This simple construct will allow several things:

* "version" could become a boolean expression instead of a block statement.
        version(...) {
        }
  would become
        if(version(...)) {
        }
  with the added possibily of logic constructions.

* Together with integers as template parameters, the data fields of a template class could be dependant on those parameters.

The addition should be absolutely straightforward. Anyhow a few more additions would make it even more powerful:

* Define "compile-time-value" as any value that can be deduced by the compiler.

* Define "function without side-effects" (should be an attribute of some kind)

* Require the compiler to be able to run such functions at compile time if the arguments are compile-time-value

Now, every expression made up of constants, basic operators and functions without side-effects are compile-time-values.

This all taken together would perhaps give us all the compile-time-computing-power we need to put really heavy optimization into a library.

One more detail: There should be an argument for function arguments to be specified as compile-time-values. This way, the function can only be called with a compile-time-value provided at that point, and inside the function, the value can be used, p.e. as a template parameter.

And a last thought: it might prove useful to provide a larger set of expressions for handling types, like comparing them, etc. so these can be used in compile-time decisions within a template library.

Ciao,
Nobbi

January 17, 2003
Comments embedded.

Norbert Nemec wrote:
> Hi there,
> 
> just a quick and dirty suggestion:
> 
> How about allowing "if"-"else"-blocks outside of function blocks? Of course, the argument will have to be computable at compile time.
> 
> This simple construct will allow several things:
> 
> * "version" could become a boolean expression instead of a block statement.
>         version(...) {
>         }
>   would become
>         if(version(...)) {
>         }
>   with the added possibily of logic constructions.

This seems like the mechanism already in place, I don't really see the win there.  Unless I'm wrong and you can't do

version(..1)
{
}
version(..2)
{
}
else
{
}

in which case I see where you're going and approve.

> * Together with integers as template parameters, the data fields of a template class could be dependant on those parameters.
> 
> The addition should be absolutely straightforward. Anyhow a few more additions would make it even more powerful:
> 
> * Define "compile-time-value" as any value that can be deduced by the compiler.
> 
> * Define "function without side-effects" (should be an attribute of some kind)
> 
> * Require the compiler to be able to run such functions at compile time if the arguments are compile-time-value

hard to do, chews up keywords.  Hard to make guarantees in those respects, I think.  It would also be *really* annoying to maintain.  But then, I'm not really interested in writing libraries, so if it didn't intrude much, I'd not really complain.

> Now, every expression made up of constants, basic operators and functions without side-effects are compile-time-values.
> 
> This all taken together would perhaps give us all the compile-time-computing-power we need to put really heavy optimization into a library.
> 
> One more detail: There should be an argument for function arguments to be specified as compile-time-values. This way, the function can only be called with a compile-time-value provided at that point, and inside the function, the value can be used, p.e. as a template parameter.
> 
> And a last thought: it might prove useful to provide a larger set of expressions for handling types, like comparing them, etc. so these can be used in compile-time decisions within a template library.
> 
> Ciao,
> Nobbi
> 

January 17, 2003
Evan McClanahan wrote:

> Comments embedded.
> 
> Norbert Nemec wrote:
>> Hi there,
>> 
>> just a quick and dirty suggestion:
>> 
>> How about allowing "if"-"else"-blocks outside of function blocks? Of course, the argument will have to be computable at compile time.
>> 
>> This simple construct will allow several things:
>> 
>> * "version" could become a boolean expression instead of a block
>> statement.
>>         version(...) {
>>         }
>>   would become
>>         if(version(...)) {
>>         }
>>   with the added possibily of logic constructions.
> 
> This seems like the mechanism already in place, I don't really see the win there.  Unless I'm wrong and you can't do
> 
> version(..1)
> {
> }
> version(..2)
> {
> }
> else
> {
> }
> 
> in which case I see where you're going and approve.

There's no win at that point. Just that the language definition becomes simpler if "version" is not an additional block statement, but simply a expression evaluating to a boolean. And my generalized "if" is by far more powerful, and maybe even easier to understand, than the current "version"-block statement. The language definition gets tidier and the result is far more expressive.

>> * Define "compile-time-value" as any value that can be deduced by the compiler.
>> 
>> * Define "function without side-effects" (should be an attribute of some kind)
>> 
>> * Require the compiler to be able to run such functions at compile time if the arguments are compile-time-values
> 
> hard to do, chews up keywords.

???!!! "const" is there already. One keyword for "function without side-effects" would have to be found (suggestions?). That's it.

> Hard to make guarantees in those respects, I think.
> It would also be *really* annoying to maintain.  But
> then, I'm not really interested in writing libraries, so if it didn't
> intrude much, I'd not really complain.

What do you mean? Maintain the code? Nothing special to do there. I just propose the additional possibility to give a special attribute to some functions so they can be used in places where the result has to be know at compile time. This doesn't restrict the use of the function, just what you can do within. And since, usually, you would't want to do expensive computations at compile-time anyway, it is mainly meant for tiny, simple functions after all. So where's the problem?

Of course, the compiler needs some additional intelligence, but about all that is needed is there already for optimization. Basically, what I'm talking about, is constant folding and inlining. About every reasonable compiler has those, so the extra effort is not that bad. What is needed, is to define what exactly is allowed in a function without side-effects and assure that the compiler can do those things at compile time.

Ciao,
Nobbi
January 17, 2003
this is something I have been thinking about, allowing D to be used for
runtime and compile time code.
allowing sections of code, and variables to exists at compile time (a D
interpreter as part of the D compile, the ast/dag could be interpreted
instead of compiled)
you can perform all the features of C preprocessor macros and inline
functions etc;
I think allowing a clear distinction between runtime and compile time values
and code may seem odd to C/C++ programmers and is a feature I've not seen in
any languages (has anyone?), but is something I've wanted in several.

compiletime { .... compile time executed D ... }

so to create a static array of constants

Object[] foo;
// may have to be compiletime(visible) Object[] foo;
// might be compiletime( only ) {
// or compiletime( eval ) {
compiletime {
       /// perfroms the same op as c++ [cost] Object[] = { { 1, 2 }, { 2,
4, } ..... }; but with more flexability
        /// will actually create a "snap shot" in rom/code/ram of the
compiled object mesh.
    foo = new MyObject[5];
    for ( int i = 0; i < 5; i++ )
    {
        foo[i] = new MyObject( i, myFunc( i*2 ) );
    }
}

compiletime int min( int a, int b ) { return a < b ? a : b ; }
would only compile if a and b are determinable at compile time, in the
current context

etc and so on

it would be good if templates could have parameter arrays too

template foo ( T, P )
{
    T myFunc( P )
    {
        compiletime {
            if ( cast( ctParams[]) P )
            {
                    if ( !(P[0].hasoperator( +, T  ) ) ) throw new
CompileTimeError( "Param 0 must have and operator + for foo.MyFunc to
work" );
                runtime {
                       T = compileTime P[0] + compileTime P[1];
                }
            }
            else
                throw CompileTimeError( "P must be a param list type " );
        }
    }
}

"Norbert Nemec" <nobbi_at_theorie3.physik.uni-erlangen.de@NOSPAM.COM> wrote in message news:b090su$2qf4$1@digitaldaemon.com...
> Hi there,
>
> just a quick and dirty suggestion:
>
> How about allowing "if"-"else"-blocks outside of function blocks? Of
course,
> the argument will have to be computable at compile time.
>
> This simple construct will allow several things:
>
> * "version" could become a boolean expression instead of a block
statement.
>         version(...) {
>         }
>   would become
>         if(version(...)) {
>         }
>   with the added possibily of logic constructions.
>
> * Together with integers as template parameters, the data fields of a template class could be dependant on those parameters.
>
> The addition should be absolutely straightforward. Anyhow a few more additions would make it even more powerful:
>
> * Define "compile-time-value" as any value that can be deduced by the compiler.
>
> * Define "function without side-effects" (should be an attribute of some
> kind)
>
> * Require the compiler to be able to run such functions at compile time if the arguments are compile-time-value
>
> Now, every expression made up of constants, basic operators and functions without side-effects are compile-time-values.
>
> This all taken together would perhaps give us all the compile-time-computing-power we need to put really heavy optimization into a library.
>
> One more detail: There should be an argument for function arguments to be specified as compile-time-values. This way, the function can only be
called
> with a compile-time-value provided at that point, and inside the function, the value can be used, p.e. as a template parameter.
>
> And a last thought: it might prove useful to provide a larger set of expressions for handling types, like comparing them, etc. so these can be used in compile-time decisions within a template library.
>
> Ciao,
> Nobbi
>


January 18, 2003
Mike Wynn wrote:

> this is something I have been thinking about, allowing D to be used for
> runtime and compile time code.
> allowing sections of code, and variables to exists at compile time (a D
> interpreter as part of the D compile, the ast/dag could be interpreted
> instead of compiled)
> you can perform all the features of C preprocessor macros and inline
> functions etc;
> I think allowing a clear distinction between runtime and compile time
> values and code may seem odd to C/C++ programmers and is a feature I've
> not seen in any languages (has anyone?), but is something I've wanted in
> several.

Well, part of it is present in many languages. C++ allows a const to be calculated as an expression of other consts. I never thought of any special "compiletime" functions, but just of functions that are allowed in such a constant expression. Many language features (like pointer handling etc.) would have to be prohibited in those restricted functions, but otherwise they are just plain functions usuable at any point in the code. The only point where the whole thing goes beyond plain constant folding is, that via "if" statements outside of functions, there can be arbitrary decisions made at compile time about the code that is to be produced.

Anyhow, the idea of a "CompileTimeError" is something I missed. Of course this would be necessary - although I don't think "throw" should be used for it. It should rather be done by a separate statement.

Ciao,
Nobbi
January 18, 2003
"Norbert Nemec" <Nobbi_at_theorie3.physik.uni-erlangen.de@NOSPAM.COM> wrote in message news:b0a9i8$jm6$1@digitaldaemon.com...
> Mike Wynn wrote:
>
> > this is something I have been thinking about, allowing D to be used for
> > runtime and compile time code.
> > allowing sections of code, and variables to exists at compile time (a D
> > interpreter as part of the D compile, the ast/dag could be interpreted
> > instead of compiled)
> > you can perform all the features of C preprocessor macros and inline
> > functions etc;
> > I think allowing a clear distinction between runtime and compile time
> > values and code may seem odd to C/C++ programmers and is a feature I've
> > not seen in any languages (has anyone?), but is something I've wanted in
> > several.
>
> Well, part of it is present in many languages. C++ allows a const to be calculated as an expression of other consts. I never thought of any
special
> "compiletime" functions, but just of functions that are allowed in such a constant expression. Many language features (like pointer handling etc.) would have to be prohibited in those restricted functions, but otherwise they are just plain functions usuable at any point in the code. The only point where the whole thing goes beyond plain constant folding is, that
via
> "if" statements outside of functions, there can be arbitrary decisions
made
> at compile time about the code that is to be produced.


exactly my point, parts are present in other langs, but not the concept that
code can be run at either compile time or runtime explicitly.
why stop at 'if', if you have if, you need to have expressions, many
statements can be written as expressions; infact many programs can be
rewritten to be one expression, so not why go that extra step; this allows
manual control over constant folding
allows you to write lookuptables in the same code as the program;
think of it this way, you can write a sin lookuptable (float ->fixed compile
time conversion) that is build by the compiler to run on a platform without
floats, but without having to write two programs.
no more writing programs to generate source code, for the compiler to
compile, you write is all in one program, easy to maintain, easy to modify
when things change 0..360 deg lookup not 0..256 all the consts that the
lookuptable gen code sees are all the same values that the final code sees

pointers to static data are known at compile time (or enough is know about
them to link later)
so why not allow compile time new that allocate in the final code/rom image
?

>
> Anyhow, the idea of a "CompileTimeError" is something I missed. Of course this would be necessary - although I don't think "throw" should be used
for
> it. It should rather be done by a separate statement.
>

Why ? that's what exceptions are for, I can not continue along this code
path - goto somewhere (anywhere) that can deal with the problem.
seem simple and logical (to me). why add yet another keyword/feature when
there is a perfect solution already there.
all though I do see a problem with 'new' which would create the exception
object in the final image, but thats o.k. because the compile is being
terminated, if the exception is caught, that's also o.k. the new'ed objects
would only need one gc mark-sweep cycle to remove unreachables before
comitting the data to the object file image.

Mike.


January 18, 2003
"Mike Wynn" <mike.wynn@l8night.co.uk> escreveu na mensagem news:b09ou3$9jj$1@digitaldaemon.com...
> this is something I have been thinking about, allowing D to be used for
> runtime and compile time code.
> allowing sections of code, and variables to exists at compile time (a D
> interpreter as part of the D compile, the ast/dag could be interpreted
> instead of compiled)
> you can perform all the features of C preprocessor macros and inline
> functions etc;
> I think allowing a clear distinction between runtime and compile time
values
> and code may seem odd to C/C++ programmers and is a feature I've not seen
in
> any languages (has anyone?), but is something I've wanted in several.

    Syntax definitions in Scheme are macro expanded at compile-time but
accessing the entire environment while doing so.
http://www.scheme.com/tspl2d/ and
http://www.schemers.org/Documents/Standards/R5RS/ can give you directions.
They're different from normal function definitions, but can be used as
language primitives.

>
> compiletime { .... compile time executed D ... }
>
> so to create a static array of constants
>
> Object[] foo;
> // may have to be compiletime(visible) Object[] foo;
> // might be compiletime( only ) {
> // or compiletime( eval ) {
> compiletime {
>        /// perfroms the same op as c++ [cost] Object[] = { { 1, 2 }, { 2,
> 4, } ..... }; but with more flexability
>         /// will actually create a "snap shot" in rom/code/ram of the
> compiled object mesh.
>     foo = new MyObject[5];
>     for ( int i = 0; i < 5; i++ )
>     {
>         foo[i] = new MyObject( i, myFunc( i*2 ) );
>     }
> }
>
> compiletime int min( int a, int b ) { return a < b ? a : b ; }
> would only compile if a and b are determinable at compile time, in the
> current context
>
> etc and so on
>
> it would be good if templates could have parameter arrays too
>
> template foo ( T, P )
> {
>     T myFunc( P )
>     {
>         compiletime {
>             if ( cast( ctParams[]) P )
>             {
>                     if ( !(P[0].hasoperator( +, T  ) ) ) throw new
> CompileTimeError( "Param 0 must have and operator + for foo.MyFunc to
> work" );
>                 runtime {
>                        T = compileTime P[0] + compileTime P[1];
>                 }
>             }
>             else
>                 throw CompileTimeError( "P must be a param list type " );
>         }
>     }
> }
>
> "Norbert Nemec" <nobbi_at_theorie3.physik.uni-erlangen.de@NOSPAM.COM>
wrote
> in message news:b090su$2qf4$1@digitaldaemon.com...
> > Hi there,
> >
> > just a quick and dirty suggestion:
> >
> > How about allowing "if"-"else"-blocks outside of function blocks? Of
> course,
> > the argument will have to be computable at compile time.
> >
> > This simple construct will allow several things:
> >
> > * "version" could become a boolean expression instead of a block
> statement.
> >         version(...) {
> >         }
> >   would become
> >         if(version(...)) {
> >         }
> >   with the added possibily of logic constructions.
> >
> > * Together with integers as template parameters, the data fields of a template class could be dependant on those parameters.
> >
> > The addition should be absolutely straightforward. Anyhow a few more additions would make it even more powerful:
> >
> > * Define "compile-time-value" as any value that can be deduced by the compiler.
> >
> > * Define "function without side-effects" (should be an attribute of some
> > kind)
> >
> > * Require the compiler to be able to run such functions at compile time
if
> > the arguments are compile-time-value
> >
> > Now, every expression made up of constants, basic operators and
functions
> > without side-effects are compile-time-values.
> >
> > This all taken together would perhaps give us all the compile-time-computing-power we need to put really heavy optimization
into
> > a library.
> >
> > One more detail: There should be an argument for function arguments to
be
> > specified as compile-time-values. This way, the function can only be
> called
> > with a compile-time-value provided at that point, and inside the
function,
> > the value can be used, p.e. as a template parameter.
> >
> > And a last thought: it might prove useful to provide a larger set of expressions for handling types, like comparing them, etc. so these can
be
> > used in compile-time decisions within a template library.
> >
> > Ciao,
> > Nobbi
> >
>
>


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.443 / Virus Database: 248 - Release Date: 11/1/2003


January 18, 2003
Mike Wynn wrote:
> why stop at 'if'...

Be careful on how far you take the concept. My suggestions were tiny, easy to implement extensions to the current language. Of course, one can always start dreaming, but in the end, the whole suggestion will just be to invading and complex to be realistic. D is not a language to experiment with great, new ideas, but to stay in well-known terrain and make the best out of it.

I think, my few suggestions were pretty straightforward and one can about estimate their overall effects on the overall language, but once you get beyond that point, there's the danger that many more extensions have to be added to compensate effects you never dreamed of.

Just think of templates in C++. They were a pretty revolutionary concept when they were invented, and that is the cause for most of the problems of complexity they introduce.

Ciao,
Nobbi

January 18, 2003
>
> "Mike Wynn" <mike.wynn@l8night.co.uk> escreveu na mensagem news:b09ou3$9jj$1@digitaldaemon.com...
> > this is something I have been thinking about, allowing D to be used for
> > runtime and compile time code.
> > allowing sections of code, and variables to exists at compile time (a D
> > interpreter as part of the D compile, the ast/dag could be interpreted
> > instead of compiled)
> > you can perform all the features of C preprocessor macros and inline
> > functions etc;
> > I think allowing a clear distinction between runtime and compile time
> values
> > and code may seem odd to C/C++ programmers and is a feature I've not
seen
> in
> > any languages (has anyone?), but is something I've wanted in several.
>
>     Syntax definitions in Scheme are macro expanded at compile-time but
> accessing the entire environment while doing so.
> http://www.scheme.com/tspl2d/ and
> http://www.schemers.org/Documents/Standards/R5RS/ can give you directions.
> They're different from normal function definitions, but can be used as
> language primitives.
>
I must read that more fully, but looks very much along the lines I was
thinking about.
I would like scheme if it is was not for the prolific use of brackets, and
the lack of list indexed access (all those cddar's cry out for c[2] in my
mind (wrote some gimp scripts, that was enough scheme for me)).




January 18, 2003
"Norbert Nemec" <Nobbi_at_theorie3.physik.uni-erlangen.de@NOSPAM.COM> wrote in message news:b0bdua$185s$1@digitaldaemon.com...
> Mike Wynn wrote:
> > why stop at 'if'...
>
> Be careful on how far you take the concept. My suggestions were tiny, easy to implement extensions to the current language. Of course, one can always start dreaming, but in the end, the whole suggestion will just be to invading and complex to be realistic. D is not a language to experiment with great, new ideas, but to stay in well-known terrain and make the best out of it.

the think is parts are already there
consider
bit a = (SOME_CONST < 5) || (SOMEOTHER>600);
which is infact

bit a;
if ( SOME_CONST < 5 ) { a = true;}
else if (SOMEOTHER>600){ a = true }
else { a = false; }

more fun, D has the C comma operator;
I must try out
const int a = 3;
int b;
int c = (b = (a+3)), a+5;
it does not work (not that I'm suprised)

const int a = 3;
int b;
int c = (b = a);
gives "test.d(6): non-constant expression b = 3"

but
int d = a+5;
bit e = (a<3)||(a>67);
compile fine

> I think, my few suggestions were pretty straightforward and one can about estimate their overall effects on the overall language, but once you get beyond that point, there's the danger that many more extensions have to be added to compensate effects you never dreamed of.
your right, but conditional compilation exists in D with the use of
'version( foo ) { ... }'

and I've realised that what I realy want in const functions and
constructors;
that is a function whose output is ONLY determined by its inputs and has no
effect on anything other than its locals and return value.
the same for constructors, which only effect the object, and could only call
const constructors of members.

this means that as long as the params are fully determinable at compile time, the return of the function or the consturcted object would also be fully determinable at compile time.


> Just think of templates in C++. They were a pretty revolutionary concept when they were invented, and that is the cause for most of the problems of complexity they introduce.

and for all their faults and  complex probems they introduce they are now a standard feature that people expect a new language to have.




« First   ‹ Prev
1 2