Re: Tuple enumeration without integers or strings

2021-01-03 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 3 January 2021 at 13:36:57 UTC, Paul wrote:

Is there an easy way for me to know when code is assessed / 
generated at compile time?
For example, is indexing a constant compile time array compile 
time or run time?
Or how about functions? The hashOf documentation does not seem 
to hint to being done at compile time.


It's not what you do, but the context in which you do it. If a 
function must be evaluated at compile time, it will be.


```
string tellme() {
if(__ctfe) return "Compile Time";
else return "Run time";
}

void main()
{
writeln(tellme());
pragma(msg, tellme());
writeln(tellme());
}
```

Since the msg pragma is a compile-time construct, tellme *must* 
be evaluated at compile time. The calls to writeln are just 
normal function calls, therefore the calls to tellme happen at 
runtime.


So any context where you replace a compile-time constant with a 
function call, you'll have CTFE (as long as it's possible [1]). 
It's common to use enum to force CTFE:


enum s = tellme();

[1] https://dlang.org/spec/function.html#interpretation


Re: Tuple enumeration without integers or strings

2021-01-03 Thread Paul via Digitalmars-d-learn

On Sunday, 3 January 2021 at 06:05:48 UTC, frame wrote:

The hash is also generated at compile time.


Is there an easy way for me to know when code is assessed / 
generated at compile time?
For example, is indexing a constant compile time array compile 
time or run time?
Or how about functions? The hashOf documentation does not seem to 
hint to being done at compile time.


Re: Tuple enumeration without integers or strings

2021-01-02 Thread frame via Digitalmars-d-learn

On Sunday, 3 January 2021 at 04:16:20 UTC, Paul Backus wrote:

On Sunday, 3 January 2021 at 02:41:12 UTC, Paul wrote:


hashOf is not guaranteed to produce unique values, so I would 
not advise using it here.


Of course it's a hashing method but also internally used for 
comparison and good enough, at least in that example code. By 
using an enum I don't assume there will be that much members to 
take care of anyway. The hash is also generated at compile time.




Re: Tuple enumeration without integers or strings

2021-01-02 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 3 January 2021 at 02:41:12 UTC, Paul wrote:


I haven't used hashOf before, though assuming no  equal values, 
which I generally wouldn't do, I take it this is reliable? I 
haven't tried it before, and I dont know how to effectively 
compare it to using 'switch(w.to!string)' & 'case 
Wind.B.stringof' (regarding speed/reliability).


hashOf is not guaranteed to produce unique values, so I would not 
advise using it here.


to!string is expensive both at compile time (requires a lot of 
template instantiations) and runtime (needs to allocate memory 
for the string). It will work if you need to hack something 
together quickly, but I would not recommend it for "serious" code.


Re: Tuple enumeration without integers or strings

2021-01-02 Thread Paul via Digitalmars-d-learn

On Sunday, 3 January 2021 at 02:17:43 UTC, frame wrote:

Besides the problem with equal values, what's wrong with that:

alias Thing = Tuple!(int, int);
enum Wind {
A = Thing(0, 1),
B = Thing(0, 2),
C = Thing(0, 2)
}

void some_function(Wind w) {
switch (w.hashOf) {
case Wind.B.hashOf:
break;

default:
assert(0);
}
}

void main() {
some_function(Wind.B);
writefln("%d%d", Wind.C.expand);
}


I haven't used hashOf before, though assuming no  equal values, 
which I generally wouldn't do, I take it this is reliable? I 
haven't tried it before, and I dont know how to effectively 
compare it to using 'switch(w.to!string)' & 'case 
Wind.B.stringof' (regarding speed/reliability).


Re: Tuple enumeration without integers or strings

2021-01-02 Thread frame via Digitalmars-d-learn

On Sunday, 3 January 2021 at 01:15:56 UTC, Paul wrote:

On Saturday, 2 January 2021 at 21:48:04 UTC, Paul Backus wrote:
Yes, but this will be true of any approach you choose. If two 
enum members have exactly the same value, there is no way to 
distinguish between them, either at compile time or at runtime.


Oh I see, thanks!
A bit of a bummer as I guess that means you're pretty much 
required to use an additional seperate structure like an array 
or map/associative array, the latter making the use of an enum 
instead of string names slightly pointless in this scenario, 
thank you nontheless .


Besides the problem with equal values, what's wrong with that:

alias Thing = Tuple!(int, int);
enum Wind {
A = Thing(0, 1),
B = Thing(0, 2),
C = Thing(0, 2)
}

void some_function(Wind w) {
switch (w.hashOf) {
case Wind.B.hashOf:
break;

default:
assert(0);
}
}

void main() {
some_function(Wind.B);
writefln("%d%d", Wind.C.expand);
}


Re: Tuple enumeration without integers or strings

2021-01-02 Thread Paul via Digitalmars-d-learn

