Details

    • Type: Suggestion Suggestion
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Labels:
      None

      Description

      Scala has the compound (i.e. conjunction) type by employing `with`, but it does not have a union (i.e. disjunction) type.

      I hope I have successfully demonstrated how to simulate a nearly first-class union type:

      http://groups.google.com/group/shapeless-dev/browse_thread/thread/01f26830027f3517/7c1006ac6e638044?#7c1006ac6e638044

      And the negation of the disjunction:

      http://www.chuusai.com/2011/06/09/scala-union-types-curry-howard/#comment-1160

      I have filed today two bug reports that hinder use of that simulated union type.

      Beyond that, I am pondering if Scala is going to lose significant competitive ground w.r.t. to Ceylon if it doesn't add a completely first-class union type asap. And go beyond Ceylon by adding some way to extend the disjunction (e.g. for heterogeneous types) as I demonstrated at link above for negation.

      Afaics it is necessary for supporting heterogeneous collections type-safely without resorting to the (probably unbearable for novices, and more "Scala is difficult to read" accusations) complexity of the experimental metascala.

      I have been thinking that first-class intersection types are very important, both for the [reasons Ceylon has them][8], and because instead of [subsuming][9] to `Any` which means unboxing with a `match` on expected types can generate a runtime error, the unboxing of a ([heterogeneous collection][10] containing a) disjunction can be type checked. Unions are more straightforward than the [complexity of using][11] the experimental [HList][12] of [metascala][13] for heterogeneous collections.

      [8]: http://ceylon-lang.org/documentation/1.0/faq/language-design/#optional_types
      [9]: http://stackoverflow.com/questions/8360413/selectively-disable-subsumption-in-scala-correctly-type-list-contains
      [10]: http://lambda-the-ultimate.org/node/4394#comment-68110
      [11]: http://jnordenberg.blogspot.com/2008/08/hlist-in-scala.html
      [12]: http://stackoverflow.com/questions/185972/arrays-in-scala/205729#205729
      [13]: http://stackoverflow.com/questions/3508077/does-scala-have-type-disjunction-union-types/3508357#3508357

      P.S. There is a duplicate syntax-highlighted version buried nearer to the bottom of the following stackoverflow answer:

      http://stackoverflow.com/questions/3508077/does-scala-have-type-disjunction-union-types/7460312#7460312

      P.S.S. Consider reading the Ceylon language design FAQ[8], as it appears to me to be significant substance in their effort, although I am not yet clear on what corner cases may be lurking in their attempts to simplify and make code more amenable to the mainsteam.

        Activity

        Hide
        Shelby Moore III added a comment -

        I found the following thread in the Scala language mailing list, and will add my thoughts to that thread as well.

        http://groups.google.com/group/scala-language/browse_thread/thread/cfcf64dfff14e76f/3fa97e6d9fe4a0f8?lnk=gst&q=union+type

        Show
        Shelby Moore III added a comment - I found the following thread in the Scala language mailing list, and will add my thoughts to that thread as well. http://groups.google.com/group/scala-language/browse_thread/thread/cfcf64dfff14e76f/3fa97e6d9fe4a0f8?lnk=gst&q=union+type
        Hide
        Shelby Moore III added a comment -

        We need unions otherwise we can't get modular reuse of data structures, e.g. when we want to put them in a heterogeneous collection, where subsumption Any is viewed as a type hole and to be avoided:

        https://groups.google.com/d/msg/scala-debate/LWBz3-Q0pNI/MzuU-5HgFyQJ

        We need disjunctions when we can't coalesce different types to have the same supertype (other than Any), which will happen when ever we reuse modules written by others, where we can't refactor their types to inherit from the supertypes we need to mash all the universe together.

        Disjunctions are fundamentally about the Expression Problem (which I have provided links to upthread already) or more importantly the fragile base class problem.

        Without disjunctions, can't meet big picture goal of forwarding modularity and reuse across the universe (not just within the local team)

        The above link continues references to work already done by others on solving this issue.

        Show
        Shelby Moore III added a comment - We need unions otherwise we can't get modular reuse of data structures, e.g. when we want to put them in a heterogeneous collection, where subsumption Any is viewed as a type hole and to be avoided: https://groups.google.com/d/msg/scala-debate/LWBz3-Q0pNI/MzuU-5HgFyQJ We need disjunctions when we can't coalesce different types to have the same supertype (other than Any), which will happen when ever we reuse modules written by others, where we can't refactor their types to inherit from the supertypes we need to mash all the universe together. Disjunctions are fundamentally about the Expression Problem (which I have provided links to upthread already) or more importantly the fragile base class problem. Without disjunctions, can't meet big picture goal of forwarding modularity and reuse across the universe (not just within the local team) The above link continues references to work already done by others on solving this issue.
        Hide
        Shelby Moore III added a comment - - edited

        We need unions otherwise we can't type check the Expression Problem:

        http://copute.com/dev/docs/Copute/ref/Complete%20solutions%20to%20the%20%93Expression%20Problem.htm#comment-10417524

        In the Mutable Partial Solutions section, I suggest the alternative coding style to use a union type to lift the match default case out of the function to the input parameter type, where the supported types are thus enumerated and type checked by the compiler. This is analogous to first-class concept in Extensible Programming with First-Class Cases. Thus, my tradeoff rule holds true for that research paper. None of this eliminates the "default cases". It just pushes them to different places.

        The point is that the Expression Problem (extensibility, reuse, and modularity..hey ya know Scala-ble code) creates cases that are not enumerated in match-case blocks in pre-existing code. When the parent is not sealed, then the programmer will be given no warning that the code can fail at runtime throwing an exception. Whereas, if we type the match-case block by inputting a union, then the caller can not call the function with a case that is not enumerated.

        Show
        Shelby Moore III added a comment - - edited We need unions otherwise we can't type check the Expression Problem: http://copute.com/dev/docs/Copute/ref/Complete%20solutions%20to%20the%20%93Expression%20Problem.htm#comment-10417524 In the Mutable Partial Solutions section, I suggest the alternative coding style to use a union type to lift the match default case out of the function to the input parameter type, where the supported types are thus enumerated and type checked by the compiler. This is analogous to first-class concept in Extensible Programming with First-Class Cases . Thus, my tradeoff rule holds true for that research paper. None of this eliminates the "default cases". It just pushes them to different places. The point is that the Expression Problem (extensibility, reuse, and modularity..hey ya know Scala -ble code) creates cases that are not enumerated in match-case blocks in pre-existing code. When the parent is not sealed , then the programmer will be given no warning that the code can fail at runtime throwing an exception. Whereas, if we type the match-case block by inputting a union, then the caller can not call the function with a case that is not enumerated.
        Hide
        Shelby Moore III added a comment -

        We need unions otherwise we can't write type parametrized functions that use typeclasses on the elements of collections, because those element types could be heterogeneous.

        https://groups.google.com/d/msg/scala-debate/LWBz3-Q0pNI/S8YV_Nk9RlwJ

        https://groups.google.com/d/msg/scala-language/J8LpYDmrOCg/SAem2VlvUswJ

        Show
        Shelby Moore III added a comment - We need unions otherwise we can't write type parametrized functions that use typeclasses on the elements of collections, because those element types could be heterogeneous. https://groups.google.com/d/msg/scala-debate/LWBz3-Q0pNI/S8YV_Nk9RlwJ https://groups.google.com/d/msg/scala-language/J8LpYDmrOCg/SAem2VlvUswJ
        Hide
        Shelby Moore III added a comment - - edited

        We need unions otherwise we can't write covariant collections, or any function that inputs a type that is parametrized with a lower bound, that do not subsume to Any (or AnyVal) when the input is neither a supertype nor a subtype of the lower bound:

        https://groups.google.com/d/msg/scala-language/B6f-iubR9Mk/y58JS-zmwmIJ

        https://groups.google.com/d/msg/scala-language/B6f-iubR9Mk/zC1p-hucscoJ

        In other words, we barely have any control over what gets input. For example, Scala's Set was forced to be invariant so the contains method would avoid this problem.

        Show
        Shelby Moore III added a comment - - edited We need unions otherwise we can't write covariant collections, or any function that inputs a type that is parametrized with a lower bound, that do not subsume to Any (or AnyVal ) when the input is neither a supertype nor a subtype of the lower bound: https://groups.google.com/d/msg/scala-language/B6f-iubR9Mk/y58JS-zmwmIJ https://groups.google.com/d/msg/scala-language/B6f-iubR9Mk/zC1p-hucscoJ In other words, we barely have any control over what gets input. For example, Scala's Set was forced to be invariant so the contains method would avoid this problem.
        Hide
        Shelby Moore III added a comment - - edited

        An implementation strategy and a single rule to follow for all cases:

        https://gist.github.com/shelby3/6639849

        Show
        Shelby Moore III added a comment - - edited An implementation strategy and a single rule to follow for all cases: https://gist.github.com/shelby3/6639849

          People

          • Assignee:
            Unassigned
            Reporter:
            Shelby Moore III
          • Votes:
            6 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

            • Created:
              Updated:

              Development