Here is a good example for your point Jochen:

///////////////////
@groovy.transform.TypeChecked
def method() {
    def component = new Random().nextBoolean() ? new ArrayDeque() : new
Stack()
    component.clear() // 'clear' in LUB (AbstractCollection or Serializable
or Cloneable)
    if (component instanceof ArrayDeque) {
        component.addFirst(1) // 'addFirst' only in ArrayDeque
    } else if (component instanceof Stack) {
        component.addElement(2) // 'addElement' only in Stack
    }
    if (component instanceof ArrayDeque || component instanceof Number) {
        // checked duck typing
        assert component.peek() in 1..2 // 'peek' in ArrayDeque and Stack
but not LUB
    }
}

method()
///////////////////

The peek() case is what you call LUBU. I am still not sure what the best
name is.
This is where we'd need either an invokedynamic or smarter multi-branch
logic with several alternative invokevirtual paths.

Cheers, Paul.



On Sat, Jun 6, 2020 at 2:44 PM Jochen Theodorou <blackd...@gmx.org> wrote:

> On 04.06.20 21:45, Daniil Ovchinnikov wrote:
> [...]
> >>   If we do not give up on flow typing, then I would like to
> >> know why the assignment should not be legal. And if it is legal in the
> >> if-branch, then why not in the Closure block?
> >
> > All assignments should be legal, and assignment in Closure block as well.
>
> to be clear. An assignment should be legal if the flow type of a
> variable and the static type of a variable are compatible. The new type
> of the variable is then the flow type (in Java it would stay being the
> static type).
>
> > Let me annotate the last example with types:
> >
> > class A {}
> > class B extends A{ def b() {}}
> > class C extends A{}
> >
> > A x // inferred to A because LUB(B,C) = A
> > x = new B()
> > // typeOf(x) as this point is B due to flow typing
> > if (true) {
> >      x = new C()
> >      // typeOf(x) as this point is C due to flow typing
> > }
> > // typeOf(x) as this point is A due to flow typing merging branches
> where typeOf(x) is B and C
> > A z  // inferred to A because LUB(A) = A
> > z = x
> > // typeOf(z) as this point is A
> > z.b() // STC error, no method b in A
>
> Which means we are on the same page, only that you work with LUB and I
> with LUBU. I know LUBU is a difficult thing. Not really in
> understanding, but in teaching the JVM, the compiler and the IDEs. The
> "normal" LUB is much more easy here.
>
> bye Jochen
>

Reply via email to