Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Caramel: An OCaml to Erlang Compiler (abstractmachines.dev)
151 points by signa11 on Nov 22, 2020 | hide | past | favorite | 26 comments


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?

Where does OCaml end and Erlang begin?


OCaml ends at compile time, Erlang begins at runtime.


yeah but WHAT is it compiling is my question. Does it compile OCaml dependencies or am I using Erlang deps?


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.


Can this work? People have been scrambling for static typing on the BEAM for a while. Is this the one?


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 :)


This is about static typing. I expect my static typing to terminate. Getting typing to work with a "screw this" fallback is already possible.



Yes, that is the "screw-this-fallback" typing I was referring to...

If it fails to prove a type for a value, it falls back to "this could be any type" which brings this part of the code back to pure dynamic typing.


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 don't think so. Hot code reloading is hot code reloading. The parent to your comment is talking about in production so it's the 'real thing'.


I’m not sure what exactly you’re disputing.

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.


> no one (literally) uses hot-code reloading

I could be wrong but I thought phoenix uses this when you're in dev.


We will be running a webinar on Caramel on December 9th for those wanting to explore or ask the creator any questions :) Register at https://www2.erlang-solutions.com/webinar-registration-2


Obligatory link to my list of alternative BEAM languages.

https://gist.github.com/macintux/6349828#alternative-languag...


There is https://nact.io/ for JS/ReasonML.

For Rust there is:

https://bastion.rs/

https://docs.rs/actix/0.10.0/actix/

and Lunatic (which compiles to WebAssembly): https://news.ycombinator.com/item?id=25160474

(edit: added Actix and Lunatic, formatting)


Thank you very much, I've added all of those.


Does Swish (https://github.com/becls/swish) fit anywhere in your list?


Thanks, I added it to the list of other actor implementations.


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 :)




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

Search: