-
Notifications
You must be signed in to change notification settings - Fork 152
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
Port POSet
to Java
#4103
Port POSet
to Java
#4103
Conversation
8e6c5b1
to
6079e63
Compare
@@ -1,2 +1,2 @@ | |||
[Error] Compiler: Had 1 parsing errors. | |||
[Error] Compiler: Illegal circular relation: Exp < ExpList < Exp | |||
[Error] Compiler: Illegal circular relation: ExpList < Exp < ExpList |
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.
The output is unstable because it's based on the iteration order of relations.entrySet()
, but I don't see a clean way to address 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.
We can revisit this in the future if it becomes a worse problem; this code is pretty stable and so long as we aren't doing further big changes here we should be fine!
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.
If we care more that there's a circularity, and less what the circularity is, we could sed
out the example given in the error message.
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 pleasantly surprised by how nicely the Java code comes out to be here!
import java.util.function.Supplier; | ||
|
||
@FunctionalInterface | ||
public interface SerializableSupplier<T> extends Supplier<T>, Serializable {} |
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.
Where does the need for Serializable
come in? I presume you've thought this all through, just curious what the technical reason is!
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.
The root of the issue is that lambdas and method references are not serializable by default. Instead, they are only serializable when constructed in a context whose target type is Serializable
(https://stackoverflow.com/questions/25391656/serialization-of-a-lambda-after-its-creation).
In particular, this means that the Supplier<T>
in each Lazy<T>
in the POSet
is not guaranteed to be serializable, giving errors when trying to serialize the overall POSet
. We fix this by instead requiring SerializableSupplier<T>
.
As for why the overall POSet
needs to be serializable in the first place, this was admittedly error driven development - the original POSet
class extends Serializable
, and removing it causes tests to fail!
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.
Looks good; I'm impressed by how readable the Java translation is and how minimal the API surface change is. Nice work!
Part of #4030.
Port the
POSet
class from Scala to Java.This is mostly a straightforward conversion from Scala functional idioms (
map
,filter
,reduce
, etc.) to the corresponding Java Stream methods. To portlazy val
s, we also implement aLazy<T>
wrapper which caches the result of aSupplier<T>
.The only remaining reference to Scala here is a single constructor which takes a
scala.collection.Set<Tuple2<T, T>>
and internally converts it to ajava.util.Set<Pair<T, T>>
. This can be removed once we more pervasively switch away from Scala collection types everywhere in the codebase.