digitalmars.D - Initializing "two-dimensional" compile-time enum
- Uranuz (23/23) Nov 24 2013 Greetings! I have a problem in my code and I need an advice. I
- Uranuz (22/22) Nov 24 2013 Compiling following code makes another strange error message.
- Philippe Sigaud (21/42) Nov 24 2013 Geez, I just spent 15' trying to make this work! AA + Compile-time are
- Uranuz (7/7) Nov 24 2013 Thanks! I'll try it. Another question is can I use immutable
- Philippe Sigaud (14/20) Nov 24 2013 A named enum has no 'real' existence: you cannot take its address (it
- Uranuz (27/27) Nov 24 2013 As far as I understand I can't use immutable values as template
- Uranuz (7/7) Nov 24 2013 This example above will not compile because name is not a compile
- Philippe Sigaud (7/10) Nov 24 2013 That's what we all want, but it's more or less impossible. If your
- Philippe Sigaud (11/25) Nov 24 2013 I see some possibilities, but they might be a bit overkill. In
- monarch_dodra (15/18) Nov 24 2013 Lambda's to the rescue!
- Uranuz (1/1) Nov 24 2013 While looking at this example JavaScript syntax calling to mind))
- Philippe Sigaud (2/3) Nov 24 2013 Well, in an ideal world, we wouldn't have to fall back to these contorti...
- monarch_dodra (11/16) Nov 25 2013 Even without bugs, it's still convenient way to declare a
- Philippe Sigaud (2/2) Nov 25 2013 Good idea, it's something I tend to forget. I always create associated
- Philippe Sigaud (4/6) Nov 25 2013 Arg, damn gmail. ... when an anonymous one would be enough (and would
Greetings! I have a problem in my code and I need an advice. I need possibility of creating "two-dimensional" AA in module scope that I can access at compile-time. I considered that it should be marked as enum to do this but I get strange error. There is a piece of code to test. //--------------- import std.stdio; enum string[int][string] pohodEnumValues = [ "vid": [ 3: "skiing", 5: "rafting", 7: "jumping" ], "ks": [ 1: "first", 2: "second", 3: "third" ], "prepare": [ 1:"planning", 3:"preparing", 5:"complete" ] ]; void main() { writeln(pohodEnumValues); } //--------END OF CODE ----- In dmd 2.064.2 I get following output: Compilation output: /d521/f517.d(4): Error: not an associative array initializer Elements of AA are used as template arguments so I need them at compile-time. I need help, please))
Nov 24 2013
Compiling following code makes another strange error message. import std.stdio; enum string[int][string] pohodEnumValues = [ "vid": [ 3: "skiing", 5: "rafting", 7: "jumping" ].dup, "ks": [ 1: "first", 2: "second", 3: "third" ].dup, "prepare": [ 1:"planning", 3:"preparing", 5:"complete" ].dup ]; void main() { writeln(pohodEnumValues); } //------- Compilation output: /opt/compilers/dmd2/include/object.di(435): Error: _aaApply2 cannot be interpreted at compile time, because it has no available source code /opt/compilers/dmd2/include/object.di(458): called from here: this.opApply(delegate int(ref int __applyArg0, ref string __applyArg1) => 0) /d895/f161.d(5): called from here: [3:"skiing", 5:"rafting", 7:"jumping"].dup()
Nov 24 2013
Geez, I just spent 15' trying to make this work! AA + Compile-time are like oil and water. You can use CTFE and an initializing function. It's a bit cumbersome, but it works. module main; import std.stdio; string[int][string] initializePohod() { string[int][string] result; result["vid"] = [ 3: "skiing", 5: "rafting", 7: "jumping" ]; result["ks"] = [ 1: "first", 2: "second", 3: "third" ]; result["prepare"] = [ 1:"planning", 3:"preparing", 5:"complete" ]; return result; } enum string[int][string] pohodEnumValues = initializePohod(); void main() { writeln(pohodEnumValues); pragma(msg, pohodEnumValues); // there, accessible during compilation. } On Sun, Nov 24, 2013 at 1:01 PM, Uranuz <neuranuz gmail.com> wrote:Greetings! I have a problem in my code and I need an advice. I need possibility of creating "two-dimensional" AA in module scope that I can access at compile-time. I considered that it should be marked as enum to do this but I get strange error. There is a piece of code to test. //--------------- import std.stdio; enum string[int][string] pohodEnumValues = [ "vid": [ 3: "skiing", 5: "rafting", 7: "jumping" ], "ks": [ 1: "first", 2: "second", 3: "third" ], "prepare": [ 1:"planning", 3:"preparing", 5:"complete" ] ]; void main() { writeln(pohodEnumValues); } //--------END OF CODE ----- In dmd 2.064.2 I get following output: Compilation output: /d521/f517.d(4): Error: not an associative array initializer Elements of AA are used as template arguments so I need them at compile-time. I need help, please))
Nov 24 2013
Thanks! I'll try it. Another question is can I use immutable variables in compile time or they are just runtime variables that are once initialized and can't be modified? Is it only way to use manifest constants (enum). And what is semantics of enum constants? In D we have a lot of modifiers: static, enum, const, immutable. So sometimes I get stuck with question what to use? Could someone briefly explain the purpose of each one of these?
Nov 24 2013
On Sun, Nov 24, 2013 at 5:14 PM, Uranuz <neuranuz gmail.com> wrote:Thanks! I'll try it. Another question is can I use immutable variables in compile time or they are just runtime variables that are once initialized and can't be modified? Is it only way to use manifest constants (enum). And what is semantics of enum constants? In D we have a lot of modifiers: static, enum, const, immutable. So sometimes I get stuck with question what to use? Could someone briefly explain the purpose of each one of these?A named enum has no 'real' existence: you cannot take its address (it has none), for example. It's a glorified literal, which is just replaced by its value every time it's used. Which means using enum` in conjunction with dynamic arrays and associative arrays is prone to drastically limit your code speed, because there will be an allocation for each instance. An immutable value is much more standard: it's allocated once, you can take its address and so on. It can be allocated at runtime and once it's allocated, no one can change it. It A const value cannot be modified in the current scope, but someone else, elsewhere, might. See: http://ddili.org/ders/d.en/const_and_immutable.html And also: http://ddili.org/ders/d.en/const_member_functions.html
Nov 24 2013
As far as I understand I can't use immutable values as template arguments. It's what I need in my code. I'll give an example. //--------------- import std.stdio; immutable(string[int][string]) pohodEnumValues; shared static this() { pohodEnumValues = [ "vid": [ 3: "skiing", 5: "rafting", 7: "jumping" ], "ks": [ 1: "first", 2: "second", 3: "third" ], "prepare": [ 1:"planning", 3:"preparing", 5:"complete" ] ]; } //Some template method void foo(string arg)() { //Some actions here } void main() { foreach( name, item; pohodEnumValues ) { foo!(name)(); //I need name at compile time here } } //----------------- Because we have only compile time foreach over tuple this is not working. Can someone give an advice, please?
Nov 24 2013
This example above will not compile because name is not a compile time expression. But I can't undersatnd how to make some kind of compile-time variable. If we have advanced metaprogramming features I think possibility of defining compile-time variables is needed. Am I right or not? I think defining compile-time array as Tuple!("first", "second", "third") looking sophisticated.
Nov 24 2013
But I can't undersatnd how to make some kind of compile-time variable. If we have advanced metaprogramming features I think possibility of defining compile-time variables is needed. Am I right or not?That's what we all want, but it's more or less impossible. If your variable do not change type, then you can at least build an array and store its successive values in the array. Then you use the last value for the rest of your computation. Or, as I said in another post, use Compile-Time Function Evaluation: using standard functions, you can be as iterative/imperative as you want.
Nov 24 2013
On Sun, Nov 24, 2013 at 8:09 PM, Uranuz <neuranuz gmail.com> wrote:As far as I understand I can't use immutable values as template arguments.Indeed not. They are not defined at compile-time.//Some template method void foo(string arg)() { //Some actions here } void main() { foreach( name, item; pohodEnumValues ) { foo!(name)(); //I need name at compile time here } } //----------------- Because we have only compile time foreach over tuple this is not working. Can someone give an advice, please?I see some possibilities, but they might be a bit overkill. In increasing order of coding effort: 1) use a tuple (as you suggest in another post) 2) use functions to build the code you want (as a string) and then mix it in. Using functions, you can use iterative code as much as you wish. 3) Another, more far-fetched, option is to use a struct. Since your AA is defined at compile-time, I would not create an AA, but a struct, crafting it to mimic your AA.
Nov 24 2013
On Sunday, 24 November 2013 at 13:58:11 UTC, Philippe Sigaud wrote:You can use CTFE and an initializing function. It's a bit cumbersome, but it works.Lambda's to the rescue! //---- enum string[int][string] pohodEnumValues = (){ string[int][string] result; result["vid"] = [ 3: "skiing", 5: "rafting", 7: "jumping" ]; result["ks"] = [ 1: "first", 2: "second", 3: "third" ]; result["prepare"] = [ 1:"planning", 3:"preparing", 5:"complete" ]; return result; }(); //---- This is cleaner, IMO.
Nov 24 2013
While looking at this example JavaScript syntax calling to mind))
Nov 24 2013
On Sun, Nov 24, 2013 at 5:19 PM, monarch_dodra <monarchdodra gmail.com> wrote:This is cleaner, IMO.Well, in an ideal world, we wouldn't have to fall back to these contortions.
Nov 24 2013
On Sunday, 24 November 2013 at 17:16:21 UTC, Philippe Sigaud wrote:On Sun, Nov 24, 2013 at 5:19 PM, monarch_dodra <monarchdodra gmail.com> wrote:Even without bugs, it's still convenient way to declare a variable as enum or const, when 1-liner initialization is simply not possible. enum bar = () { T t; initialize(t); return t; }();This is cleaner, IMO.Well, in an ideal world, we wouldn't have to fall back to these contortions.
Nov 25 2013
Good idea, it's something I tend to forget. I always create associated functions when an anony...
Nov 25 2013
On Mon, Nov 25, 2013 at 7:10 PM, Philippe Sigaud <philippe.sigaud gmail.com> wrote:Good idea, it's something I tend to forget. I always create associated functions when an anony...Arg, damn gmail. ... when an anonymous one would be enough (and would not clutter the namespace)
Nov 25 2013