Evan asked for bullet points, so here they are:
* The Elm Compiler can emit function definitions in orders that result in the values of variables being used before they've been defined. For example, a list of functions defined at module scope may end up containing null values if its definition gets emitted before the function's definition gets emitted. This results in runtime exceptions.
* A batch of function definitions can be emitted in any order because they will refer to each other via JavaScript variables. This, however, does not apply to constructions like a list of functions or referencing functions in a closure.
* This problem is difficult to distill down to an SSCCE because it seems to result from the compiler applying insufficient constraints to its sorting process. Slight changes to an example or the compiler could make the problem go away in one example without actually fixing it.
* This problem can be addressed using Tarjan's algorithm to identify strong components in the dependency digraph.
* Naive application of Tarjan's algorithm will result in more programs being rejected for cyclic dependencies than need to be because there is a distinction between having the value available for use in initializing other structures — e.g., filling in a list — and being able to invoke a function which would require that the function and everything it references be fully realized.
* The Elm code here is an example of applying Tarjan's algorithm with a distinction between value types and hence the nature of dependencies to the problem of sorting variable definitions.
Mark