The TypeScript comment is wrong, the author needs to use a const enum:
<a href="https://www.typescriptlang.org/docs/handbook/enums.html#const-enums" rel="nofollow">https://www.typescriptlang.org/docs/handbook/enums.html#cons...</a><p>Then it generates code that's better than Flow. It's not as aggressive as Reason for sure, but it's still pretty good.<p><a href="https://www.typescriptlang.org/play/#src=const%20enum%20ScreenType%20%7B%0D%0A%20%20%20%20LoadingScreen%2C%0D%0A%20%20%20%20CodeEntryScreen%2C%0D%0A%20%20%20%20SuccessScreen%2C%0D%0A%20%20%20%20FailureScreen%2C%0D%0A%7D%0D%0A%0D%0Aconst%20impossible%20%3D%20(x%3A%20never)%3A%20never%20%3D%3E%20%7B%0D%0A%20%20throw%20new%20Error('This%20case%20is%20impossible.')%3B%0D%0A%7D%0D%0A%0D%0Aconst%20needsCancelButton%20%3D%20(screen%3A%20ScreenType)%3A%20boolean%20%3D%3E%20%7B%0D%0A%20%20switch%20(screen)%20%7B%0D%0A%20%20%20%20case%20ScreenType.LoadingScreen%3A%0D%0A%20%20%20%20%20%20return%20true%3B%0D%0A%20%20%20%20case%20ScreenType.CodeEntryScreen%3A%0D%0A%20%20%20%20%20%20return%20true%3B%0D%0A%20%20%20%20case%20ScreenType.SuccessScreen%3A%0D%0A%20%20%20%20%20%20return%20false%3B%0D%0A%20%20%7D%0D%0A%20%20return%20impossible(screen)%3B%0D%0A%7D%0D%0A" rel="nofollow">https://www.typescriptlang.org/play/#src=const%20enum%20Scre...</a>
ReasonML is by far my favorite emerging JavaScript tech. Not only is its JS code output small, it's also performant. For immutable updates it generates code faster[1] that Object.assign! :)<p>[1] <a href="https://medium.com/@javierwchavarri/performance-of-records-in-bucklescript-ecf6566fff5c" rel="nofollow">https://medium.com/@javierwchavarri/performance-of-records-i...</a>
As someone who 1) knows a few functional programming concepts, 2) hasn't programmed extensively in a functional language, 3) would like to get productive fast (in web development), but also 4) wants a language for the long term (think general purpose, decent momentum), including for academic interests... Is there a language that fits all these requirements, or am I asking too much?<p>Elm is too limited, Haskell seems too convoluted, unsure about F# and OCaml, don't know about good alternatives.<p>I've been considering PureScript because it seems to strike a balance between features, JS interoperability and skill transferability, but I'm still a little afraid of it being unnecessarily complex for my next short-term projects.<p>I've only now started considering ReasonML, but am I wrong to think it's much closer to the "get productive fast" side than the "long-term investment" one? Not to mention its JS-like syntax, which I admit I have a distaste for.
How is the uglify.js example correct? It replaces 'status !== 2' with '!(status>=2)'<p><pre><code> > needsCancelButton(2)
false
</code></pre>
Surely it should be:<p><pre><code> function needsCancelButton(n){ return 2 === n }
</code></pre>
Also, more generally, uglify.js has no idea about the range of integers that could be passed in so how is a greater than optimization like that ever valid?
Nitpicky but critical detail: union types are not the same as "sum" types such as what you get in Reason, Purescript, and Elm. Union types are convenient for adding atop a dynamic language or modeling records (although, Purescript's row types are better), but they are less capable of abstraction.<p>The key example to differentiate union and sum types is `int union int == int` whereas `int sum int` is something unique and different from `int`. A sum type keeps track of the "left side" versus the "right side".<p>So, all said and done not only is Reason producing faster, tinier code... it's also managing a more sophisticated and powerful abstraction!
The difference between Reason's and PureScript's output is easily explained if you take into account the differing goals of the two projects. PureScript has an emphasis on [JS interop](<a href="https://leanpub.com/purescript/read#leanpub-auto-polyglot-web-programming" rel="nofollow">https://leanpub.com/purescript/read#leanpub-auto-polyglot-we...</a>) going both ways. Being able to add some PureScript code to a JS codebase, or even to intentionally layer a JS frontend on top of a PureScript core, is an explicit design goal.<p>You can actually create instances of PureScript types in JS and pass them into functions defined in PureScript. That explains why there's a JS class for each data constructor. Similarly, the generated PureScript code can't actually "know[] the match is exhaustive", since it could be called from anywhere.<p>The article was interesting, but I think the comparison would benefit from providing an example of the code generated for calling the function as well as its definition.
From the section on TypeScript:<p>> enums, which are basically like Java’s enums.<p>They really aren't. Java enums are somewhat unique in that they are full-fledged classes, not just glorified constants. TS enums are much closer to those of C#.
Meanwhile in dynamic land:<p><pre><code> if(cancelButton == undefined) throw new Error("Specify if there should be a cancel button or not")</code></pre>
I think the root of the problem is overzealous use of OOP patterns like inheritance. If you would do the most naive implementation you would just do one view, copy it, and when needed a fourth, just copy it again, instead of entangling your code with yet more paths.
This is a nice insight into Reason's handling of sum types. Here's the Reason code as we'd typically write it:<p><pre><code> let needsCancelButton = fun
| LoadingScreen | CodeEntryScreen => true
| SuccessScreen => false
};</code></pre>
For the Appendix: Idris is also a functional language that can compile to JS. I wouldn't say the output is very readable, but except for a couple of JS interop issues, I haven't had too look at it at all :)