So does this mean you are effectively writing OCaml-looking erlang? meaning, you are using Erlang libraries (not OCaml libs) to perform any IO or iterate over a list?
It compiles a large subset of OCaml into (more or less) idiomatic Erlang. So technically it can compile a subset of OCaml dependencies, but I don't think it's integrated with the opam/dune package/build systems. It's still early days.
As far as I'm aware there are a few major problems with static typing in Erlang that can't be solved so far and are not solved here either:
1. If you have a function that calls into other modules like `other_module:some_func(X)`, then the typing of this call can change at runtime. You could first have
some_func(N) when is_number(N) -> N + 1.
and later load a new version with
some_func(N) when is_integer(N) -> N + 1.
The older version accepts all numbers, i.e. floats and integers, while the second only accept integers.
2. Erlang message passing can not be typed statically in a meaningful (i.e. non-trivial) way, as the typing may be state-dependent:
Pid = spawn_link(fun () ->
receive
first -> ok;
_ -> error(bad_message)
end,
receive
second -> ok;
_ -> error(bad_message)
end
end)
Now, the static typing of sending to `Pid` depends on what you've sent before. This could maybe be handled by "enumerating" the receives, but I think that invites the halting problem into your type system.
The stateful receive (2) just means that an Erlang process should be modelled as a state machine with some variety of automaton. Each receive blocks on a finite ordered sequence of (possibly overlapping) pattern-matching expressions. The priority sequence means it behaves more like a PEG than an NDA or DFA.
Writing down the PEG message grammar for the process becomes quite easy. Pattern matching is well-defined. The number of states may be large, but can often be factored nicely by data types and ranges (e.g. tagged tuples). However, PEG semantics make it difficult to analyze composition of receive statements in the general case.
It's easy to solve the Halting Problem in Erlang - just add a timeout to your receive and accept some false positives :)
So... does this work with distributed Erlang or hot code reloading? Because those are the reasons[1], to my knowledge, that statically typed language won't fly.
Really stoked to give this a whirl!
[1] I know, and in-case others don't, almost no one (literally) uses hot-code reloading. Still... Instead of killing it, as in the case of Lumen (I think), I'd like to see it become easier/better...
Where do you derive this "almost no one" from? I use it all the time in production, and I guess quite a few other users use it to fulfill their very high uptime requirements.
I suspect there may be two different features (or degrees of features) here. Hot code reloading is indeed frequently used, but the corresponding ability to upgrade the entire application live (“hot swap”) is less so.
I would wager that nearly everyone who has run Erlang code in production has upgraded code (edit for precision: a module) live.
To engineer the entire application to support an upgrade, and to do all the testing required to make sure it will work correctly, is very resource-intensive, and (lacking real numbers, just from observing the industry working for Basho) I’d wager very few people do so.
Users of hot code reloading are probably on the minority but there are definitely more than 'almost no-one'.
There is a common misconception that 'no one on HN does something' means that 'no one does something'. HN is heavily biased towards startups and Web companies and large segments of the industry are very underrepresented. Pretty sure telecoms is one.
> Because those are the reasons[1], to my knowledge, that statically typed language won't fly.
Why not? If you're doing hot code reloading, the types all of the functions and receive expressions expect still have to be compatible, otherwise the code will fail at runtime. Static type checking just lets you know about those problems ahead of time.
I think it is more if Node A calls something on Node B, things should be correct initially. But then I update the code on Node B and didn't change anything on Node A, the code is now "incorrect". In this case, just because it compiles, doesn't mean it works.
If this works well, and can eventually interface nicely with Elixir libraries like Phoenix, I think it’ll be really exciting. Definitely going to keep an eye on this :)
Where does OCaml end and Erlang begin?