Skip to content

Intersection vs. Union

Robert Ewald edited this page Apr 24, 2015 · 2 revisions

I take this from here: https://groups.google.com/forum/#!topic/clojure/Fi5JtNHAON4 where Ambroise nicely explained the difference in terms of java services.

To understand the difference between intersection and union it might help thinking in terms of Java interfaces, Foo and Bar.

(definterface Foo
  (foo []))
(definterface Bar
  (bar []))

(I Foo Bar) is a value that extends both Foo and Bar.

(deftype IImp []
  Foo
  (foo [this])
  Bar
  (bar [this]))

(->IImp) is of type Foo, Bar, (I Foo Bar) and (U Foo Bar).

Assuming we assign (->IImp) the type (I Foo Bar), we can call these safely:

(let [i :- (I Foo Bar), (->IImp)]
 (.foo i)
 (.bar i))

A type that just implements Foo is not a Bar, so we can't claim it's a Foo and a Bar.

(deftype UImp []
  Foo
  (foo [this]))

(->UImp) is of type Foo, and (U Foo Bar).

Assuming we assign (->UImp) the type (U Foo Bar), the same operations now must cast at runtime.

(let [i :- (U Foo Bar), (->UImp)]
 (if (instance? Foo)
  (.foo i)
  (.bar i))
Clone this wiki locally