Re: Is it possible to add items to the arrays and hashes at compile time?
On 06/09/2015 09:36 PM, Dennis Ritchie wrote: But I can not do so: enum int[][int][int] ctHash = init_ctHash(5); ctHash = merge(ctHash, init_ctHash(6)); I have a question: why variables may not be initialized more than once? Why can't they to resave at compile time? My phrasing was off: By definition, initialization happens once. :) What I meant is, once initialized, a compile-time variable cannot be reassigned. The reason is, to effect compile time evaluation, one needs to use 'enum' (or 'static const') but 'enum' is a literal, i.e. it cannot be modified. As I've shown, it is possible to use an expression that will be used as the value of the compile-time variable. As long as it is evaluable at compile time, the expression can be arbitrarily complex. Ali
Re: Is it possible to add items to the arrays and hashes at compile time?
On Wednesday, 10 June 2015 at 17:43:36 UTC, Ali Çehreli wrote: On the other hand, if it's a manifest constant (enum, const static, etc.) then by definition it cannot be mutated. If we allowed mutation of compile-time expressions, then we would have a complicated language. Unfortunately, the halting problem says that the analyzer does not exist. Although I don't believe it! enum i = 42; enum j = foo(i);// Did foo() use 42 or 43? i = 43; enum k = foo(i);// Did foo() use 42 or 43? How can an enum value be changed? I find the above confusing. So in fact, if `int` is evaluated at compile time, then we won't need constants or enums. Because they almost would not make sense. Although the issues associated with immutability, complex, I think they can be solved differently. The great thing about D's CTFE is that we can use arbitrarily complex expressions as long as they are available at compile time. For example, it is possible to make 'i' above a foreach loop variable and call foo() with different values. There is nothing great. Everything is based on constexpr of C++. I want something more revolutionary :) What is your use case? I feel like it can be solved by other means. There is no precedent special :) I just want to know more about the possibilities of D and the possibility of its compiler. D made me a terrible interest in compilers :)
Re: Is it possible to add items to the arrays and hashes at compile time?
On Wednesday, 10 June 2015 at 17:13:34 UTC, anonymous wrote: On Wednesday, 10 June 2015 at 17:00:34 UTC, Dennis Ritchie wrote: Isnt it possible to come up with the interpreter compile-time, which will determine the operating time of the program at runtime at compile time. Sounds like the halting problem. So, no, generally this is not possible. Thanks. I had never heard of the halting problem. This is exactly what I wanted to know.
Re: Is it possible to add items to the arrays and hashes at compile time?
On 06/10/2015 10:00 AM, Dennis Ritchie wrote: Is it possible somehow to create a more complex compilation process, which can reassign variables more than once? I am not a compiler writer but I assume if a variable is not a compile-time expression, then the compiler generates code that makes it possible to initialize it at run time and modify it if mutable: int i = argc; // ... ++i; On the other hand, if it's a manifest constant (enum, const static, etc.) then by definition it cannot be mutated. If we allowed mutation of compile-time expressions, then we would have a complicated language. enum i = 42; enum j = foo(i);// Did foo() use 42 or 43? i = 43; enum k = foo(i);// Did foo() use 42 or 43? How can an enum value be changed? I find the above confusing. The great thing about D's CTFE is that we can use arbitrarily complex expressions as long as they are available at compile time. For example, it is possible to make 'i' above a foreach loop variable and call foo() with different values. What is your use case? I feel like it can be solved by other means. Ali
Re: Is it possible to add items to the arrays and hashes at compile time?
On Wednesday, 10 June 2015 at 07:15:26 UTC, Ali Çehreli wrote: My phrasing was off: By definition, initialization happens once. :) What I meant is, once initialized, a compile-time variable cannot be reassigned. The reason is, to effect compile time evaluation, one needs to use 'enum' (or 'static const') but 'enum' is a literal, i.e. it cannot be modified. As I've shown, it is possible to use an expression that will be used as the value of the compile-time variable. As long as it is evaluable at compile time, the expression can be arbitrarily complex. I understand your phrase :) I don't understand why the variables at compile time cannot be reassigned. I.e. why can't we use `int` instead of `enum` or `immutable`? Isnt it possible to come up with the interpreter compile-time, which will determine the operating time of the program at runtime at compile time. And if this time is small, it is possible to reassign variables at compile time more than once. Maybe it's something out of science fiction, but still. Is it possible somehow to create a more complex compilation process, which can reassign variables more than once?
Re: Is it possible to add items to the arrays and hashes at compile time?
On Wednesday, 10 June 2015 at 17:00:34 UTC, Dennis Ritchie wrote: Isnt it possible to come up with the interpreter compile-time, which will determine the operating time of the program at runtime at compile time. Sounds like the halting problem. So, no, generally this is not possible.
Re: Is it possible to add items to the arrays and hashes at compile time?
On Sunday, 7 June 2015 at 15:20:17 UTC, Ali Çehreli wrote: /* Some function that generates an AA */ Thanks. Beautiful code, but I want a little more :) /* Some function that generates an AA */ int[][int][int] initHash(int i) { /* It is nice to see that this function is not called at run time */ if (!__ctfe) { import std.stdio; writefln(%s is called at run time, __FUNCTION__); } return [i : [ i : [i, i] ] ]; } /* Question: Is there a function to merge two AAs? */ int[][int][int] merge(Hash)(Hash[] hashes...) { /* It is nice to see that this function is not called at run time */ if (!__ctfe) { import std.stdio; writefln(%s is called at run time, __FUNCTION__); } int[][int][int] result; foreach (hash; hashes) { foreach (key, value; hash) { result[key] = value; } } return result; } /* These three are generated at compile time */ enum firstPart = initHash(1); enum secondPart = initHash(2); enum int[][int][int] ctHash = merge(firstPart, secondPart); void main() { import std.stdio; static if (!(4 in ctHash)) {{ // ... }} ctHash[4][4] ~= [4, 4]; // I want this to work at compile time :) // Possible? static if (!!(4 in ctHash)) {{ // ... }} }
Re: Is it possible to add items to the arrays and hashes at compile time?
On Wednesday, 10 June 2015 at 03:38:32 UTC, Ali Çehreli wrote: The way I understand it and the way it makes sense to me, :) variables that are generated at compile time can be initialized only once. It is not possible after initialization. However, the initialization of the variable can be as complex as needed: Thanks. It turns out I can do this: import std.stdio; auto merge(Hashes)(Hashes[] hashes...) { int[][int][int] result; foreach (hash; hashes) { foreach (key, value; hash) { result[key] = value; } } return result; } enum firstPart = [1 : [ 1 : [1, 1] ] ]; enum secondPart = [2 : [ 2 : [2, 2] ] ]; int[][int][int] init_ctHash(int i) { auto result = merge(firstPart, secondPart); result[i] = [ i : [i, i] ]; return result; } void main() { enum int[][int][int] ctHash = init_ctHash(5); enum t = merge(ctHash, init_ctHash(6)); writeln(t); } But I can not do so: enum int[][int][int] ctHash = init_ctHash(5); ctHash = merge(ctHash, init_ctHash(6)); I have a question: why variables may not be initialized more than once? Why can't they to resave at compile time?
Re: Is it possible to add items to the arrays and hashes at compile time?
On 06/09/2015 06:53 PM, Dennis Ritchie wrote: ctHash[4][4] ~= [4, 4]; // I want this to work at compile time :) // Possible? It is possible but not exactly as you wrote. In other words, it is not as flexible. The way I understand it and the way it makes sense to me, :) variables that are generated at compile time can be initialized only once. It is not possible after initialization. However, the initialization of the variable can be as complex as needed: enum int[][int][int] ctHash = init_ctHash(); int[][int][int] init_ctHash(){ auto result = merge(firstPart, secondPart); result[4] = [4 : [4, 4 ]]; return result; } (I couldn't get ctHash[4][4] to work; so I changed the code like above.) Ali
Re: Is it possible to add items to the arrays and hashes at compile time?
On Sunday, 7 June 2015 at 12:30:12 UTC, Dennis Ritchie wrote: Does D the ability to add items to arrays and hashes at compile time? For example, how do I do it in compile time?: int[][int][int] hash; hash[4][6] ~= [34, 65]; hash[5][7] ~= [4, 78, 21]; try using a pure function + static e.g. int[][int][int] somePureDefaultHash() pure { ... //initialise it here } ... static hash = somePureDefaultHash();