Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
TypeScript 1.4 sneak peek: union types, type guards, and more (msdn.com)
111 points by numo16 on Nov 19, 2014 | hide | past | favorite | 31 comments


Union Types, done in a lightweight 'anonymous' fashion. Awesome! Some languages go the discriminated type union route. If I had to chose I would take the this over a that alternative. Typescript continues to push forward.

Hopefully this leads to the construct being adopted by more languages. Rust has the heavier version, maybe they will adopt this before they release instead and then they can replace their gussied up Either/Err type with unions.

Maybe someday the Scala team will see the light and we will get them as well. Sadly I am not holding my breath, adopting innovations like union types were what drew me to Scala. Something like this isn't even on the docket for the next several years at a minimum. All the innovation in syntax died following the terrible 2013 scaladays keynote that "challenged" the Scala community to suck as hard as Java by 2018. It's really a shame that martin didn't decide to just implement union types when he implemented tuples years ago, now the language is probably too ossified to ever adopt them for fear they'll be another XML.


> Maybe someday the Scala team will see the light and we will get them as well. Sadly I am not holding my breath, adopting innovations like union types were what drew me to Scala. Something like this isn't even on the docket for the next several years at a minimum.

??? Union types are already announced and will ship in a future version of Scala.

If you can't wait you can use dotc instead of scalac, and play with union types today. (A commit to share the newest scalac-backend between scalac and dotc just entered the pull request queue and should close one of the largest missing pieces.)


That's awesome! I must have missed that announcement where it will come sooner than the next several years. Can you point me to it? The last I heard was in the roadmap [http://www.scala-lang.org/news/roadmap-next] and the earliest it is to be expected is in "Don Giovanni" which is not 2.12 or 2.13 but 2.14 which is, what, 4-5 years away at this point?

Unfortunately, we can't use dotc, we use Scala for a decently large project (220KLOC using wc -l) started back in the late 2.6/early 2.7 days which is gradually being ported to cross compile in ScalaJS. Having said that I will look into it for a side project. That's how our use of ScalaJS started. I had been attempting to use Typescript, but after giving it a shot, ScalaJS clearly beat it in every regard for our use cases, (well until the union types, but ScalaJs is still very very far ahead for us).

Thanks for the heads up!


I think this is the announcement I had in mind, I'd just take the published roadmap with a grain of salt, because usually things ship when they are ready and fit into the whole picture.

As seen in dotty, the basic stuff around union types is already working, so I'd be pretty surprised if it didn't ship earlier, especially because there is a demonstrated need for HLists, and shipping HLists without union types ... could be done, but why?

Additionally, a lot of things mentioned in "Don Giovanni" are already ready-to-ship today (sans a few minor requirements). For instance Giovanni's 1.3, 2.1, (some parts of 2.4 already shipped with 2.11), (approaches for 5.1 were already discussed and benchmarked), 5.1/5.2 (will happen when targeting Java 10).

My recommendation is to take that roadmap as a bottom line, but be prepared for drastic changes. My current guess is that if work gets done at the current speed, it might be possible to move things to earlier releases and subsequently eliminate a whole release in between, e. g. shipping the features of three releases in two.

But that's all just my educated guess.


Sweet I will definitely check out dotty then! Thanks for taking the time to catch me up. I'll move to guardedly optimistic we'll see union types in Scala this decade :)

Are HLists shipping soon too? I was under the impression they would have to wait for Giovanni as well, I need to start reading internals again I guess.

Re: 5.1/5.2(miniboxing/value classes) => Java 10 is going to get structs then I am guessing? I read the rough draft of that a few months back, looks pretty complicated but it seems to have thought through the corner cases. It is a godsend if you need that level of performance.

As an aside: it's funny you mention 1.3(Procedure Syntax) and 2.1(Result types are mandatory for Implicit definitions). They are actually the two changes that are far and away the worst for us from Giovanni so it's frustrating to see them be implemented first.

This is because we have thousands of lines for our serialization framework that run afoul of 2.1 which look like this:

    object Foo {implicit val ser = SerBuilder.forCase(this.apply _)}
    case class Foo(x : Int)
And thousands upon thousands that use procedure syntax. (We should write with less side-effects, I agree.) However when we do have side effects we want them to visually separate themselves from all the non unit returning methods. Procedure syntax does that and conveys the inherit difference between a procedure and function, via quickly scannable visual signaling. So that the procedures don't blend in to the : Blah = .... sea of functions, and all while being 8 less keypresses.


