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