-
Notifications
You must be signed in to change notification settings - Fork 39
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
RFC: Constraints on generic parameters #50
base: master
Are you sure you want to change the base?
Conversation
Constrained generics are absolutely something we're going to look at eventually, but this RFC needs a much more compelling example to properly justify them. In your "Drawbacks" section, you point out a perfectly reasonable solution to your problem that doesn't require generics at all. A more compelling example would be something like |
Thanks for the feedback, I have tried to add more complelling reasons, as well as more examples as to why this could be useful, some even including real world use cases, such as a Dependency Injection service container, or a factory like |
fireGun("Hello, world!") -- Type Error: type 'string' and 'Gun' are not related to one another. | ||
``` | ||
|
||
The syntax for defining a generic function would remain the same, except, instead of simply taking a `T`, we would take a `T : TypeConstraint`, the syntax remains similar to other features of the language, and it would work by checking if the type that `T` is inferred to be has any kind of relationship with `TypeConstraint`. However, we may also want to be explicit when we are doing generics on this way, therefore a syntax to properly and explicitly specify which types the function takes in its current call would be preferred, this way, we no longer have to use turbofish to type cast into the correct return type `U` constrained by `WeaponResult`. |
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 don't know why you're mentioning turbofish, that doesn't exist in Luau, and can't because it's ambiguous with :: <T>() -> ()
.
No turbofish is also not an option for the exact same reasons it's necessary in Rust.
local a, b = the<guardian, stands>(resolute)
...is perfectly valid code today.
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 remember discussing with Drak that f.<T, U>()
isn't the worst syntax in the world, but also it feels out of scope for this RFC anyway?
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.
You're right, it feels out of scope for this RFC to add on about, and it was already somewhat addressed on the original generic functions rfc
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.
although I did not know that that snippet was valid ever, however, all I keep getting from attempting it is syntax errors
I think I would also like to see 2 more things: Type parameters are allowed to reference each other despite the lexical ordering, e.g. A Here's a full EBNF describing the potential syntax, formally: typaram ::= <NAME> [':' ty]
typarams ::= typaram {',' typaram}
tpparam ::= <NAME> '...' [':' tp]
tpparams ::= tpparam {',' tpparam}
params ::= (typarams tpparams?) | tpparams
tybound ::= ty [':' ty]
tybounds ::= tybound {',' tybound}
tpbound ::= tp [':' tp]
tpbounds ::= tpbound {',' tpbound}
bounds ::= (tybounds tpbounds?) | tpbounds
paramdecl ::= '<' params ['where' bounds] '>' |
This RFC is a possible implementation on what could be an improvement to the current generics system, by allowing generic types to be constrained, just as in any other language's implementation of generics, which would allow for generics to be used in other seemingly unrelated places, like more efficient native code generation.
rendered