digitalmars.D - define should be the keyword for manifest constants
- Steven Schveighoffer (15/15) Dec 13 2007 Seriously. Are we too concerned about stigmas to not use the absolute b...
- Gilles G. (3/25) Dec 13 2007 "define" makes no sense if you want to declare a "const" member function...
- Jason House (11/13) Dec 13 2007 I have absolutely no problem with different logical things using differe...
- Steven Schveighoffer (27/52) Dec 13 2007 define int x = 0;
- Janice Caron (16/18) Dec 13 2007 You're thinking old-school. D is new-school. Imports don't just import
- guslay (10/34) Dec 13 2007 1 - Code:
- Janice Caron (4/5) Dec 13 2007 Now you're stating the obvious! :-)
- =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= (24/66) Dec 13 2007 -----BEGIN PGP SIGNED MESSAGE-----
- Steven Schveighoffer (12/23) Dec 13 2007 OK, so what is the big deal then? Why do we need manifest constants? I...
- Steven Schveighoffer (9/12) Dec 13 2007 I was not talking about using define instead of pure for *everything* th...
- Christopher Wright (15/32) Dec 13 2007 Instead of goto, let's use comefrom:
- Steven Schveighoffer (4/11) Dec 13 2007 Oh yeah :) It was *obvious* that when I said 'use another keyword', I m...
- Russell Lewis (9/9) Dec 13 2007 I thought about suggesting this, but what turned me off to it was this
- Bill Baxter (9/18) Dec 13 2007 That may be their first guess as to what it does, but it doesn't seem
- Russell Lewis (11/31) Dec 13 2007 I'm certainly not one who argues that we should take things from C/C++
- Derek Parnell (7/39) Dec 13 2007 Right ... like static, const, final, int, long, struct ... all used in
- Russell Lewis (3/38) Dec 13 2007 True. But we can make any new features the "right" way (if you guys
- Steven Schveighoffer (4/9) Dec 14 2007 If I'm not mistaken, pure is a keyword in gcc already, and does not mean...
- Vladimir Panteleev (11/28) Dec 13 2007 s
- Steven Schveighoffer (8/17) Dec 13 2007 Too bad, so sad. If you want something that acts exactly like C, use C....
Seriously. Are we too concerned about stigmas to not use the absolute best word for defining a constant? Even in the description of a manifest constant, it will be something like: to *define* a manifest constant, use enum If you use *define* you don't even need an explanation! If you are concerned about people not liking define because it *looks* too much like C's #define, then lets also drop goto (because C's is just too error prone), class (because there are slicing problems in C++, and we don't want people to think they still exist in D), struct (because C++'s is just like class, so people will think D structs and classes are the same), etc. If you are concerned about adding a new keyword, please, all coders who have used the symbol define, please respond to this thread, and we'll send you a handy script that will update your code to use another keyword of your choice. Only $6.95 shipping and handling. -Steve
Dec 13 2007
"define" makes no sense if you want to declare a "const" member function. It could be of great use for manifest constant, but you'd still have to find a word for other const cases... Steven Schveighoffer Wrote:Seriously. Are we too concerned about stigmas to not use the absolute best word for defining a constant? Even in the description of a manifest constant, it will be something like: to *define* a manifest constant, use enum If you use *define* you don't even need an explanation! If you are concerned about people not liking define because it *looks* too much like C's #define, then lets also drop goto (because C's is just too error prone), class (because there are slicing problems in C++, and we don't want people to think they still exist in D), struct (because C++'s is just like class, so people will think D structs and classes are the same), etc. If you are concerned about adding a new keyword, please, all coders who have used the symbol define, please respond to this thread, and we'll send you a handy script that will update your code to use another keyword of your choice. Only $6.95 shipping and handling. -Steve
Dec 13 2007
Gilles G. Wrote:"define" makes no sense if you want to declare a "const" member function. It could be of great use for manifest constant, but you'd still have to find a word for other const cases...I have absolutely no problem with different logical things using different keywords. IMHO, shoe-horning keywords to fit a new and unanticipated case is not desirable. I'd hate to see manifest constants without types. I'd probably vote against define simply because I associate it with a loss of type info (probably the influence of C) I'm not yet convinced in what cases manifest constants are important. I think most headers defining integral constants should be enums instead of (C) #define. That's probably one reason the enum keyword gained some traction. If manifest constants go beyond integral types, is it better to extend enums to contain more types than just integer? Or is it better to use another keyword? I kind of like the pure proposal because it does fit in with the concept of pure functions. With the whole const vs. invariant thing, even const as a keyword doesn't make a whole lot of sense (it'd really be invariant). Of course, I wonder why the compiler can't just determine which constants should be manifest and which need allocation. It could very well be that we just say define manifest constants like any other constants and then *if* you don't trust the compiler to get it right, use an attribute to force the compiler in the right direction. manifest{ const int A = ...; const int B = ...; const int C = ...; ... }
Dec 13 2007
"Jason House" wroteGilles G. Wrote:define int x = 0; What's wrong with that?"define" makes no sense if you want to declare a "const" member function. It could be of great use for manifest constant, but you'd still have to find a word for other const cases...I have absolutely no problem with different logical things using different keywords. IMHO, shoe-horning keywords to fit a new and unanticipated case is not desirable. I'd hate to see manifest constants without types. I'd probably vote against define simply because I associate it with a loss of type info (probably the influence of C)I'm not yet convinced in what cases manifest constants are important. I think most headers defining integral constants should be enums instead of (C) #define. That's probably one reason the enum keyword gained some traction.They are important because they occupy code space if they are not used. For example, if you have 10,000 constants defined in a module, but you only need 10 of them, then your code now has 10,000 constants in it, whereas if you define 10,000 manifest constants, only the ones you use are included because they are inlined in the code.If manifest constants go beyond integral types, is it better to extend enums to contain more types than just integer? Or is it better to use another keyword?enum does not capture what we are trying to do. We are trying to make an instance of a certain type into a manifest constant, not define a new type.I kind of like the pure proposal because it does fit in with the concept of pure functions.I like pure more than enum, but the issue I have with pure is that a pure struct that has methods would imply only pure methods could be called. Of course, having a manifest constant struct would mean there would be no address to pass to a member function, but people have suggested that one can make a copy of the struct on the stack and then call the method on that. In any case, pure would be acceptable to me, but it really doesn't make any intuitive sense. If you had never heard of functionali programming and pure functions, and you read a D file that had: pure x = 0; What would you think pure means?With the whole const vs. invariant thing, even const as a keyword doesn't make a whole lot of sense (it'd really be invariant). Of course, I wonder why the compiler can't just determine which constants should be manifest and which need allocation. It could very well be that we just say define manifest constants like any other constants and then *if* you don't trust the compiler to get it right, use an attribute to force the compiler in the right direction.How would the compiler know when compiling a module with a constant whether some other module is going to take the address of that constant? Plus it is nice to be able to FORCE the compiler to say "you can't use this like a non-manifest constant" But I do agree that it would be nice if the compiler could optimize when possible. -Steve
Dec 13 2007
On 12/13/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:How would the compiler know when compiling a module with a constant whether some other module is going to take the address of that constant?You're thinking old-school. D is new-school. Imports don't just import symbols, they import abstract symbol trees. Saying "How would the compiler know when compiling a module with a constant whether some other module is going to take the address of that constant?" is like saying "How would the compiler know whether a template needs to be instantiated?". The point is, it doesn't need to - it just exports the AST. In fact, you can mimic #define pi=3.14159 as template pi { const real pi = 3.14159 } in one module, and it will take up zero storage space until someone (possibly in another module) instantiates it with something like real x = pi!; Not that I'm suggesting that we use templates for compile-time constants! (That would be silly). But the fact that we can do it at all shows that it can be done.
Dec 13 2007
Janice Caron Wrote:On 12/13/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:1 - Code: const real Pi = 3.14; // or the template version. //... real x = Pi; 2 - Compiler: Pi is const. Replace x dynamic initialisation with static init. Becomes real x = 3.14; 3 - All value assigment of Pi have been trivialy optimized away. Pi is not used anymore. However, if Pi is addressable, someone in another module might have taken a reference to Pi. The compiler cannot know. Therefore, Pi cannot be optimized way. This is what take storage. If Pi is "enum"-like, it's a symbol that is just a placeholder for a value. After its value has been propagated, is not required anymore. It does not take storage.How would the compiler know when compiling a module with a constant whether some other module is going to take the address of that constant?You're thinking old-school. D is new-school. Imports don't just import symbols, they import abstract symbol trees. Saying "How would the compiler know when compiling a module with a constant whether some other module is going to take the address of that constant?" is like saying "How would the compiler know whether a template needs to be instantiated?". The point is, it doesn't need to - it just exports the AST. In fact, you can mimic #define pi=3.14159 as template pi { const real pi = 3.14159 } in one module, and it will take up zero storage space until someone (possibly in another module) instantiates it with something like real x = pi!; Not that I'm suggesting that we use templates for compile-time constants! (That would be silly). But the fact that we can do it at all shows that it can be done.
Dec 13 2007
On 12/13/07, guslay <guslay gmail.com> wrote:If Pi is "enum"-like, it's a symbol that is just a placeholder for a value. After its value has been propagated, is not required anymore. It does not take storage.Now you're stating the obvious! :-) (And in such a patient, explanatory way, too!) I really hope you're not imagining that anyone on this thread doesn't know that.
Dec 13 2007
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 guslay wrote:Janice Caron Wrote:cannotOn 12/13/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:1 - Code: const real Pi = 3.14; // or the template version. //... real x = Pi; 2 - Compiler: Pi is const. Replace x dynamic initialisation with static init. Becomes real x = 3.14; 3 - All value assigment of Pi have been trivialy optimized away. Pi is not used anymore. However, if Pi is addressable, someone in another module might have taken a reference to Pi. The compiler cannot know. Therefore, PiHow would the compiler know when compiling a module with a constant whether some other module is going to take the address of that constant?You're thinking old-school. D is new-school. Imports don't just import symbols, they import abstract symbol trees. Saying "How would the compiler know when compiling a module with a constant whether some other module is going to take the address of that constant?" is like saying "How would the compiler know whether a template needs to be instantiated?". The point is, it doesn't need to - it just exports the AST. In fact, you can mimic #define pi=3.14159 as template pi { const real pi = 3.14159 } in one module, and it will take up zero storage space until someone (possibly in another module) instantiates it with something like real x = pi!; Not that I'm suggesting that we use templates for compile-time constants! (That would be silly). But the fact that we can do it at all shows that it can be done.be optimized way. This is what take storage.Yes it can. When the compiler compiles a given module, if this module does not take the address of Pi, then the compiler does not allocate any storage for it. If this module does take the address of Pi, then the compiler allocates storage in a special section. Then, when the linker creates the final executable, it can combine all allocations for Pi into a single one. This is actually what already happens for template functions (and now that I think about it, it's probably what happens for Janice's Pi template too... Jerome - -- +------------------------- Jerome M. BERGER ---------------------+ | mailto:jeberger free.fr | ICQ: 238062172 | | http://jeberger.free.fr/ | Jabber: jeberger jabber.fr | +---------------------------------+------------------------------+ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFHYYu0d0kWM4JG3k8RAkDsAKCejovzcBcqPEBae0HCySXDbLYx9QCgg5lM rCU59t/Lr690482Um2+zwxg= =NLyG -----END PGP SIGNATURE-----
Dec 13 2007
"Janice Caron" wroteOn 12/13/07, Steven Schveighoffer wrote:OK, so what is the big deal then? Why do we need manifest constants? I assume this is a problem because we are talking about fixing it. I was assuming that Jason's proposed solution (the compiler decides when to have manifest constants and when to have addressable constants) was impossible, and that the reason it is good to have manifest constants is because otherwise the compiler creates space for all non-manifest constants. Is this not the case? If not, why have a difference between manifest constant declarations and normal constant declarations? And if I'm not mistaken, import imports source code, just like #include included header files... -SteveHow would the compiler know when compiling a module with a constant whether some other module is going to take the address of that constant?You're thinking old-school. D is new-school. Imports don't just import symbols, they import abstract symbol trees. Saying "How would the compiler know when compiling a module with a constant whether some other module is going to take the address of that constant?" is like saying "How would the compiler know whether a template needs to be instantiated?". The point is, it doesn't need to - it just exports the AST.
Dec 13 2007
"Gilles G." wrote"define" makes no sense if you want to declare a "const" member function.I was not talking about using define instead of pure for *everything* that pure is for. Use pure for function declarations. Use define for manifest constants.It could be of great use for manifest constant, but you'd still have to find a word for other const cases...what's wrong with the current keywords? const, invariant, pure, etc? I'm talking about having define *only* for manifest constants, and nothing else. Every once in a while, there comes a time where a new keyword not only makes sense, but is the only true fit. I believe this is one of those times. -Steve
Dec 13 2007
Steven Schveighoffer wrote:Seriously. Are we too concerned about stigmas to not use the absolute best word for defining a constant? Even in the description of a manifest constant, it will be something like: to *define* a manifest constant, use enum If you use *define* you don't even need an explanation! If you are concerned about people not liking define because it *looks* too much like C's #define, then lets also drop goto (because C's is just too error prone), class (because there are slicing problems in C++, and we don't want people to think they still exist in D), struct (because C++'s is just like class, so people will think D structs and classes are the same), etc.Instead of goto, let's use comefrom: foreach (a; collection) { if (a.someproperty) { found: } } throw new Exception("didn't find it!"); comefrom found; Instead of class, caste. Instead of struct, skel (short for skeleton). 'new' becomes 'makemea': auto sandwich = makemea Sandwich;If you are concerned about adding a new keyword, please, all coders who have used the symbol define, please respond to this thread, and we'll send you a handy script that will update your code to use another keyword of your choice. Only $6.95 shipping and handling.Replacing variables and types that collide with keywords using ANOTHER keyword? That's just begging the question!
Dec 13 2007
"Christopher Wright" wroteSteven Schveighoffer wrote:Oh yeah :) It was *obvious* that when I said 'use another keyword', I meant 'use another symbol'. I was just testing you to see if you'd catch that. -SteveIf you are concerned about adding a new keyword, please, all coders who have used the symbol define, please respond to this thread, and we'll send you a handy script that will update your code to use another keyword of your choice. Only $6.95 shipping and handling.Replacing variables and types that collide with keywords using ANOTHER keyword? That's just begging the question!
Dec 13 2007
I thought about suggesting this, but what turned me off to it was this declaration: define int x = some_compile_time_func(); A C/C++ programmer will probably think of this as a #define-style substitution, which means that he will expect the function to run every time that he uses the constant. However, what we are trying to declare is a manifest constant. It seemed like it would introduce confusion. Just my $.02, Russ
Dec 13 2007
Russell Lewis wrote:I thought about suggesting this, but what turned me off to it was this declaration: define int x = some_compile_time_func(); A C/C++ programmer will probably think of this as a #define-style substitution, which means that he will expect the function to run every time that he uses the constant. However, what we are trying to declare is a manifest constant. It seemed like it would introduce confusion.That may be their first guess as to what it does, but it doesn't seem like it would be difficult to relieve oneself of that misconception. And in any case, the only time the above would work is if some_compile_time_function() really is a compile time function. So it doesn't really matter if the user wants to think of it as evaluating every time it's used or just once. That's the whole point of compile_time / pure functions. No side effects and context doesn't matter. --bb
Dec 13 2007
Bill Baxter wrote:Russell Lewis wrote:I'm certainly not one who argues that we should take things from C/C++ without reconsidering them! :) I am just of the opinion that if we have some other good choice for the keyword ("pure"), it is desirable not to cause confusion. IMHO, it's better for a C++ programmer to say "I've never seen that keyword, let me look up what it does," than to say "I know what that does" - and be wrong. Yes, you can re-teach them. But if the keyword is unfamiliar, then you re-teach them the *first* time that they see it, not ages later when they stumble upon a subtle bug. RussI thought about suggesting this, but what turned me off to it was this declaration: define int x = some_compile_time_func(); A C/C++ programmer will probably think of this as a #define-style substitution, which means that he will expect the function to run every time that he uses the constant. However, what we are trying to declare is a manifest constant. It seemed like it would introduce confusion.That may be their first guess as to what it does, but it doesn't seem like it would be difficult to relieve oneself of that misconception. And in any case, the only time the above would work is if some_compile_time_function() really is a compile time function. So it doesn't really matter if the user wants to think of it as evaluating every time it's used or just once. That's the whole point of compile_time / pure functions. No side effects and context doesn't matter.
Dec 13 2007
On Thu, 13 Dec 2007 15:13:11 -0700, Russell Lewis wrote:Bill Baxter wrote:Right ... like static, const, final, int, long, struct ... all used in C/C++ but not in quite the same way. -- Derek Parnell Melbourne, Australia skype: derek.j.parnellRussell Lewis wrote:I'm certainly not one who argues that we should take things from C/C++ without reconsidering them! :) I am just of the opinion that if we have some other good choice for the keyword ("pure"), it is desirable not to cause confusion. IMHO, it's better for a C++ programmer to say "I've never seen that keyword, let me look up what it does," than to say "I know what that does" - and be wrong. Yes, you can re-teach them. But if the keyword is unfamiliar, then you re-teach them the *first* time that they see it, not ages later when they stumble upon a subtle bug.I thought about suggesting this, but what turned me off to it was this declaration: define int x = some_compile_time_func(); A C/C++ programmer will probably think of this as a #define-style substitution, which means that he will expect the function to run every time that he uses the constant. However, what we are trying to declare is a manifest constant. It seemed like it would introduce confusion.That may be their first guess as to what it does, but it doesn't seem like it would be difficult to relieve oneself of that misconception. And in any case, the only time the above would work is if some_compile_time_function() really is a compile time function. So it doesn't really matter if the user wants to think of it as evaluating every time it's used or just once. That's the whole point of compile_time / pure functions. No side effects and context doesn't matter.
Dec 13 2007
Derek Parnell wrote:On Thu, 13 Dec 2007 15:13:11 -0700, Russell Lewis wrote:True. But we can make any new features the "right" way (if you guys agree that my way is the "right" way, of course!) :)Bill Baxter wrote:Right ... like static, const, final, int, long, struct ... all used in C/C++ but not in quite the same way.Russell Lewis wrote:I'm certainly not one who argues that we should take things from C/C++ without reconsidering them! :) I am just of the opinion that if we have some other good choice for the keyword ("pure"), it is desirable not to cause confusion. IMHO, it's better for a C++ programmer to say "I've never seen that keyword, let me look up what it does," than to say "I know what that does" - and be wrong. Yes, you can re-teach them. But if the keyword is unfamiliar, then you re-teach them the *first* time that they see it, not ages later when they stumble upon a subtle bug.I thought about suggesting this, but what turned me off to it was this declaration: define int x = some_compile_time_func(); A C/C++ programmer will probably think of this as a #define-style substitution, which means that he will expect the function to run every time that he uses the constant. However, what we are trying to declare is a manifest constant. It seemed like it would introduce confusion.That may be their first guess as to what it does, but it doesn't seem like it would be difficult to relieve oneself of that misconception. And in any case, the only time the above would work is if some_compile_time_function() really is a compile time function. So it doesn't really matter if the user wants to think of it as evaluating every time it's used or just once. That's the whole point of compile_time / pure functions. No side effects and context doesn't matter.
Dec 13 2007
"Russell Lewis" wroteIMHO, it's better for a C++ programmer to say "I've never seen that keyword, let me look up what it does," than to say "I know what that does" - and be wrong. Yes, you can re-teach them. But if the keyword is unfamiliar, then you re-teach them the *first* time that they see it, not ages later when they stumble upon a subtle bug.If I'm not mistaken, pure is a keyword in gcc already, and does not mean "manifest constant" -Steve
Dec 14 2007
On Thu, 13 Dec 2007 22:43:41 +0200, Bill Baxter <dnewsgroup billbaxter.c= om> wrote:Russell Lewis wrote:sI thought about suggesting this, but what turned me off to it was thi=rydeclaration: define int x =3D some_compile_time_func(); A C/C++ programmer will probably think of this as a #define-style substitution, which means that he will expect the function to run eve=retime that he uses the constant. However, what we are trying to decla=is a manifest constant. It seemed like it would introduce confusion.=That may be their first guess as to what it does, but it doesn't seem like it would be difficult to relieve oneself of that misconception. And in any case, the only time the above would work is if some_compile_time_function() really is a compile time function. So it=doesn't really matter if the user wants to think of it as evaluating every time it's used or just once. That's the whole point of compile_time / pure functions. No side effects and context doesn't ma=tter. In that case, what's wrong with "alias"? It sounds good, it has the same= problem (misconception of substitution), but isn't a new keyword. -- = Best regards, Vladimir mailto:thecybershadow gmail.com
Dec 13 2007
"Russell Lewis" wroteI thought about suggesting this, but what turned me off to it was this declaration: define int x = some_compile_time_func(); A C/C++ programmer will probably think of this as a #define-style substitution, which means that he will expect the function to run every time that he uses the constant. However, what we are trying to declare is a manifest constant. It seemed like it would introduce confusion. Just my $.02, RussToo bad, so sad. If you want something that acts exactly like C, use C. D already uses lots of C keywords differently than C does, that was my original point. And Bill Baxter's point is right on. If the function is compile time, no need to execute it every time it's used because the result will already be evaluated by the compiler. -Steve
Dec 13 2007