Thread overview | |||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 08, 2002 computing compile-time constants | ||||
---|---|---|---|---|
| ||||
Sometimes you need to have compile time constants (an enum perhaps.) The situation I'm running into is D3D's definition of its HRESULT error codes. It uses a macro MAKE_D3DHRESULT to do the computation. Aside from expanding it out manually I don't think there's any way in D to have a reusable function-style package that generates compile time constants if given compile time constants as inputs. Surely the compiler could check when it expects a compile time constant and instead encounters a function call, check if the function is inlineable and the arguments are compile-time constants, and if so evaluates the function at compile time? Or is there some other way this can be automated? I'd hate to duplicate that much code using copy'n'paste. Copy'n'paste coding is the opposite of refactoring and is A Bad Thing. Sean |
June 09, 2002 Re: computing compile-time constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | Something like: int f(int n) = n * 4 + 1; Might work. It's like shortcut function syntax that combines a computation with a return of result and AFAIK so long as we don't allow it to call real functions, can be evaluated at compile time. the above would be roughly equivalent to: int f(int n) { return n * 4 + 1; } So mostly just syntax sugar I guess. The real problem is turning all possible arbitrary compile-time constant expressions into constants at compile time, even in say debug builds. It might also be interesting to have "non constant" constant expressions... more like equivalence. Such as: double price_of_oil = 24.99; double gasoline_scale_factor = 24.99; let double price_of_gasoline = price_of_oil * gasoline_scale_factor; This is also a form of syntax sugar for parameterless function calls. But this form would be used just like a variable except you can't store into it, and reads evaluate the function. Sean "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:adu2u3$1gv1$1@digitaldaemon.com... > Sometimes you need to have compile time constants (an enum perhaps.) The situation I'm running into is D3D's definition of its HRESULT error codes. It uses a macro MAKE_D3DHRESULT to do the computation. Aside from expanding > it out manually I don't think there's any way in D to have a reusable function-style package that generates compile time constants if given compile time constants as inputs. > > Surely the compiler could check when it expects a compile time constant and > instead encounters a function call, check if the function is inlineable and > the arguments are compile-time constants, and if so evaluates the function at compile time? > > Or is there some other way this can be automated? I'd hate to duplicate that much code using copy'n'paste. Copy'n'paste coding is the opposite of refactoring and is A Bad Thing. > > Sean > > |
June 09, 2002 Re: computing compile-time constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@earthlink.net> escribió en el mensaje news:adu6b9$1kh9$1@digitaldaemon.com... > Something like: > > int f(int n) = n * 4 + 1; > > Might work. It's like shortcut function syntax that combines a computation > with a return of result and AFAIK so long as we don't allow it to call real > functions, can be evaluated at compile time. > > the above would be roughly equivalent to: > > int f(int n) { return n * 4 + 1; } > I don't know if this could work much. And I say this from experience: in old releases of Basic (gwbasic, qb, etc.) there was something like this: def fnfoo(n)=n*4+1 and it was a function (since old Basics didn't have procedures, functions, subroutines, etc.). Eventually it was replaced (and eventually eliminated) by the (normal) syntax: function foo (n as integer) as integer ... end function now, many criticize Basic, but in all the mistakes that Basic has (in programming style I mean), they changed that syntax for good. They saw that other programming languages didn't work that way for a reason, so it wasn't a good idea to keep. So adding it to D, IMHO, would be like returning to the days when you had to put a line in every single line. |
June 10, 2002 Re: computing compile-time constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:adu6b9$1kh9$1@digitaldaemon.com... > Something like: > > int f(int n) = n * 4 + 1; > > Might work. It's like shortcut function syntax that combines a computation > with a return of result and AFAIK so long as we don't allow it to call real > functions, can be evaluated at compile time. > > the above would be roughly equivalent to: > > int f(int n) { return n * 4 + 1; } Maybe use the const attribute? I think it is a good idea, as long as such declaration would be _restricted_ to constant arguments. This would make it possible to do things like: const int f(int n) = n * 4 + 1; const int a = 3; const int b = f(a); Such a code cannot be written using inline functions... |
June 11, 2002 Re: computing compile-time constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel Minayev | "Pavel Minayev" <evilone@omen.ru> wrote in message news:ae354f$lqc$1@digitaldaemon.com... > "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:adu6b9$1kh9$1@digitaldaemon.com... > > > Something like: > > > > int f(int n) = n * 4 + 1; > > > > Might work. It's like shortcut function syntax that combines a > computation > > with a return of result and AFAIK so long as we don't allow it to call > real > > functions, can be evaluated at compile time. > > > > the above would be roughly equivalent to: > > > > int f(int n) { return n * 4 + 1; } > > Maybe use the const attribute? > > I think it is a good idea, as long as such declaration would be _restricted_ > to constant arguments. This would make it possible to do things like: > > const int f(int n) = n * 4 + 1; > const int a = 3; > const int b = f(a); > > Such a code cannot be written using inline functions... Yes, that should work. We definitely need something like this. It's one of the few uses of macros D hasn't found a better replacement for yet. Sean |
June 11, 2002 Re: computing compile-time constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | It gets my vote "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:ae41ms$1i0o$1@digitaldaemon.com... > "Pavel Minayev" <evilone@omen.ru> wrote in message news:ae354f$lqc$1@digitaldaemon.com... > > "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:adu6b9$1kh9$1@digitaldaemon.com... > > > > > Something like: > > > > > > int f(int n) = n * 4 + 1; > > > > > > Might work. It's like shortcut function syntax that combines a > > computation > > > with a return of result and AFAIK so long as we don't allow it to call > > real > > > functions, can be evaluated at compile time. > > > > > > the above would be roughly equivalent to: > > > > > > int f(int n) { return n * 4 + 1; } > > > > Maybe use the const attribute? > > > > I think it is a good idea, as long as such declaration would be > _restricted_ > > to constant arguments. This would make it possible to do things like: > > > > const int f(int n) = n * 4 + 1; > > const int a = 3; > > const int b = f(a); > > > > Such a code cannot be written using inline functions... > > Yes, that should work. We definitely need something like this. It's one of > the few uses of macros D hasn't found a better replacement for yet. > > Sean > > |
June 11, 2002 Re: computing compile-time constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:adu6b9$1kh9$1@digitaldaemon.com... > Something like: > > int f(int n) = n * 4 + 1; > > Might work. It's like shortcut function syntax that combines a computation > with a return of result and AFAIK so long as we don't allow it to call real > functions, can be evaluated at compile time. > > the above would be roughly equivalent to: > > int f(int n) { return n * 4 + 1; } > > So mostly just syntax sugar I guess. The real problem is turning all possible arbitrary compile-time constant expressions into constants at compile time, even in say debug builds. > > It might also be interesting to have "non constant" constant expressions... > more like equivalence. Such as: > > double price_of_oil = 24.99; > double gasoline_scale_factor = 24.99; > let double price_of_gasoline = price_of_oil * gasoline_scale_factor; > > This is also a form of syntax sugar for parameterless function calls. But this form would be used just like a variable except you can't store into it, > and reads evaluate the function. Hmm... Well, it seems to me this is actually syntax suggar for preprocessing! #define f(n) ((n)*4+1) #define price_of_gasoline ((price_of_oil) * (gasoline_scale_factor)) The syntax is different but the same effect. Or was it the syntax, that was problematic with the C preprocessor? I don't think so. Actually I love compile time computations, so I think we will need something to fill the gap left by the absence of the preprocessor. An other idea come up with that price_of_gasoline: GLOBAL PROPERTIES (tada!). So you can have: temperature = 10; int t = temperature; While temperature is actually a global property with a global gettor and/or settor function. THAT seems useful to me. Sandor |
June 11, 2002 Re: computing compile-time constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sandor Hojtsy | "Sandor Hojtsy" <hojtsy@index.hu> wrote in message news:ae50gr$2i9o$1@digitaldaemon.com... > Hmm... > Well, it seems to me this is actually syntax suggar for preprocessing! > #define f(n) ((n)*4+1) > #define price_of_gasoline ((price_of_oil) * (gasoline_scale_factor)) > The syntax is different but the same effect. There _is_ a difference: // C++ #define f(n) n * n f(n++) == n++ * n++; // possibly D int f(int n) = n * n; f(n++) == (n++, n * n) n++ only gets computed once. Besides, this solution is typesafe: you should pass an int, and you cannot pass a string or even some keyword. |
June 11, 2002 Re: computing compile-time constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel Minayev | A nice side effect of this is that you get *forced* inlining? Or would you? Sean "Pavel Minayev" <evilone@omen.ru> wrote in message news:ae57ei$2ptd$1@digitaldaemon.com... > "Sandor Hojtsy" <hojtsy@index.hu> wrote in message news:ae50gr$2i9o$1@digitaldaemon.com... > > > Hmm... > > Well, it seems to me this is actually syntax suggar for preprocessing! > > #define f(n) ((n)*4+1) > > #define price_of_gasoline ((price_of_oil) * (gasoline_scale_factor)) > > The syntax is different but the same effect. > > There _is_ a difference: > > // C++ > #define f(n) n * n > f(n++) == n++ * n++; > > // possibly D > int f(int n) = n * n; > f(n++) == (n++, n * n) > > n++ only gets computed once. Besides, this solution is typesafe: you should pass an int, and you cannot pass a string or even some keyword. |
June 12, 2002 Re: computing compile-time constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:ae5ghn$1ut$1@digitaldaemon.com... > A nice side effect of this is that you get *forced* inlining? Or would you? Yes, absolutely. Since function can only consist of expression, it can always be inlined. In those cases where all arguments are const, the expression is simply calculated and the result is inserted into the code, also making it possible to be used in const expression. If arguments are variable, a code to calculate the expression would be generated: const word lo(dword d) = d & 0xFFFF; const word hi(dword d) = d >> 16; const int a = 12345678; const int b = hi(a); const int c = lo(a); int main() { dword x; scanf("%d", &x); printf("%d %d\n", hi(x), lo(x)); return 0; } What do you think of all this, Walter? |
Copyright © 1999-2021 by the D Language Foundation