On Saturday, 2 January 2021 at 21:48:04 UTC, Paul Backus wrote:
Yes, but this will be true of any approach you choose. If two 
enum members have exactly the same value, there is no way to 
distinguish between them, either at compile time or at runtime.


Oh I see, thanks!
A bit of a bummer as I guess that means you're pretty much 
required to use an additional seperate structure like an array or 
map/associative array, the latter making the use of an enum 
instead of string names slightly pointless in this scenario, 
thank you nontheless .


Re: Tuple enumeration without integers or strings

2021-01-02 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 2 January 2021 at 21:41:34 UTC, Paul wrote:

On Saturday, 2 January 2021 at 03:20:29 UTC, Paul Backus wrote:
D's switch statement only works on strings and integers. For 
more complex values, the easiest thing is to just use an 
if-else chain.


If you really want to use a switch statement, you can do it by 
defining a function that maps each of your enum values to a 
unique integer; for example:


Im afraid that would still result in issues when duplicate enum 
vlues are at play right?


Yes, but this will be true of any approach you choose. If two 
enum members have exactly the same value, there is no way to 
distinguish between them, either at compile time or at runtime.


Re: Tuple enumeration without integers or strings

2021-01-02 Thread Paul via Digitalmars-d-learn

On Saturday, 2 January 2021 at 03:20:29 UTC, Paul Backus wrote:
D's switch statement only works on strings and integers. For 
more complex values, the easiest thing is to just use an 
if-else chain.


If you really want to use a switch statement, you can do it by 
defining a function that maps each of your enum values to a 
unique integer; for example:


Im afraid that would still result in issues when duplicate enum 
vlues are at play right?

(This issue would maybe warrant a compile time warning imho)


Re: Tuple enumeration without integers or strings

2021-01-01 Thread Paul Backus via Digitalmars-d-learn

On Friday, 1 January 2021 at 23:14:43 UTC, Rekel wrote:
I seem to have hit a bit of a wall when comparing D enums to 
Java enums.
Of course the latter is just a fancy class, though it'd be nice 
to see partially equivalent usefulness regardless.


For example, as soon as non-integer, non-string values are 
given to enums things get messy for me when using switch cases, 
I haven't yet found a satisfying way of doing this.


D's switch statement only works on strings and integers. For more 
complex values, the easiest thing is to just use an if-else chain.


If you really want to use a switch statement, you can do it by 
defining a function that maps each of your enum values to a 
unique integer; for example:


enum Wind { ... }

size_t index(Wind w)
{
if (w = Wind.N) return 0;
// etc.
}

void someFunction(Wind w)
{
switch(w.index) {
case Wind.N.index: // uses CTFE
// ...
break;
// etc.
default: assert(0);
}
}


Re: Tuple enumeration without integers or strings

2021-01-01 Thread frame via Digitalmars-d-learn

On Saturday, 2 January 2021 at 00:57:48 UTC, Paul wrote:

So this neither seems a satisfiable solution to me :/


Couldn't you just use Wind.N.hashOf and a custom format() 
expression for string-representation?





Re: Tuple enumeration without integers or strings

2021-01-01 Thread Paul via Digitalmars-d-learn
It seems w.to!string works in conjunction with Wind.N.stringof, 
though I wonder about the efficiency/wastefulness of this method.
Sadly this also leads to very funny behavior when some of the 
enums have the same value, as to!string(Enum) will yield the name 
of the first of these enums having the same values.



alias Thing = Tuple!(int, int);
enum Enum {
A = Thing(0, 1),
B = Thing(0, 2),
C = Thing(0, 2)
}
void main(){
Enum.C.to!string.writeln;
}


For example, the code above will print 'B' (I'm slightly curious 
how & why std.conv uses the Enum name when converting to string, 
instead of using the value, especially since I didn't see this 
pitfall coming partly due to this)


So this neither seems a satisfiable solution to me :/


Tuple enumeration without integers or strings

2021-01-01 Thread Rekel via Digitalmars-d-learn
I seem to have hit a bit of a wall when comparing D enums to Java 
enums.
Of course the latter is just a fancy class, though it'd be nice 
to see partially equivalent usefulness regardless.


For example, as soon as non-integer, non-string values are given 
to enums things get messy for me when using switch cases, I 
haven't yet found a satisfying way of doing this.
Note the reason I'm using tuples is to somehow replicate the way 
java enumerals can contain several member variables, which tends 
to be very useful.


Something along the lines of the following is what i'd like to 
achieve;

alias Direction = Tuple!(byte, "x", byte, "y");
enum Wind {N = Direction(0, 1) ... etc}
...
void some_function(Wind w) {
switch (w) {
case Wind.N:
... etc
break;
... etc
default:
assert(0);
}
}


One thing that might have worked would have been an equivalent of 
java's "ordinal", though from what I've found D doesn't seem to 
have something equivalent to this?
(I'd prefer not to have a seperate tuple member purely for 
ordinality, and dropping enumerals altogether also seems like a 
waste)