Elm 0.14 – Simpler Core, Better Tools
elm-lang.org
elm-lang.org
It will help to already have a bit of background in functional programming.
https://github.com/pflanze/de-elm
(Edit: here's a copy of the content of the linked page: https://github.com/pflanze/de-elm/blob/master/examples/annou... . Tell me if you don't like this and I'll remove it again.)
So, there's a practical point to this, which is that I wanted to read the page, and a mixed practical/political point which is that I don't want to enable JavaScript if I don't absolutely have to. So I sat down and figured out what can be done...
I'm sure this will cease to be useful at some point, but for the moment, I find that some of the time, running the URL in question through Google Cache produces a useful view.
Of course, Google properties themselves increasingly insist upon JS, even for basic "read-only" views. At least I have some confidence that Google is performing some measure of vetting their own JS against particularly the security problems that most concern me.
Here's the OP URL, via Google Cache:
http://webcache.googleusercontent.com/search?q=cache:http%3A...
This is very interesting to me. It demands consideration: do we need a person to manually bump the version anymore at all? If you can statically verify that a change meets the criteria, couldn't the package publishing process autoincrement the appropriate version segment and be done with it?
I'm not sure I agree that the phrase "going stable" really applies to a semver project. The most stable release would just be the highest number in each segment. Version 1.0.1 is almost by definition going to be more stable than 1.0.0, since the changes are only backwards-compatible bug fixes. At least that's my understanding of semver.
> Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.
(Yes, this means that you can use 0.x and declare yourself "semver compatible" and break on any patch release)
That being said it's possible to change a library's behaviour without touching the API. Consider the following diff:
-add a b = a + b
+add a b = a - b
Granted the example is simplistic. With the API versioning system in place the author should have renamed the method and would have gotten the right result. It's just to show that it wouldn't be a silver bullet.That said, it might be the case that removing the responsibility of versioning from experts would make them less concerned about the ramifications, and less likely to notice when they make a change like this one (well not this one exactly, but one similar but more reasonable).
You really do need tests in addition to static analysis to be sure of these things.
Plus, it gives a degree of reliability to those using the packages, which is something you can't necessarily count on in Haskell right now.
When I looked at Elm it was really similar to Haskell. After I learned a bit of Elm I dove into Haskell. Now that I'm coming back to Elm I'm having problems because I confuse this different syntaxes many times.
I hoped they could maintain the language more similar to it to make the switch between them easier.
: and :: are reversed.
They have no intention of making them more similar- in fact I was told there is going to be more subtle diverging happening.
Elm was really cool for me too at first, but these subtleties are just a pain. I am now using haste (haste-lang.org), which seems to have really come a long way over the course of its 3 year life span. I highly recommend it to those wanting to use Haskell as a front-end web development language.
Purescript has now become my alternative but I will take a look at Haste (ghcjs may be another possibility to look into).
I'm hopeful that Elm will help bring Haskell's ideas to a wider audience. After those ideas become familiar, I fully expect a large crowd of them to find Haskell's highly efficient syntax for expressing them to be very enticing. But, getting people to that point is going to require a lot of considerations to ease the JavaScripter -> Elmer -> Haskeller transformation.
(:) is very standard notation for "has type" in type theory.
Also, all of the mapN functions exist in Haskell and Idris as applications of the Applicative typeclass.
https://github.com/elm-lang/core/pull/25
I believe the original improvements were done here: https://github.com/jwmerrill/elm-animation-frame
I modified a game I wrote to use the modified run time. I can see a huge difference between the two in Firefox.
Unmodified: http://jcollard.github.io/elm-flyer-old/
Modified: http://jcollard.github.io/elm-flyer/
If there are any Firefox engineers reading this, maybe there is a good benchmark to be extracted out of this observation? I'd be interested in discussing this with someone. Feel free to reach out at the e-mail address in my profile.
[0]: http://elm-lang.org/blog/announce/0.14.elm#making-error-hand...
[1]: http://static.rust-lang.org/doc/master/std/result/index.html
Here's the first instance of what would become Rust's `Result` type (Oct 28 2011): https://github.com/rust-lang/rust/commit/c1092fb6d88efe51e42...
Note that the type is called `t` since the convention at the time was to name the primary type of a module `t` and then refer to the type as `modulename::t` (shows how far we've come, eh?). At this initial stage the variants are named `ok` and `error`. Also note that at this point in history Rust had had an `either` type for a while (https://github.com/rust-lang/rust/blob/c1092fb6d88efe51e42df...), which would later be removed as Result gained more traction.
Here's the commit where the `error` variant is renamed to `err` (Oct 28 2011, so the same day): https://github.com/rust-lang/rust/commit/2b62a80202e2855d47f...
Here's the first instance of `std::result` being mentioned in the mailing list (Nov 14 2011): http://article.gmane.org/gmane.comp.lang.rust.devel/891
Where the type itself is renamed to `result` (Mar 13 2012): https://github.com/rust-lang/rust/commit/b968c8e6cd362567bf0...
Where the type and variant names are capitalized in accordance with the current style guide (Aug 26 2012): https://github.com/rust-lang/rust/commit/0c6e470a257fc546555...
So this convention may very well have originated with Rust.
I also got tired of explaining "the good result goes in Right, because it's 'Right'" like I'm endlessly telling a bad dad-joke.
"Either" is IMO a nice counterpart to tuple types: one is a generic sum, the other is a generic product. People could complain that a tuple of ints are less descriptive than just using a constructor with a more descriptive name - like "Pair" or "Coordinate", depending on its intended application.
Having a specialized type for error handling makes sense, though.
I'm learning Verilog in my spare time, because I want to implement a dataflow/FRP language in hardware. (People tried to build massively parallel hardware in the past to run dataflow languages... I'm pretty sure it's a good idea.) Should be interesting!
(I just realised you meant to say that FRP is a subset of dataflow. I agree!)
This was going to be contentious no matter what. For what it's worth, Wikipedia (top Google result) seems to have a compatible story.
Luckily, it's just a conversation change. I think it will be fine, and net more helpful than damaging. The overall goals are intuition and accessibility.
> For the record, I voted for enum, like in rust-lang ;-)
Funny, because there's actually a long, long history of debate around whether Rust should refer to them as unions rather than enums (and change the keyword correspondingly). :) Here's the most recent one that I know of: https://github.com/rust-lang/rfcs/pull/27Swift seems to have followed Rust's example with its terminology here, so this issue is hardly settled. It may shake out such that `enum` is used for tagged unions where the variants are declared as part of the type (`enum Foo { Bar, Baz}`) (and hence the variants can't be shared between types, at least not without wrapping in a newly-defined variant), whereas `union` is used for tagged unions where the type is composed from multiple existing types (`type Bar; type Baz; union Foo { Bar | Baz }`).
For example Julia: http://docs.julialang.org/en/release-0.3/manual/types/#type-...
Typed Racket: http://docs.racket-lang.org/ts-guide/beginning.html#%28part....
Haskell: http://okmij.org/ftp/Haskell/extensible/#open-union
And many more.
if (isString(x)) {
// only now can we call string functions on x
} else if (isNumber(x)) {
// only now can we call number functions on x
}That said, forgive me pedantry for a moment: I think your use of the word "tag" is unclear. Typically, both sum types and union types must be tagged. If you think about something like the JVM, every object is tagged with a pointer to it's class. Untagged, or "tagless", objects are closely related to "unboxed" objects, but still not quite the same thing. The point is that the tag is something that can be inspected, switched on, etc at runtime. Where as a tagless representation does not require that runtime overhead.
It's possible to have a Union(int, String) or something like that where one type is typically untagged and the other typically tagged. If the compiler could eliminate the tag at runtime from context, then it would just eliminate the union and substitute the type with either int or String directly. So if it can't tell from context, it must actually make it a Union(Box<int>, String) so it can discriminate by tag.
Tangential: There is of course a trade off in tagless representations in terms of type system complexity and runtime cost. If you want to change from a List<int> (specialized list of machine ints) to a List<Integer> (nullable boxed ints), that's an O(N) operation to add the tags (and a more complex type system).
Yes, they are disjoint union, but there's really no such thing as non-disjoint union in a statically typed language i.e. that's what makes it typesafe.
People searching for it online will very likely be searching for "elm union type" where they'll quickly find examples and docs. Furthermore, you can prefix the term "union type" with stuff like "closed/open" and "tagged/untagged" to start making finer grained distinctions as need higher degrees of precision. In Elm it is always tagged and closed, so in discussions within the community, adding those prefixes is redundant. Finally, if you start with the term "union type" it becomes easier to think about what an "anonymous union type" might look like (like OCaml's polymorphic variants or open variants) ;)
More broadly, if people do run into the term "union type" in other languages they will be building intuition in exactly the way I'd like: it's a way to use different types in the same place. Things happen to have this extra tag thing in Elm, but it's not so different than anything people do in JS or Clojure or Racket or TypeScript or C or whatever else. I think bringing that connection out is a major benefit of this naming choice. The goal is to feel really welcoming and friendly, and my personal preference is to build on people's existing intuition as much as possible. If someone comes from JS and does not see all the subtleties of this discussion immediately on day one, they are actually having a better experience because they can learn the info as it becomes relevant to their daily usage. Hopefully a much nicer learning curve!
I realize I am making a somewhat controversial choice, but the idea is that statically typed FP people are building artificial barriers by being sticklers about this, rather than just prefixing for precision. You may not agree with all this, but we thought it through pretty extensively, and that is the reasoning!
Nothing serious though...
Anyway, the changes here do look pretty nice. Looking at the docs, it seems that they've added more examples, which is always appreciated! I still don't like the impurity that comes with the Signal.Channel, though... not that I have a better idea.
Interestingly enough, the dice is loaded. If you click long enough, you'll get an upside down V shape.
7 = 1+6, 2+5, 3+4, 4+3, 5+2, 6+1
2 = 1+1, 1+1
[1] http://en.wikipedia.org/wiki/Binomial_distribution [2] http://hyperphysics.phy-astr.gsu.edu/hbase/math/dice.html#c2