Struggling with Valhalla conversion of library
Srikanth
srikanth.adayapalam at oracle.com
Wed Aug 7 04:21:25 UTC 2019
Hi Philippe,
Thanks for the report. Yes you have discovered a bug in javac's handling
of ? in the context of lambdas. This came in from another source too - I
am investigating a fix. Stay tuned.
Srikanth
On 05/08/19 3:14 AM, Philippe Marschall wrote:
> Hi
>
> As you published the LW2 prototype I thought I tried to convert one of
> my libraries [1] to Valhalla and see how it goes. Right now I'm
> struggling with generics.
>
> Some context about the library. The library implements a range tree that
> allows to map a range of keys to a single value. Eg. {[100,199] -> "1",
> [200,299] -> "2"}. The library should support both inline and reference
> types as keys and values.
> The potential for inline classes is limited as the tree nodes are
> mutable and recursive. There are however two good candidates, the range
> class and an unsigned 96bit integer class (called U96) that is provided
> for convenience.
>
> The unsigned 96bit integer class was easy to convert. I had to change
> it to implements Comparable<U96?>. I am not yet sure how I want to treat
> null / 0.
> But there are two cases where I struggled.
>
> First, I have an interface
>
> public interface AdjacencyTester<T> {
>
> boolean areAdjacent(T low, T high);
>
> }
>
> I want to implement this for the unsigned 96bit integer class (called
> U96). Right know in Java 8 this is implemented as
>
> public static AdjacencyTester<U96> adjacencyTester() {
> return (low, high) -> {
> // lambda body
> };
> }
>
> Simply converting this to
>
> public static AdjacencyTester<U96?> adjacencyTester() {
> return (low, high) -> {
> // lambda body
> };
> }
>
> did not work, I got
>
> com/github/marschall/rangetree/key/U96.java:[51,12] incompatible types:
> incompatible parameter types in lambda expression
>
> Converting it to an anonymous inner class worked
>
> public static AdjacencyTester<U96?> adjacencyTester() {
> return new AdjacencyTester<U96?>() {
> public boolean areAdjacent(U96? low, U96? high) {
> // method body
> }
> };
>
> }
>
> Using U96? as types for the lambda arguments did not compile
>
> public static AdjacencyTester<U96?> adjacencyTester() {
> return (U96? low, U96? high) -> {
> // lambda body
> };
> }
>
> Compilation failure:
> /src/main/java/com/github/marschall/rangetree/key/U96.java:[51,16] ')'
> expected
> src/main/java/com/github/marschall/rangetree/key/U96.java:[51,21] :
> expected
> src/main/java/com/github/marschall/rangetree/key/U96.java:[51,32] ';'
> expected
>
> Second I have a simple Range class which is supposed to hold both
> reference and inline types. That was easy to convert but integrating
> into my existing interfaces failed.
>
> public inline class Range<E> {
>
> private E low;
> private E high;
>
> In my RangeMap interface I have #computeIfAbsent similar to the one from
> Map.
>
> V computeIfAbsent(K key, Function<? super K, Entry<Range<? extends K>, ?
> extends V>> mappingFunction)
>
> src/main/java/com/github/marschall/rangetree/RangeMap.java:[52,59]
> unexpected type
> [ERROR] required: reference
> [ERROR] found: com.github.marschall.rangetree.Range<? extends K>
>
> I tried to switch to
> Range<? extends K?>
>
> but that did not help.
>
> You can find the code and building instructions here [2]
>
> [1] https://github.com/marschall/range-tree
> [2] https://github.com/marschall/range-tree/tree/valhalla
>
> Cheers
> Philippe
More information about the valhalla-dev
mailing list