Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 15, 2005 Static Const (Compile-Time) Functions | ||||
---|---|---|---|---|
| ||||
Hi there, In the vein of the const parameter discussion, I would like to introduce this topic. Since some form of const is coming, it would be great if it was made to support static const functions at some point. Anyway, these functions run at compile time. They can return a true const which would be identical to a const literal. I don't think they exist in C++, but C++ does have plain const functions. This is not the same thing (it's better). This is essentially an extremely safe, full-featured macro. For example: # static const int square(const int num) { # return (num * num); # } # # static const char tolower(const char c) { # return ((c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c); # } # # const int foo = square(5); # // foo = 25 at compile-time. # const char bar = tolower('B'); # // bar = 'b' at compile-time. I'm not suggesting any specific syntax, just the general idea. Is this something that could be done? Some benefits: - It doesn't add _anything_ to the runtime. - Doesn't require any runtime or library support. - Can make your code faster and smaller by shifting some processing to compile-time. - No new concepts or keywords needed. Functions and consts already exist in D. This simply combines the two. - Can make your code cleaner and more readable without incurring any function-call penalties. - You get the best of both worlds: macro zero-cost efficiency, plus complete function safety and (hehehe) functionality. Thanks, --AJG. |
July 15, 2005 Re: Static Const (Compile-Time) Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to AJG | "AJG" <AJG_member@pathlink.com> wrote in message news:db8r7q$2k3u$1@digitaldaemon.com... Something like this can already be done with templates, although with a more.. obtuse syntax. template square(T, T value) { const T square=(value*value); } void main() { int x=square!(int,5); writefln(x); } Since the template is expanded at compile-time, the constant folds, and x=25. The square!() template can also be used to initialize global or const members. A more function-esque syntax would be welcome, though. |
July 16, 2005 Re: Static Const (Compile-Time) Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Hm... interesting. I didn't know you could do that. Thanks for the suggestion. The problem is (other than being template-syntax-clunky), that you are still limited to one initialization. In essense you are just moving it somewhere else. I'll definitely use it, but it'd be great to have real const functions with normal syntax and features. Walter, before I get my hopes up, is this even technically possible? --AJG. In article <db8ssg$2mjj$1@digitaldaemon.com>, Jarrett Billingsley says... > >"AJG" <AJG_member@pathlink.com> wrote in message news:db8r7q$2k3u$1@digitaldaemon.com... > >Something like this can already be done with templates, although with a more.. obtuse syntax. > >template square(T, T value) >{ > const T square=(value*value); >} > >void main() >{ > int x=square!(int,5); > writefln(x); >} > >Since the template is expanded at compile-time, the constant folds, and x=25. The square!() template can also be used to initialize global or const members. > >A more function-esque syntax would be welcome, though. > > |
July 16, 2005 Re: Static Const (Compile-Time) Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to AJG | "AJG" <AJG_member@pathlink.com> wrote in message news:db9o29$gij$1@digitaldaemon.com... > The problem is (other than being template-syntax-clunky), that you are > still > limited to one initialization. In essense you are just moving it somewhere > else. Nope. You can use it as many times as you'd like. I use this weird form of templates to replace function-style macros from C headers that are used to initialize module-level variables or constants. const int x=square!(int,5); const int y=square!(int,10); const float z=square!(float,3.14159); > I'll definitely use it, but it'd be great to have real const functions > with > normal syntax and features. Walter, before I get my hopes up, is this even > technically possible? > > --AJG. > > In article <db8ssg$2mjj$1@digitaldaemon.com>, Jarrett Billingsley says... >> >>"AJG" <AJG_member@pathlink.com> wrote in message news:db8r7q$2k3u$1@digitaldaemon.com... >> >>Something like this can already be done with templates, although with a more.. obtuse syntax. >> >>template square(T, T value) >>{ >> const T square=(value*value); >>} >> >>void main() >>{ >> int x=square!(int,5); >> writefln(x); >>} >> >>Since the template is expanded at compile-time, the constant folds, and >>x=25. The square!() template can also be used to initialize global or >>const >>members. >> >>A more function-esque syntax would be welcome, though. >> >> > > |
July 16, 2005 Re: Static Const (Compile-Time) Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Hi, >"AJG" <AJG_member@pathlink.com> wrote in message news:db9o29$gij$1@digitaldaemon.com... >> The problem is (other than being template-syntax-clunky), that you are >> still >> limited to one initialization. In essense you are just moving it somewhere >> else. > >Nope. You can use it as many times as you'd like. I use this weird form of templates to replace function-style macros from C headers that are used to initialize module-level variables or constants. No, I meant that the template itself is just one initialization. There is no other useful construct that you could use (e.g. a static if). I mean, the whole thing has to be one single assignment expression, right? --AJG. >const int x=square!(int,5); >const int y=square!(int,10); >const float z=square!(float,3.14159); > >> I'll definitely use it, but it'd be great to have real const functions >> with >> normal syntax and features. Walter, before I get my hopes up, is this even >> technically possible? >> >> --AJG. >> >> In article <db8ssg$2mjj$1@digitaldaemon.com>, Jarrett Billingsley says... >>> >>>"AJG" <AJG_member@pathlink.com> wrote in message news:db8r7q$2k3u$1@digitaldaemon.com... >>> >>>Something like this can already be done with templates, although with a more.. obtuse syntax. >>> >>>template square(T, T value) >>>{ >>> const T square=(value*value); >>>} >>> >>>void main() >>>{ >>> int x=square!(int,5); >>> writefln(x); >>>} >>> >>>Since the template is expanded at compile-time, the constant folds, and >>>x=25. The square!() template can also be used to initialize global or >>>const >>>members. >>> >>>A more function-esque syntax would be welcome, though. >>> >>> >> >> > > |
July 16, 2005 Re: Static Const (Compile-Time) Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | "Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote in message news:db8ssg$2mjj$1@digitaldaemon.com... > "AJG" <AJG_member@pathlink.com> wrote in message news:db8r7q$2k3u$1@digitaldaemon.com... > > Something like this can already be done with templates, although with a more.. obtuse syntax. > > template square(T, T value) > { > const T square=(value*value); > } > > void main() > { > int x=square!(int,5); > writefln(x); > } > > Since the template is expanded at compile-time, the constant folds, and x=25. The square!() template can also be used to initialize global or const members. > > A more function-esque syntax would be welcome, though. > Nice idea! |
July 17, 2005 Re: Static Const (Compile-Time) Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Fedoniouk | "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:dba2cb$nu6$1@digitaldaemon.com... > Nice idea! Thank Andy Friesen, he's the one who showed me how to do this :) Templates are weird. |
July 17, 2005 Re: Static Const (Compile-Time) Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to AJG | "AJG" <AJG_member@pathlink.com> wrote in message news:dba07g$ll2$1@digitaldaemon.com... > No, I meant that the template itself is just one initialization. There is > no > other useful construct that you could use (e.g. a static if). I mean, the > whole > thing has to be one single assignment expression, right? Ah, yes, I see what you mean. You wouldn't be able to, say, calculate a factorial with this (though that can strangely be done with templates as well..). I'm not sure how complex it would be, however, to evaluate compile-time functions, as they'd have to be compiled and run _during_ the compilation process. I don't know if that's even possible. |
July 17, 2005 Re: Static Const (Compile-Time) Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Hi, >Ah, yes, I see what you mean. You wouldn't be able to, say, calculate a factorial with this (though that can strangely be done with templates as well..). Yeah, I'm finding out more and more exotic uses for templates... this would all get much better if implicit instantiation were possible. >I'm not sure how complex it would be, however, to evaluate compile-time functions, as they'd have to be compiled and run _during_ the compilation process. I don't know if that's even possible. I have a feeling this is related to the halting problem. However, I don't think it's hopeless. I think you would only have to deal with a small, limited subset of all possible inputs (namely, constant inputs). Can anyone who knows about this pitch in? Thanks, --AJG. |
July 18, 2005 Re: Static Const (Compile-Time) Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to AJG | In article <dbeh1t$12p4$1@digitaldaemon.com>, AJG says... .. >Yeah, I'm finding out more and more exotic uses for templates... this would all get much better if implicit instantiation were possible. .. >--AJG. > > While we are whishing, how about implicit instantiation defining the return type of a function as a function of the inputs. That would allow something like this: #// a Unit (m, km, kg, lb, etc.) safe arithmetic type # #template Unit(T, int d, int m, int t) #{ # typedef T Unit; # # Unit!(T,d,m,t).Unit opAdd(Unit!(T,d,m,t).Unit v1, Unit!(T,d,m,t).Unit v2) # { # return csat(T)v1 + cast(T)v2; # } # Unit!(T,d,m,t).Unit opSub(Unit!(T,d,m,t).Unit v1, Unit!(T,d,m,t).Unit v2) # { # return cast(T)v1 - cast(T)v2; # } # # Unit!(T,d1+d2,m1+m2,t1+t2).Unit opMul(Unit!(T,d1,m1,t1).Unit v1, Unit!(T,d2,m2,t2).Unit v2) # { # return cast(T)v1 * cast(T)v2; # } # # Unit!(T,d1-d2,m1-m2,t1-t2).Unit opMul(Unit!(T,d1,m1,t1).Unit v1, Unit!(T,d2,m2,t2).Unit v2) # { # return cast(T)v1 / cast(T)v2; # } #} I know, I know, implementing this would likely be a royal mess. One possible means to simplify it would be to require a list of allowed instantiations e.g. # instance Unit !(real, 1, 0, 0) ; // meters # instance Unit !(real, 0, 1, 0) ; // kg # instance Unit !(real, 0, 0, 1) ; // seconds # instance Unit !(real, 1, 0, -1) ; // m/s # // etc… BCS p.s One quirk of the above example is that it can optimize to the same code you would get with using just reals. |
Copyright © 1999-2021 by the D Language Foundation