digitalmars.D - Constants, Aliases
- Xinok <xnknet gmail.com> Dec 13 2006
- Bill Baxter <dnewsgroup billbaxter.com> Dec 13 2006
- nazo <lovesyao gmail.com> Dec 14 2006
- nazo <lovesyao gmail.com> Dec 14 2006
- Bill Baxter <wbaxter gmail.com> Dec 14 2006
- "John Reimer" <terminal.node gmail.com> Dec 14 2006
- nazo <lovesyao gmail.com> Dec 14 2006
- Chris Nicholson-Sauls <ibisbasenji gmail.com> Dec 14 2006
- nazo <lovesyao gmail.com> Dec 14 2006
- Chris Nicholson-Sauls <ibisbasenji gmail.com> Dec 14 2006
- Alexander Panek <a.panek brainsware.org> Dec 14 2006
- janderson <askme me.com> Dec 15 2006
- Alexander Panek <a.panek brainsware.org> Dec 16 2006
- Lutger <lutger.blijdestijn gmail.com> Dec 14 2006
- Alexander Panek <a.panek brainsware.org> Dec 14 2006
- Hasan Aljudy <hasan.aljudy gmail.com> Dec 14 2006
- Alexander Panek <a.panek brainsware.org> Dec 14 2006
- Lutger <lutger.blijdestijn gmail.com> Dec 14 2006
- Hasan Aljudy <hasan.aljudy gmail.com> Dec 14 2006
- Lutger <lutger.blijdestijn gmail.com> Dec 14 2006
- Don Clugston <dac nospam.com.au> Dec 14 2006
- Lutger <lutger.blijdestijn gmail.com> Dec 14 2006
- Don Clugston <dac nospam.com.au> Dec 14 2006
- "Tomas Lindquist Olsen" <tomas famolsen.dk> Dec 14 2006
- Lutger <lutger.blijdestijn gmail.com> Dec 14 2006
- Sean Kelly <sean f4.ca> Dec 14 2006
- Hasan Aljudy <hasan.aljudy gmail.com> Dec 14 2006
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. :-=
--bb
8th deadly sin? No..no..no... I'm sure you meant 1st deadly sin! ;D -JJR
Dec 14 2006
Bill Baxter wrote: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.
alias[] funcs=[unyu,unyu,unyu]; foreach(f;funcs)f();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.
current: template f(alias i){ const int f=i*10; } suggestion of syntax sugar: const int f(alias i)=i*10;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
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... # // Boar example # module #Math; # function Float sqr ($n) = $n * $n; # function Float cube ($n) = #Math:sqr($n) * $n; Therefore, naturally, I'm not against it. :) -- Chris Nicholson-Sauls
Dec 14 2006
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
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: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
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-Sauls
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" } // Error
enum : 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: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.
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. } } Alex
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: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)
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.
Dec 14 2006
Alexander Panek wrote:Lutger wrote: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)
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.
So what!! You can violate class encapsulation using pointers too, in fact you can even mess the v-table.
Dec 14 2006
Hasan Aljudy wrote:Alexander Panek wrote:Lutger wrote: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)
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.
So what!! You can violate class encapsulation using pointers too, in fact you can even mess the v-table.
Hahaha, yea. I don't get what const would change there, either. X-P
Dec 14 2006
Alexander Panek wrote:Lutger wrote: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)
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.
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.
Dec 14 2006
Lutger wrote:Alexander Panek wrote:Lutger wrote: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)
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.
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.
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.
Dec 14 2006
Hasan Aljudy wrote:Lutger wrote:Alexander Panek wrote:Lutger wrote: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)
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.
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.
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.
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?
Dec 14 2006
Lutger wrote:Hasan Aljudy wrote:Lutger wrote:Alexander Panek wrote:Lutger wrote: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)
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.
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.
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.
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?
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.
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: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."
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.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: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)
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)
Dec 14 2006
Tomas Lindquist Olsen wrote:Lutger wrote:Xinok wrote:The problem with the const keyword is it doesn't guarantee the expression will be constant.
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)
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; }
Dec 14 2006
Tomas Lindquist Olsen wrote:Lutger wrote:Xinok wrote:The problem with the const keyword is it doesn't guarantee the expression will be constant.
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)
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? Sean
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









Bill Baxter <dnewsgroup billbaxter.com> 