question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unification across intersection of conflicting base types is asymmetrical

See original GitHub issue

I noticed this in real code in Scala 2.x, and it seems to exist in Dotty (0.7.0-RC1), too, though I haven’t explored whether it can lead to a genuine unsoundness issue… but it at least breaks an invariant I wouldn’t expect:

trait F[T]
def foo[T](f: F[T])(g: T) = g

We can then successfully call,

foo(null.asInstanceOf[F[String] & F[Int]])("")

but not,

foo(null.asInstanceOf[F[String] & F[Int]])(42)

It appears that when trying to instantiate the type parameter T from the intersection type, the unification algorithm simply takes the first match it finds without checking for subsequent matches in the intersection, rather than inferring the union type, String | Int, which I think would be the only consistent answer. The LUB of String and Int might be better, but it’s still wrong if F is invariant in T.

Note that it is impossible to construct an instance of F[String] & F[Int], but I don’t think that’s sufficient protection…

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:15 (15 by maintainers)

github_iconTop GitHub Comments

1reaction
smartercommented, Mar 29, 2018

replacing intersections A & B by a GLB of A and B, dually to the union simplification code that @smarter has shown. I’m not sure Dotty does that simplification, either (but I wouldn’t know, yet)

No, it doesn’t. We approximate unions because they’re generally too precise and not what you want to work with (just like we widen singleton types), no such problem arise with intersections.

1reaction
propensivecommented, Mar 29, 2018

That was my intuition speaking overconfidently… but it might be worth me going over my “logic” step-by-step, so I can get a better understanding. Everything I know about types comes from experimentation, so I appreciate any feedback!

  1. F[T] represents all values which satisfy a set of properties which are written in terms of T, for any T.
  2. F[A] & F[B] represents all values with the same set of properties, each of which should be satisfied both when T = A or when T = B.
  3. This appears to be saying, “when T = A | B”, however in my logical leap of assumption I have ignored that each type is templated in terms of a single type, T, and functional dependencies may exist between properties of that same type (in both covariant and contravariant positions), where substitution of A everywhere or B everywhere will work, but A | B will, in general, not.

That was a useful exercise - thanks for instigating it!

The asymmetry in LUBs/GLBs in inference is particularly interesting to me, as I’m often making use of LUBs and GLBs to construct new types, and I rely heavily on them working differently in Scala… and having union types (“the union of the set of all the types”) as well as supertype LUBs (“the intersection of the set of all the supertypes”) confuses me (and presents the possibility of a number of in-between types formed from some hybrid of the two), while in the dual world, we only use intersection types for the GLB (i.e. “the intersection of the set of all the types”) rather than subtype GLBs (“the intersection of the set of all the subtypes”). But we construct types from the top-down, with the interesting types towards the bottom, so we don’t usually get to work with many types which have useful common subtypes. Anyway… I’ll carry on thinking about this to myself. 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Asymmetric Unification and Disunification - Springer
Asymmetric Unification is a type of Equational Unification where ... A unifier δ is more general than another unifer ρ over a set...
Read more >
Intersectionality - Wikipedia
Intersectional feminism aims to separate itself from white feminism by acknowledging women's differing experiences and identities. The term intersectionality ...
Read more >
Kenji Yoshida on Twitter: "こういう話かな。なるほど・・・ https://t ...
Unification across intersection of conflicting base types is asymmetrical · Issue #4214 · lampepf... I noticed this in real code in Scala 2.x, ......
Read more >
The Manual on Uniform Traffic Control Devices (MUTCD) 2009
Intersection Lane Control Signs (R3‑5 through R3‑8) . ... CHAPTER 6G TYPE OF TEMPORARY TRAFFIC CONTROL ZONE ACTIVITIES. Section 6G.01.
Read more >
Unification in a λ-Calculus with Intersection Types
We use a and b to range over type constants, c to range over object constants, and x, y, and z to range...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found