-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
[superseded] new macro for generic reflection: extractGeneric(Foo2[float, string], 0) is float
#8554
Conversation
extractGeneric(Foo2[float, string], 0) is float
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.
Also solves #6454 (typetraits feature request - get subtype of a generic type).
This should be in typetraits not in sugar. Regarding name, since we have genericHead
, maybe generic
alone (or genericTail
?) to match the naming.
Regarding signature, I feel like it should have a default value of 0:
macro extractGeneric*(T: typedesc, index:static[int] = 0): untyped =
that seems arbitrary esp in case generic has a number of params different from 1, if there's a default, it should be |
As an alternative, I've considered adding an indexing operator over the tuple type, which returns the respective element type: (int, float)[1] is float Then this feature may be more elegant if the API looks like this: MyGenericType.genericParams[1] Here, |
cool but can that happen sooner rather than later? I tried adding it as a proc but didn't work: template `[]`*(T: typedesc): auto = #Error: no generic parameters allowed for Foo
var ignore:T
type(ignore[i])
import typetraits
let a=(1,"foo")
echo type(a)
type Foo=type(a)
echo Foo[0] # error or should that be in "proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =" ? EDIT one concern though: there obviously should be no runtime impact, but could that affect compile time / compile memory usage, if this is used extensively (even indirectly), whereby a whole type tuple (Foo,T0,T1) is returned instead of just the requested element? |
I have a different approach. I wrote a type normalization algorithm. You can see it here: If I add this procedure to the macros library, it would solve this problem. The advantage here is that the result of the result of normalizeType is a type expression, it can be printed. It even handles aliases with generic arguments recursively. |
1c669ab
to
3ed1b6e
Compare
ok I finally revived this PR and resolved conflicts; it's now hitting a regression unfortunately, see #9855 @krux02 EDIT: hold on, I may see what you mean... |
@timotheecour when you normalize the type, you get a type expression of |
No RFC for this, in the wrong place and should use 0 instead of -1 for head. And then we need to maintain it and document all its edge cases. Rejected for now. |
There was a feature request though: #8554 |
@mratsim I think you pasted the wrong link. |
extractGeneric(Foo2[float, string], 0) is float
extractGeneric(Foo2[float, string], 0) is float
extractGeneric(Foo2[float, string], 0) is float
extractGeneric(Foo2[float, string], 0) is float
/cc @mratsim
seq[int].T is int
should compile (and be true) according to spec; also fails withtype seq2[T] = T
#8433in some contexts (IMO in most contexts), it's better to access generics by index rather than by name as mentioned by @mratsim here #8459 (comment)
I also agree with that sentiment (see #8433 (comment)), mainly because it avoids polluting scope with a generics's parameters.
a user writing
Foo.Bar
may be expectingBar(Foo)
when in fact compiler interprets as accessing generic param Bar from generic type Foo.