Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Useful Applications of Intersection Types using Local Type Inference

As stated by this blog, we are now able to write the following using local type inference (something, to my knowledge, that was previously impossible without introducing more code):

public static void main(String... args) {
    var duck = (Quacks & Waddles) Mixin::create;
    duck.quack();
    duck.waddle();
}

interface Quacks extends Mixin {
    default void quack() {
        System.out.println("Quack");
    }
}

interface Waddles extends Mixin {
    default void waddle() {
        System.out.println("Waddle");
    }
}

interface Mixin {
    void __noop__();
    static void create() {}
}

This question may be either too broad or primarily opinion-based, but do there exist any useful applications when taking advantage of intersection types like this?

like image 304
Jacob G. Avatar asked Mar 21 '18 15:03

Jacob G.


2 Answers

Dealing with partially unknown types is possible since Java 5, so it’s quite easy to backport your example to Java 8:

public static void main(String... args) {
    use((Quacks & Waddles)Mixin::create);
}
private static <Duck extends Quacks & Waddles> void use(Duck duck) {
    duck.quack();
    duck.waddle();
}
interface Quacks extends Mixin {
    default void quack() {
        System.out.println("Quack");
    }
}
interface Waddles extends Mixin {
    default void waddle() {
        System.out.println("Waddle");
    }
}
interface Mixin {
    void __noop__();
    static void create() {}
}

So the possibility to do the same using var in Java 10 allows, well, to do the same as before, but with slightly less source code. And being able to do the same things as before but with less boilerplate code is exactly what var is about, whether you use intersection types or not.

like image 83
Holger Avatar answered Nov 15 '22 02:11

Holger


You can sort of do that in java-8 too:

static class ICanDoBoth implements Quacks, Waddles {
    // implement void __noop__(); here...
}

public static void both(Object b) {
    // my point here is that you can't declare such a type 'x'
    Optional.of((Quacks & Waddles) b)
            .ifPresent(x -> {
                x.quack();
                x.waddle();
            });
}

And call it via: both(new ICanDoBoth());

Thing is you can't declare a variable of an intersection type (well, unless var or a variable that is inferred by the compiler with Optional.of()).

Practically there are some hints here, but I've never used a variable of a intersection type in something very useful...

like image 29
Eugene Avatar answered Nov 15 '22 01:11

Eugene