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 >