I don't want to cause false hopes, but I think the roadmap is quite conservative and designed to no disappoint people if things don't go according to the plan. (Especially with people complaining that the next few releases don't improve things they care about ...)

HLists are planned for Giovanni, but I considering that even Typesafe-related projects are now either depending on shapeless or shipping with their own HList implementation, I think there is a lot of desire to standardize on one (probably compiler-known (to deal with the huge increase of compile-time)) implementation.

As far as I know 1.3 and 2.1 are blocked by the need for a migration tool. Scala developers are certainly not expected to fix their code by hand, but let a "go fix"-like tool handle everything for them.

I think having the IDE assign Unit-returning methods a special color would retain some of the benefits of procedure syntax while fixing the issues caused by procedure syntax.

Tests are one case where procedures might be heavily used, but I think this can either be handled by a better API. (I never understood the reason why testing frameworks required the "assert + return Unit" pattern. Why don't they just allow tests to return Boolean and get rid of the assert boilerplate in simple cases?)

    def someTest("foo should equal bar") { assert(foo == bar) }
              |
              v
    def someTest("foo should equal bar"): Unit = foo == bar
              |
              v   // or even:
    `foo should equal bar` test { foo == bar }


Well having just written a unit test framework[1](because we needed one that cross compiled to ScalaJS and couldn't use utest for reasons relating to difficulty of getting it to produce reasonable output for all our legacy tests) I side stepped the issue by using a FunSuite style. I prefer using a series of assertions to simply returning true or false because often times you want to put multiple assertions in the same test.

However the unit test case alone is a pretty valid one. I am all for making it a compiler flag (opt-in or opt-out). I still haven't been given a single real problem with procedure syntax other than "it's different" and because "it's different" it therefore confuses new users and increases the complexity of the language. I don't think that follows logically and in my experience empirically. For the programmers I have introduced to Scala, or that I have talked to who use it none of them have gotten caught up by procedure syntax. This includes traders taking the Scala course that have never programmed before in their life.

The color/formatting is a good idea, that should just be done already. However given that the intellij guys still don't give an option[2] to color member variables defined in a constructor differently than ones defined in a method I'm not hopeful about that.

1: https://github.com/cgta/otest

2: https://youtrack.jetbrains.com/issue/SCL-2811


Thanks for your helpful information!

I think as soon as scala.meta is released, it will be vastly simpler to write your own refactorings (like converting tests using test library X to test library Y). From what I have seen on Parleys, the person behind macros even show-cased such refactorings in a talk at the last ScalaDays.


Their union type syntax looks like Ceylon's. I rather like it.

Union types with pattern matching would be the logical step, would it not? I wish for something like:

    match getResults() {
      case e: Error: ...
      case r: Results: ...
    }


Here is the issue,at the end of the day,Typescript is just javascript with compile time type checking.Pattern matching would mean introducing "new" semantics which would make the compiled code much less readable than it is today.

Tomorrow if I want to drop Typescript,I can,because it still outputs readable javascript.Introduce something like pattern matching and it will not be an option anymore.


I actually like cleanliness of Javascript generated from Typescript code. However I don't think that pattern matching would be more intrusive than, for example, module or class generation. Basically example from above could be compiled down to something like:

    var x = getResults();
    if(x instanceof Error) { ... }
    else if(x instanceof Results) { ... }


All the TypeScript examples use "instanceof". That's what a pattern matching block like this would compile down to, surely. And pattern matching on literals (eg., [x|xs]) would also translate to perfectly adequate JavaScript.


Have you checked out purescript[0]?

0: http://www.purescript.org/


Yes, it looks quite nice. I might experiment with it for a personal project at some point. Is it easy to use NPM modules without any extra glue?


I believe they can be very easily used if they are CommonJS modules? I'm not sure, but I'm almost positive the amazing Purescript Book[0] has an answer for you.

0: https://leanpub.com/purescript/read


It's great to see they're implementing feedback from the community, union types are one of the longest awaited TypeScript features. It's crucial to support them - not to mention the timing: just a day after Facebook flow is released featuring typed JS and union types.


that's not really the actual timeline. here is the pull request for adding union types. https://github.com/Microsoft/TypeScript/pull/824

I believe all 3 teams, TypeScript, Flow, and AtScript, are working together for few things as is.


AtScript are working with TypeScript and supersets it.

If you look at that TypeScipr PR, you see it closes an issue and they reference (2 months ago) Flow there.


    var x = [1, 'world']; // x: Array<string|number>
I'm not sure I wouldn't prefer this to give an error.


That's the main issue with advanced type systems that feature things like union types, generics/polymorphism, subtyping... It's hard to specify the line between type inference guessing correctly what the programmer wants, and type inference now catching a programmer's bug. This is the reason that most Hindley-Milner type systems (e.g. OCaml's) don't allow recursive types (which come up e.g. for typing the Y combinator).

Another example is:

    function equal<T>(lhs: T, rhs: T): boolean {
      return lhs === rhs;
    }

    var e = equal(42, 'hello');
Here, there obviously is a type for `T`: `any` (the toplevel dynamic type) or `number|string`.

This problem is caused by the requirement that type inference is "complete", i.e. that it correctly infers types for all programs that have a valid typing (i.e. that would work if the programmer specified all types).


This makes me wonder what the point of writing 'var' is if it doesn't tell you the type of the variable.


So variables are explicitly declared, don't have issues of mis typing a variable name and accidentally declaring a new one.

Note: This is just my thinking, I don't know if it's the actual reason


That's a sensible reason, sure, but I'd rather declare it with an actual type instead.


Yes, for complicated things like this, explicitly declaring the type is probably preferable.


As opposed to doing what?


Like python, just `e = equal(...`


Python had to go through a lot of pain for that, the "nonlocal" keyword was only added in Python 3.0, and the local/global distinction is very fragile.

Javascript and Coffeescript try to solve this in different ways, most people think that JavaScript's method sucks, and many are not fond of CoffeeScript's non-locality. Personally, I think that demanding variable declaration is still the best option (possibly except for interactive sessions).


Actually OCaml does support recursive types. Recursion through objects and polymorphic variants is always supported, and full recursive types can be turned on with the `rectypes` command-line option.


Why? This is exactly what type definition describes - an array of string or numbers. If you'd like to have an either array of strings or array of numbers, you'd type: Array<string>|Array<number>


I think he meant that he would prefer not having to deal with an array where types are all over the place.


I get to see a lot of people giving hate to Javascript for being not a real language. But with TypeScript it really feels like a modern language to build large apps.

I love how coffeescript offers high expression ability for prototyping while typescript offers scaffold so you don't shoot yourself in the foot.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: