-
-
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
make genericParams support static[T] generic params #13433
Conversation
lib/pure/typetraits.nim
Outdated
runnableExamples: | ||
type Foo[T1, T2]=object | ||
doAssert genericParams(Foo[float, string]) is (float, string) | ||
type WrapStatic*[Val] = object |
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.
Do not export this.
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.
that's needed for generic code though, so user can tell whether generic param returned by genericParams
is a static or a regular type (in fact the runnableExamples + ttypetraits tests would fail without exporting it)
the only other possibility I can think of is providing a new proc proc isWrapStatic*(T: typedesc): bool
to test for that but that's just more complex
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.
Hmm can't it produce static 1.0
instead of WrapStatic[1.0]
?
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 can't work:
type Foo = (int, static[2])
Error: type expected, but got: 2
type Foo = (int, static[2])
that's why WrapStatic is needed
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.
Ping @zah
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.
I'm not sure why WrapStatic[T]
works. I guess somebody relaxed the rules for matching generic parameters in another PR. I've never intended for the following to work, but Nim-devel seems to be happy about it:
type
Foo[T] = object
var x: Foo["test"]
For me, this signature of Foo
should allow only type parameters. Even worse version of the code is the following:
type
Foo[T] = object
x: T
var x: Foo["test"]
echo x
It currently compiles and prints:
(x: "")
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.
(see #13529)
but there's no typeclass for static (representing tyStatic) at the moment, eg:
type WrapStatic[T:static] = object
doesn't work (while type WrapStatic[T: static[float]]
does, but that's not useful here)
so we should support type WrapStatic[T: static] = object
, regardless of whether [T]
should be allowed to match to a static (that's a debate to have elsewhere).
I think the way I wrote it is fine for today's nim, and once we add support for [T: static]
, we'll simply update this code to use type WrapStatic[T:static] = object
instead
this can happen transparently without breaking any code that uses genericParams
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.
I guess I'm not fundamentally opposed to WrapStatic
. It's helpful that it has less degrees of freedom when compared to tyStatic
. I would call it StaticParam
and then name the payload param value
as it is possible to access it with the dot operator.
But all of this won't be necessary if we give up on the notion that genericParams
should return a tuple type. We could have had another trait genericParam(N): typedesc
that doesn't have these issues.
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.
I would call it StaticParam and then name the payload param value as it is possible to access it with the dot operator.
done
But all of this won't be necessary if we give up on the notion that genericParams should return a tuple. We could have had another trait genericParam(N): typedesc that doesn't have these issues.
Note that this was my previous approach (#8554) but returning a tuple (which was your suggestion) is a better API, in particular it avoids needing 2 separate APIs (genericParam(N) + genericParamLen).
That being said, I don't understand this argument, you'd have the exact same problem with genericParam(N)
if the Nth generic param is static:
type Bar[N: static int, T] = object
type Bar3 = Bar[3, float]
type t = genericParams(Bar3, 1)
doAssert t is float
type t2 = genericParams(Bar3, 0) # won't work unless you also use StaticParam
(or you'd need yet another API to check whether the N'th param is static, eg
when genericParamsIsStatic(N):
const value = genericParamsValue(N)
else:
type t = genericParams(N)
what I have in this PR is arguably much simpler to use, see usage in tests in ttypetraits.nim, eg:
doAssert genericParams(Bar3) is (StaticParam[3], 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.
Yeah, I've gone through the same motions in my own thinking.
Perhaps one day typedescs-as-values will have their revenge and we'll be able to make an alternative to genericParams
that returns a real tuple value, not a type:
doAssert generamParams(Bar3) == (3, float)
Anyway, merging this is fine to me, but it would be nice if the funny business in #13529 is not postponed for later.
0bb4f10
to
6f61c6a
Compare
@Araq is anything else needed in this PR? |
b983986
to
c3f267c
Compare
c3f267c
to
5d62255
Compare
before PR:
genericParams
didn't work with a generic containing static params (egstatic int
)after PR: this works.
example