-
-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enum Type Inference #230
Enum Type Inference #230
Conversation
Co-authored-by: Nick Treleaven <ntrel002@gmail.com>
DIPs/1NNN-AP.md
Outdated
| struct B{ A one, two; } | ||
|
|
||
| void main(){ | ||
| A myA1 = $b; //myA1 = A.b |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should compound expressions work? E.g. A x = $a | $b;. Ditto for return $a | $b;.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should compound expressions work? E.g.
A x = $a | $b;. Ditto forreturn $a | $b;.
I think I'm unfamiliar with this syntax, what does bitwise ORing two enum members result in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same thing as if you were bitwise ORing their base type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gives A:
pragma(msg, typeof(A.a | A.b));(It would be better if that produced an integer, but it doesn't).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh dear... this is some... interesting baggage you two have uncovered that I would've never even thought about.
From my testing, I think it works like this:
enum A{ a,b,c,d }
enum B{ a,b,c,d }
A.a | A.b /*becomes*/ cast(int)A.a > cast(int)A.b ? A.a : A.b
2 | A.b /*becomes*/ 2 | cast(int)A.b
A.a | B.b /*becomes*/ cast(int)A.a > cast(int)B.b ? cast(int)A.a : cast(int)B.bSo, the answer to ntrel's question "Should compound expressions work?" is yes, since only ORing two enums of the same type produces an enum of that type, everything else produces an int.
I think this raises a better question though. Should this work? ;)
enum A{ a,b,c,d,e,f,g,h }
auto myA = cast(A)($b | 2 | $e); //oh no what is going onIn my opinion, no. I can't comprehend what in the world someone would be trying to achieve by doing this, haha!
P.S. I'll edit my examples to demonstrate ORing with ETI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Just to point out, enum ORing is typically used with non-overlapping enum values such as a=1, b=2, c=4, d=8, e=16 etc to pass multiple flags as a function argument. So a | c would be 5. Then the parameter received can be ANDed with c to see if c is set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Just to point out, enum ORing is typically used with non-overlapping enum values such as a=1, b=2, c=4, d=8, e=16 etc to pass multiple flags as a function argument. So a | c would be 5. Then the parameter received can be ANDed with c to see if c is set.
Saying that, I think a syntax like this would be very useful for C API wrappers. would Do you know if it would be feasible to make this work without breaking changes?
enum Flags{ a=1,b=2,c=4,d=8 }
void setFlags(int flags);
int flagVar;
void main(){
setFlags(Flags.a | $b | $d);
flagVar = Flags.d + $a + $a;
flagVar = Flags.b & $c;
}I'm picturing it having the same rules as the array literal syntax. (first—or maybe closest to the left?—enum type used for ETI, can be interchanged with integers, maybe floats)
This comment was marked as resolved.
This comment was marked as resolved.
… noted that switch-case syntax is undergoing revision.
|
I'd love to write a "grammatical changes" section, but I'm honestly not sure what D grammar is the equivalent of " |
|
I think just add |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In simple cases, this is just an excellent way to save on typing. More difficult question is, how far should inference of the enum type go? One case to consider in general is derived types, meaning can
enum C{ e,f,g,h }
enum D:C{ i=C.f, j=C.g }...recognise members of each other with ETI?
If we were to go really ambitious with this, we could say that ETI should apply to any assignment, not just to assignment to enums. For example, we could do int x = $min, or Monotime time = $currTime. But this would be quite a mission creep so I won't say you should go there.
I don't see why that shouldn't work. I've tweaked the DIP's wording so that it doesn't sound like it's explicitly ruling this out, at least. For instance, your example is a type delcaration; I didn't give any examples involving type delcarations, but your example follows the principle of all other cases where ETI should be allowed.
Don't worry, I would love to author future DIPs for this, but I think that ETI should come first. Think there's very little to disagree over about ETI. It's a simple, lovely little QoL feature that I sorely miss when using D over, say, Swift. One step at a time is the way to go. If everyone can agree on a little change, then a bigger change in the same vein will have an easier time going through the review stages since it'll have fewer issues on its own. If I wrote a DIP for inference of EVERYTHING… well, I would be so overwhelmed with revising it that I would go insane! |
No description provided.