digitalmars.D - Constants, Aliases
- Xinok (19/19) Dec 13 2006 In C++, you can define a constant by using a preprocessor:
- Bill Baxter (21/46) Dec 13 2006 It would also make writing recursive templates a little bit simpler.
- nazo (12/12) Dec 14 2006 Expressions! Expressions! (/ ~.)/
- nazo (24/24) Dec 14 2006 current:
- Bill Baxter (10/22) Dec 14 2006 I'm all for that. Changing the order I mean, not necessarily aliases
- John Reimer (6/16) Dec 14 2006 P
- nazo (13/37) Dec 14 2006 void unyu(){writefln("unyu");};
- Chris Nicholson-Sauls (8/10) Dec 14 2006 Makes me think of my hypothetical Boar language...
- nazo (7/7) Dec 14 2006 Here is my patch for variable template 'without' alias and typedef.
- Chris Nicholson-Sauls (7/33) Dec 14 2006 Actually its the 9th deadly sin. The 8th would be copy constructors. T...
- Alexander Panek (22/47) Dec 14 2006 Technically, you can change a constant value in C++, too, if you want.
- janderson (5/10) Dec 15 2006 Actually that would be very difficult to make work, with optimisation.
- Alexander Panek (12/23) Dec 16 2006 This depends on how you used const.
- Lutger (2/4) Dec 14 2006 It doesn't? How can you modify a const var then? (in D)
- Alexander Panek (4/10) Dec 14 2006 You can modify const variables that are not set directly at declaration
- Hasan Aljudy (4/15) Dec 14 2006 So what!!
- Alexander Panek (2/20) Dec 14 2006 Hahaha, yea. I don't get what const would change there, either. X-P
- Lutger (5/16) Dec 14 2006 Haha yes it works. Is that how it should be or is it a bug or compiler
- Hasan Aljudy (5/22) Dec 14 2006 Why not?
- Lutger (10/36) Dec 14 2006 Sure, if you want it you can break the type system. But there are some
- Don Clugston (9/47) Dec 14 2006 The confusion comes from the way that D uses const in two ways.
- Lutger (11/21) Dec 14 2006 Thank you for the clarification. This means that the original statement
- Don Clugston (7/30) Dec 14 2006 You are correct. The OP statement is untrue.
- Tomas Lindquist Olsen (14/19) Dec 14 2006 This actually feels more like a bug, but here's an example:
- Lutger (12/34) Dec 14 2006 Huh yes, const doesn't work at all for structs. This also compiles:
- Sean Kelly (4/26) Dec 14 2006 On Windows, DMD doesn't put constants into ROM. I'm not entirely sure
- Hasan Aljudy (3/28) Dec 14 2006 I think you're proposing a preprocessor .. something that D deliberately...
In C++, you can define a constant by using a preprocessor: #define INT 30 In D, the standard is to use 'const': const int INT = 30; The problem with the const keyword is it doesn't guarantee the expression will be constant. const int* PTR = new int; // This technically isn't a constant, the compiler just doesn't allow you to modify it's value. Another solution is to use enumerators, but they don't aloow any type other than int: enum { val = 30 } // OK enum { str = "Hello" } // Error So I was thinking, why not give this job to aliases? Aliases must be constant, you can use any type with them, and they're easy to write. alias 30 VAL; alias "Hello" STR; alias 31.5 DEC; Expressions can simply be put within parenthesis: alias (15 * 99) EXP;
Dec 13 2006
Xinok wrote:In C++, you can define a constant by using a preprocessor: #define INT 30 In D, the standard is to use 'const': const int INT = 30; The problem with the const keyword is it doesn't guarantee the expression will be constant. const int* PTR = new int; // This technically isn't a constant, the compiler just doesn't allow you to modify it's value. Another solution is to use enumerators, but they don't aloow any type other than int: enum { val = 30 } // OK enum { str = "Hello" } // Error So I was thinking, why not give this job to aliases? Aliases must be constant, you can use any type with them, and they're easy to write. alias 30 VAL; alias "Hello" STR; alias 31.5 DEC; Expressions can simply be put within parenthesis: alias (15 * 99) EXP;It would also make writing recursive templates a little bit simpler. Sometimes it takes me a minute to figure out whether I need alias template_name[1..$] template_name; or const Type template_name = template_name[1..$]; Actually... I guess they're interchangeable till you get to the base case -- ferinstance: template tuple_all_of(T, S...) { static if(S.length == 0) { const bool tuple_all_of = true; } else static if( is(S[0]: T) ) { // either version is ok here //const bool tuple_all_of = tuple_all_of!(T, S[1..$]); alias tuple_all_of!(T, S[1..$]) tuple_all_of; } else { const bool tuple_all_of = false; } } --bb
Dec 13 2006
Expressions! Expressions! (/ ~.)/ I think that the exchange of parameters of alias is necessary from: alias (x*2) exp; to: alias exp=x*2; And I need alias arguments as syntax sugar like: alias(alias i) exp=i*2; same as: template exp(alias i){ alias exp=i*2; } #sorry for my poor English.
Dec 14 2006
current: void func(){} alias func test; suggestion: void func(){} alias test=func; alias test2="test"; #this code is error yet import std.typetuple,std.stdio; void func(){writefln("test");} alias TypeTuple!(func) test; void main(){ test[0]();//error } #And this too import std.typetuple,std.stdio; int x; alias TypeTuple!(x*x) test; void main(){ x=10; writefln(test[0]); x=20; writefln(test[0]); }
Dec 14 2006
nazo wrote:Expressions! Expressions! (/ ~.)/ I think that the exchange of parameters of alias is necessary from: alias (x*2) exp; to: alias exp=x*2;I'm all for that. Changing the order I mean, not necessarily aliases for expressions. Typedef too. They're all just saying symbol=value (where 'value' is a type). But probably it will never change. Alias is too closely connected to typedef, and typedef is too closely connected to C/C++ for Walter to change its syntax. End result: neither will change.And I need alias arguments as syntax sugar like: alias(alias i) exp=i*2; same as: template exp(alias i){ alias exp=i*2; }Hmm, yeh not sure about that. Have to get everyone to swallow the expression alias idea first, which will be tough because they've all been brainwashed into thinking that #define is the 8th deadly sin. :-P --bb
Dec 14 2006
On Thu, 14 Dec 2006 12:57:11 -0800, Bill Baxter <wbaxter gmail.com> wrot= e:And I need alias arguments as syntax sugar like: alias(alias i) exp=3Di*2; same as: template exp(alias i){ alias exp=3Di*2; }Hmm, yeh not sure about that. Have to get everyone to swallow the =expression alias idea first, which will be tough because they've all =been brainwashed into thinking that #define is the 8th deadly sin. :-=P--bb8th deadly sin? No..no..no... I'm sure you meant 1st deadly sin! ;D -JJR
Dec 14 2006
Bill Baxter wrote:nazo wrote:void unyu(){writefln("unyu");}; alias[] funcs=[unyu,unyu,unyu]; foreach(f;funcs)f();Expressions! Expressions! (/ ~.)/ I think that the exchange of parameters of alias is necessary from: alias (x*2) exp; to: alias exp=x*2;I'm all for that. Changing the order I mean, not necessarily aliases for expressions. Typedef too. They're all just saying symbol=value (where 'value' is a type). But probably it will never change. Alias is too closely connected to typedef, and typedef is too closely connected to C/C++ for Walter to change its syntax. End result: neither will change.I rewrite this idea: current: template f(alias i){ const int f=i*10; } suggestion of syntax sugar: const int f(alias i)=i*10;And I need alias arguments as syntax sugar like: alias(alias i) exp=i*2; same as: template exp(alias i){ alias exp=i*2; }Hmm, yeh not sure about that.Have to get everyone to swallow the expression alias idea first, which will be tough because they've all been brainwashed into thinking that #define is the 8th deadly sin. :-Pthe preprocessor is the 8th deadly sin! but alias and template are not bad-knowhow!
Dec 14 2006
nazo wrote:suggestion of syntax sugar: const int f(alias i)=i*10;Makes me think of my hypothetical Boar language... Therefore, naturally, I'm not against it. :) -- Chris Nicholson-Sauls
Dec 14 2006
Here is my patch for variable template 'without' alias and typedef. Test Code: const int test(int x) = x*2; void main(){ static assert(test!(5)==10); } #sorry for my poor English.
Dec 14 2006
Bill Baxter wrote:nazo wrote:Actually its the 9th deadly sin. The 8th would be copy constructors. That said, i'm actually intrigued by the idea of a expression aliases. I can think of ways they might well be useful -- and I think changing the syntax to "'alias' ident '=' expr ';'" for this particular case wouldn't be too bad either. (If nothing else it would make it perfeclty clear to a parser that this is an expression-alias rather than a symbol-alias.) -- Chris Nicholson-SaulsExpressions! Expressions! (/ ~.)/ I think that the exchange of parameters of alias is necessary from: alias (x*2) exp; to: alias exp=x*2;I'm all for that. Changing the order I mean, not necessarily aliases for expressions. Typedef too. They're all just saying symbol=value (where 'value' is a type). But probably it will never change. Alias is too closely connected to typedef, and typedef is too closely connected to C/C++ for Walter to change its syntax. End result: neither will change.And I need alias arguments as syntax sugar like: alias(alias i) exp=i*2; same as: template exp(alias i){ alias exp=i*2; }Hmm, yeh not sure about that. Have to get everyone to swallow the expression alias idea first, which will be tough because they've all been brainwashed into thinking that #define is the 8th deadly sin. :-P --bb
Dec 14 2006
Xinok wrote:In C++, you can define a constant by using a preprocessor: #define INT 30 In D, the standard is to use 'const': const int INT = 30; The problem with the const keyword is it doesn't guarantee the expression will be constant. const int* PTR = new int; // This technically isn't a constant, the compiler just doesn't allow you to modify it's value.Technically, you can change a constant value in C++, too, if you want. Just get the address and write a little inline assembler to mov x, y something else there. I can't imagine what'd hold me off from that. If you really are so afraid constant values could be changed during runtime, then wright an immutable class, that does for you what you think you need more than D's const.Another solution is to use enumerators, but they don't aloow any type other than int: enum { val = 30 } // OK enum { str = "Hello" } // Errorenum : uint { } // Yay, we've got uint as enum! enum : char { } // Yay, char too! (this works.) The only thing that does not work is an array. Apart from that, you can use any (basic?) type.So I was thinking, why not give this job to aliases? Aliases must be constant, you can use any type with them, and they're easy to write. alias 30 VAL; alias "Hello" STR; alias 31.5 DEC;This is neither type-safe nor anyhow what alias is meant to be.Expressions can simply be put within parenthesis: alias (15 * 99) EXP;Same goes here. Sorry, if I sound a bit harsh, but I really dislike preprocessors and is really great /without/ preprocessors. I don't see any need for this. You got version() statements, static if's and what not. It's way cleaner and simpler to read, why insert something in the language just half a month before the language goes 1.0, that is *actually* deprecated and (IIRC) has been discussed in other forms already a few times? Really. No need for that. D is not C++. Kind Regards, Alex
Dec 14 2006
Alexander Panek wrote:Xinok wrote: Technically, you can change a constant value in C++, too, if you want. Just get the address and write a little inline assembler to mov x, y something else there. I can't imagine what'd hold me off from that.Actually that would be very difficult to make work, with optimisation. You'd have to find and replace every position the const was used (including ones that have been combined with other constants and optimizations) and replace them.
Dec 15 2006
janderson wrote:Alexander Panek wrote:This depends on how you used const. const uint x = 1; // this is your case, the variable is just set in and has no unique memory address class X { const uint x; this ( ) { this.x = 0; // here, x has an address and const is meant to be a write-once variable, not a constant value as above. } } AlexXinok wrote: Technically, you can change a constant value in C++, too, if you want. Just get the address and write a little inline assembler to mov x, y something else there. I can't imagine what'd hold me off from that.Actually that would be very difficult to make work, with optimisation. You'd have to find and replace every position the const was used (including ones that have been combined with other constants and optimizations) and replace them.
Dec 16 2006
Xinok wrote:The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
Lutger wrote:Xinok wrote:You can modify const variables that are not set directly at declaration (write-once constants) just by getting their address and modifying them through another variable/pointer.The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
Alexander Panek wrote:Lutger wrote:So what!! You can violate class encapsulation using pointers too, in fact you can even mess the v-table.Xinok wrote:You can modify const variables that are not set directly at declaration (write-once constants) just by getting their address and modifying them through another variable/pointer.The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
Hasan Aljudy wrote:Alexander Panek wrote:Hahaha, yea. I don't get what const would change there, either. X-PLutger wrote:So what!! You can violate class encapsulation using pointers too, in fact you can even mess the v-table.Xinok wrote:You can modify const variables that are not set directly at declaration (write-once constants) just by getting their address and modifying them through another variable/pointer.The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
Alexander Panek wrote:Lutger wrote:Haha yes it works. Is that how it should be or is it a bug or compiler limitation? It looks whacky to me. You can only write a const once in a constructor or so says DMD, thus it seems like this subverts the system in more than one way. I can't imagine that ever being useful.Xinok wrote:You can modify const variables that are not set directly at declaration (write-once constants) just by getting their address and modifying them through another variable/pointer.The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
Lutger wrote:Alexander Panek wrote:Why not? It's useful when you work with sane programmers. After all, with pointers and asm, there's no limit to how many things you can mess.Lutger wrote:Haha yes it works. Is that how it should be or is it a bug or compiler limitation? It looks whacky to me. You can only write a const once in a constructor or so says DMD, thus it seems like this subverts the system in more than one way. I can't imagine that ever being useful.Xinok wrote:You can modify const variables that are not set directly at declaration (write-once constants) just by getting their address and modifying them through another variable/pointer.The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
Hasan Aljudy wrote:Lutger wrote:Sure, if you want it you can break the type system. But there are some barriers for pointers, these are still typed. I don't think it is so obscure. If you have a const value type in a class, you must set it in the initializer or the constructor. You also cannot modify it. Fine, but then if you have a getter return a reference to it, suddenly all bets are off. This is not what I'd expect, probably because of a C++ bias I still have somewhere, that I (wrongly) think const is part of the type system?Alexander Panek wrote:Why not? It's useful when you work with sane programmers. After all, with pointers and asm, there's no limit to how many things you can mess.Lutger wrote:Haha yes it works. Is that how it should be or is it a bug or compiler limitation? It looks whacky to me. You can only write a const once in a constructor or so says DMD, thus it seems like this subverts the system in more than one way. I can't imagine that ever being useful.Xinok wrote:You can modify const variables that are not set directly at declaration (write-once constants) just by getting their address and modifying them through another variable/pointer.The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
Lutger wrote:Hasan Aljudy wrote:The confusion comes from the way that D uses const in two ways. const XXX = YYY; really is const, cannot be changed (even in theory), and probably won't appear in the executable at all. This is definitely part of the type system. const XXX; is not const at all (it's a variable!). 'final' might have been a better name. As you mention, the read-only protection seems to be very fragile. It seems a very hard thing to enforce.Lutger wrote:Sure, if you want it you can break the type system. But there are some barriers for pointers, these are still typed. I don't think it is so obscure. If you have a const value type in a class, you must set it in the initializer or the constructor. You also cannot modify it. Fine, but then if you have a getter return a reference to it, suddenly all bets are off. This is not what I'd expect, probably because of a C++ bias I still have somewhere, that I (wrongly) think const is part of the type system?Alexander Panek wrote:Why not? It's useful when you work with sane programmers. After all, with pointers and asm, there's no limit to how many things you can mess.Lutger wrote:Haha yes it works. Is that how it should be or is it a bug or compiler limitation? It looks whacky to me. You can only write a const once in a constructor or so says DMD, thus it seems like this subverts the system in more than one way. I can't imagine that ever being useful.Xinok wrote:You can modify const variables that are not set directly at declaration (write-once constants) just by getting their address and modifying them through another variable/pointer.The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
Don Clugston wrote:The confusion comes from the way that D uses const in two ways. const XXX = YYY; really is const, cannot be changed (even in theory), and probably won't appear in the executable at all. This is definitely part of the type system. const XXX; is not const at all (it's a variable!). 'final' might have been a better name. As you mention, the read-only protection seems to be very fragile. It seems a very hard thing to enforce.Thank you for the clarification. This means that the original statement from the OP is not true: "In D, the standard is to use 'const': const int INT = 30; The problem with the const keyword is it doesn't guarantee the expression will be constant." Then the issue with consts (the first type) in structs and const structs must be a bug? I was wrong btw about references to members, it only applies to structs not primitives.
Dec 14 2006
Lutger wrote:Don Clugston wrote:You are correct. The OP statement is untrue. It's an important distinction -- if it's really a constant, you can use it inside a 'static if'. And you're not allowed to take the address of it.The confusion comes from the way that D uses const in two ways. const XXX = YYY; really is const, cannot be changed (even in theory), and probably won't appear in the executable at all. This is definitely part of the type system. const XXX; is not const at all (it's a variable!). 'final' might have been a better name. As you mention, the read-only protection seems to be very fragile. It seems a very hard thing to enforce.Thank you for the clarification. This means that the original statement from the OP is not true: "In D, the standard is to use 'const': const int INT = 30; The problem with the const keyword is it doesn't guarantee the expression will be constant."Then the issue with consts (the first type) in structs and const structs must be a bug?I think so. There are a few quirks with array literals and apparently consts as well -- they look like compile-time constants, but AFAIK they are currently implemented as "read-only" variables.I was wrong btw about references to members, it only applies to structs not primitives.
Dec 14 2006
Lutger wrote:Xinok wrote:This actually feels more like a bug, but here's an example: module noconst; import std.stdio; struct S { float f; } const S s = {3.1415}; void main() { writefln(s.f); s.f = 666; writefln(s.f); } (DMD.177)The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
Tomas Lindquist Olsen wrote:Lutger wrote:Huh yes, const doesn't work at all for structs. This also compiles: struct S { const int i; } void main() { S s; s.i = 10; s.i = 666; }Xinok wrote:This actually feels more like a bug, but here's an example: module noconst; import std.stdio; struct S { float f; } const S s = {3.1415}; void main() { writefln(s.f); s.f = 666; writefln(s.f); } (DMD.177)The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
Tomas Lindquist Olsen wrote:Lutger wrote:On Windows, DMD doesn't put constants into ROM. I'm not entirely sure why, but I suspect it may be that the OS doesn't support the idea? SeanXinok wrote:This actually feels more like a bug, but here's an example: module noconst; import std.stdio; struct S { float f; } const S s = {3.1415}; void main() { writefln(s.f); s.f = 666; writefln(s.f); } (DMD.177)The problem with the const keyword is it doesn't guarantee the expression will be constant.It doesn't? How can you modify a const var then? (in D)
Dec 14 2006
I think you're proposing a preprocessor .. something that D deliberately dropped from C/C++ Xinok wrote:In C++, you can define a constant by using a preprocessor: #define INT 30 In D, the standard is to use 'const': const int INT = 30; The problem with the const keyword is it doesn't guarantee the expression will be constant. const int* PTR = new int; // This technically isn't a constant, the compiler just doesn't allow you to modify it's value. Another solution is to use enumerators, but they don't aloow any type other than int: enum { val = 30 } // OK enum { str = "Hello" } // Error So I was thinking, why not give this job to aliases? Aliases must be constant, you can use any type with them, and they're easy to write. alias 30 VAL; alias "Hello" STR; alias 31.5 DEC; Expressions can simply be put within parenthesis: alias (15 * 99) EXP;
Dec 14 2006