Struggling with Valhalla conversion of library

Philippe Marschall kustos at gmx.net
Sun Aug 4 21:44:07 UTC 2019


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