-
Notifications
You must be signed in to change notification settings - Fork 29
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] New Generics #679
Comments
Can you explain what this means/how this works? I'm interested to know if the compiled jass looks any different. It seems that this is a pretty breaking change, and one that less experienced programmers are more likely to be confused by. vJass, older C++, and older Java (including what you might see as a student/junior engineer) prefer inheritance over type interfacing. Is it possible to ease the burden on wurst users, for example by gating this behind a feature flag?
|
Right now generic classes are simply classes, and the generic type is cast to int via the typecasting bug. Thus it is erased during compilation, similar to Java. The plan is to actually keep the type (allowing us to use the actual respective hashtable functions, e.g.) and not casting it to int anymore.
Not necessarily. Peq already mentioned that the old code could still be interpreted the old way, and basic usage of generics will stay compatible. Only unsafe casting like
Sure, but I don't think it is ever useful to make language features dependent on passed arguments. It will just always be a problem/confusion in the future, I believe. |
Is that also true for casting up/down an inheritance hierarchy? That's the use-case I envisage newer users to be abusing |
No, you would still be able to cast So I think this would be a minor incompatibility. |
This is the first step towards the new Generics design (see #679). This pull requests adds support for template generics. The behavior of existing code should not change. To use template generics, add a colon (`:`) after the type parameter name.
Updated section 2 on "restrict type parameters" |
Updated section 2 again. With these changes interfaces stay like they are, which should avoid some confusion for users and compiler implementers. I'll try to release a first version on the weekend (See PR #931). |
Thank you all for still working on this. It's making me want to give map-making a shot. I was almost scared away when I today looked up JASS, but seeing this makes me Keep up the good work! And don't let Reforged kill your spirits ❤️ |
Thanks. If by |
@peq revive new generics? :) |
Just started a real job this year. Probably gonna be some time before I'll be hacking Wurst again. |
Currently, generics are translated using erasure. This means, that generics can only be instantiated with types compatible with
int
. The idea of this proposal is to change the translation and instead of using erasure translation would generate one copy per instantiated type. This would allow to extend generics with some interesting new features, but would also be incompatible in some cases.Language changes:
1. Allow all types for generics
Every type can be inserted for a generic type parameter without any restrictions.
For example, we can then use
LinkedList<vec3>
.This also allows us to get rid of the implicit calls to
fromIndex
andtoIndex
that we currently have as a woraround.2. Allow to restrict type parameters / type classes
Sometimes we want to restrict type parameters.
For example
LinkedList<T>.toString() returns string
only can be implemented, if we have a methodtoString(T) returns string
.We could of course provide this method using an additional argument:
However, it is not very convenient to always pass this
Show
value explicitly.Instead we allow to use generic interfaces as type constraints:
The compiler automatically finds instances that are defined with the new
instance
definitions:If multiple instance are in scope there is a compilation error.
The instantiation is part of the type, so the following example is not allowed:
To resolve instances, we first match the parameters and then match the type constraints from left to right.
Type class translation: The translation uses monomorphization (like traits in Rust) when translating to Jass and dictionary passing when translating to Lua.
3. Disallow casting to int
Since we now allow all types to be used for type parameters, we can no longer cast type parameters to
int
. However, we can use the new feature of restricted type parameters to implement the same feature:Old
HashMap
:New
HashMap
To simplify the transition, we could automatically interpret the old code as the new one.
Also we can automatically create some useful instances for all classes, for example the Indexable above.
A challenge here is that for Jass and Lua different type classes would make sense:
Casting classes to int in Lua is an ugly and leaky workaround and not really needed as we have tables to store stuff without indexes.
4. Disallowing casting between different instantiations
Currently the following code is valid:
With the proposed changes this would still compile, but might no longer work, since translation might create complete different code for
List<A>
andList<B>
.Maybe it makes sense to guarantee that all instantiations with class types share the same code (same as it is now), but this is difficult to implement in combination with typeclasses.
The text was updated successfully, but these errors were encountered: