-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Support calling signature polymorphic methods (needed to use MethodHandle
and VarHandle
)
#11332
Comments
This comment has been minimized.
This comment has been minimized.
Hi @smarter is there a workaround / hackaround for this by any chance? Eg some way to generate pure Java at compile-time or similar? If it works, Scala 3 macros + VarHandles/MethodHandles = <3 |
I don't think there's any workaround besides writing the calls in java files |
Thanks for getting back so quickly @smarter . Just to add, I was doing simple calls like
and:
Changing the code to have type-casting with
I do appreciate it's a completely new compiler - because it looks like a regression (or I missed some sort of migration document), would there be a chance to prioritize this? I imagine there might be a few Scala codebases that might not be able to take the leap because of this. |
I'd be happy to help along anyone who wants to port the scala 2 implementation of this feature but I don't have the time to deal with it myself, and I don't know if anyone else does. |
I would like to work on this issue, but I have not yet contributed to the Scala 3 compiler and I'm honestly not sure where to begin. It seems to me that the Scala 2 code cannot be easily ported to the new compiler. I'd appreciate any pointers. |
Seconding the above. I looked, and I don't know how the scala 2 code corresponds to the scala 3 code. |
Welcome! Some pointers:
I think the Scala 2 approach could work in Scala 3 too, but we also store our typed trees into tasty and can deserialize them at any point (for example, when calling an It might be worth exploring alternative approaches which don't involve creating fake symbols, but as mentioned in scala/scala#4139 this is likely to touch many parts of the compiler. I had a quick look just now and it seems pretty daunting indeed. |
Thank you for the great list of resources @smarter. I will take some time to internalize everything and hopefully come up with a PR. Thank you again. |
I've been working on this issue for 2 days now, but I am unable to make any progress. The code in the type checker, while I mostly know where to put it and what to aim for, I am unable to translate the Scala 2 compiler code to the Scala 3 compiler code. I'm especially having difficulty trying to copy symbols and modify them, as well as the purpose of the I would appreciate any help that anyone could provide, because for the moment I'm stuck, with no clear way to proceed. |
I'd expect you'd need something like
Type-checking proceeds top-down: at every level we have a tree we want to give a type to and an "expected type" aka "prototype", for example in |
I found the |
Indeed, looks like you need to do |
Guillaume walked Dale through how to add the needed code to typer, inspired by Jason's patch but with the right Dotty details. We did that and have a basic test case passing. (Dale will push a WIP branch soon, I expect.)
Minor hurdle: (Aside: It might be nice if we didn't always make a fresh symbol at every call site, even if we already saw a call site with the same types. But probably it isn't worth doing the extra work to add a cache.) Bigger hurdle: TASTy support. If we do nothing, the TASTy unpickler blows up because the type of the method we're calling doesn't match the types at the call site anymore. Two possible solution paths:
|
Glad to see competent people on this issue and not me. 😄 |
I think we need a name for the competent team. (Besides Goofus & Gallant.) I would propose "Chip 'n' Dale", but then we'd have to start calling Seth "Chip". |
It seems to Dale and me that we are required here to be Gallant and do it it the right way. Forward compatibility isn't possible here, so we need a bumped TASTy version to signal that, and if we're bumping the TASTy version anyway, we might as well add the new node type. |
A small wrinkle here is that the definition of polymorphic signature methods in the Java Language Specification broadened in JDK JLS 8 wording at https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html is:
The JLS
Compared to JLS 8, the mention of |
I wouldn't hard code the class or method names on the unpickler side, just trust the pickler to do something sensible |
Dale pushed new code with the TASTy support. We're about 95% of the way there, I think. I will do the generalization to the additional JDK
|
Fantastic work. I'm looking forward to this feature. Thank you for the updates. Very much appreciated. |
@SethTisue @dwijnand do you think you'll manage to finish this for 3.2 (which is scheduled to be the next release) or should we defer this to 3.3? |
thanks for the reminder — tbh, I'd forgotten (but self-assigning should prevent that from happening again). this week is pretty tight for me, timewise. how much more time do I have, when is 3.2 coming? |
Please don't rush with the implementation. Personally, I'm fine if it lands in 3.3. I will also help you test it. Cats Effect is a bit stuck on 3.0 for now in any case, there's really no pressure here. |
You can see the tentative release date of 3.2.0-RC1 on https://github.com/lampepfl/dotty/milestones (currently march 9) |
It seems plausible we could make that. I'll try. (And I'll keep Vasil's remarks in mind.) |
3.2.0-RC1 has been delayed until April 27 (https://github.com/lampepfl/dotty/milestones) if you want another chance at this :). |
Recent related PR on the Scala 2 side: scala/scala#9930 |
ping to get the status for this. If it should be in 3.2 we need to merge it this week, or next at the latest |
A very simple workaround for those who need this now.
Instead of |
Please note that while the above workaround does work, it's still not great. I've restarted development of my slinc library, and it uses methodhandles. The implementation using this approach runs at 93 ops/us, while a version using a hardcoded invokeExact runs at 147 ops/us. I cannot use inokeExact right now because Scala 3 trips over it when trying to compile it. If it weren't for that, I could write the optimal form of any method binding using invokeExact and macros. Boxing is really costing a lot here, so I hope that support for PolyMorphicSignature methods comes soon and frees me from it. |
Guillaume, Dale, and I will revisit this today (for 3.3.0-RC1) Dale's WIP branch is https://github.com/dwijnand/scala3/tree/support-poly-sigs
|
MethodHandle
and VarHandle
)
This comment was marked as outdated.
This comment was marked as outdated.
LOL, we were maybe 25% of the way there |
ach, the painful reality:-) |
blog post, for publication once this makes it into an RC: scala/scala-lang#1428 UPDATE: now published at https://scala-lang.org/blog-detail/2023/07/17/signature-polymorphic-methods.html |
See scala/scala#4139, scala/scala#5594, scala/scala#9530, scala/scala#9930
The text was updated successfully, but these errors were encountered: