Hacker News new | ask | show | jobs
by Ericson2314 1638 days ago
Someone needs to get OCaml running on the Go runtime, so it can be an F# for that ecosystem.
5 comments

With all the problems arising from leaky abstractions and trying to adapt to a foreign runtime? Imho there's no point. Especially now that OCaml Multicore is on the way. A much better effort, for anyone interested, would be to vastly simplify the OCaml build and package management story to be more Go-like.
> A much better effort, for anyone interested, would be to vastly simplify the OCaml build and package management story to be more Go-like.

OCaml's package management and build system is not complicated for consumers and builds are very fast. What do you feel is complicated about opam and dune?

What is complicated (but got better) is submitting packages into the official package repository. However, this ensures that packages have correctly versioned dependencies, which is good for consumers.

Go does not rely on a central package repository and this makes it easier to use by essentially just pointing to GitHub. OCaml and Go differ in the way they try to use updated dependencies for a build. OCaml by default is aggressive whereas Go prefers stability.

> With all the problems arising from leaky abstractions and trying to adapt to a foreign runtime?

Huh? The point is Go might be a lousy language, but I can't think of anything OCaml needs to do that the Go runtime cannot do. This wouldn't be leaky and the FFI could be quite good.

> Especially now that OCaml Multicore is on the way.

As I wrote in the other reply, this would be a naked ploy for new users, and flexing the language isn't wedded to a single run time.

Multicore OCaml isn't just a runtime change, but also demonstration of the new effects indicating that the language can do parallelism without bad concurrency problems. All that language-side work carries over to the other runtime: you get to show off Goroutines done more safely!

Does Go's runtime do generational collection? No. Does it support tailcalls? I have no idea but I doubt so. Without these there cannot be any chance for OCaml-on-go; more blockers would probably come to mind quite quickly.
The GC would be shitty, yes. I doubt the runtime itself really cares about tailcails. There could be tiny calling convention issue, you can share the runtime while using a different calling convention, I assume.

People forget that the call stack data structure naturally allows tail calls, and restrictions against it invariably have a certain degree of artificiality.

Not sure about now with multicore, but pretty sure OCaml had a "bump" memory allocator previously. These are just a little bit slower than stack allocation as they just involve a pointer increment and is important in functional languages since they allocate a LOT. Go's memory allocator is pretty fast (I played with making a bump allocator for it and it was only 4-5x faster, so very fast), but the slowdown would be noticeable. Also, Go uses a "mark and sweep" style collector (which is the reason it can't use a bump allocator - those require moving on collection, which Go can't do) which just isn't designed for the amount of garbage that FP languages generate. It might work, but it would be quite a bit slower.
Go uses a simple non-generational collector because it avoids generating garbage on the heap by doing escape analysis and allocating on stack. I get the ocaml does a lot of recursion, being functional. But could stack allocation also work for ocaml when using growable stacks?
c-cube mentioned a couple, here's another: algebraic effects, or to put it another way, 'resumable exceptions'. Go doesn't even have exceptions natively. The level of indirection this alone would introduce to handle it, would make it an extremely leaky abstraction.

Beware that in your naked grab for users, you don't disappoint them and end up actually driving them away.

Eh just through in a sum type. Unwinding or other runtime support for exceptions is highly overrated in my mind.

What's really dank is doing https://www.ccs.neu.edu/home/shivers/papers/mrlc-jfp.pdf i.e. multiple return pointers. This way you can do the Rust Result (Either Monad) thing without branching.

This is a very bad idea considering Go runtime is optimized for way less allocations due to 1) how good Go in stack allocation is and 2) how mutable everything is.

OCaml on the other hand has an extremely well optimized runtime for lots of small heap allocations (typical in FP), and produces good asm code for functional patterns.

What's the motivation? OCaml is roughly as performant as Go.
Pure naked grab at more users. I don't mean to imply there any anything better about Go's runtime at all.
In any case, if a large number of users is what you're after, you'd target Java ( http://www.ocamljava.org/ ) or JavaScript ( https://rescript-lang.org/ , http://ocsigen.org/js_of_ocaml/latest/manual/overview ).
Yes, those are fine ones to do too.
In that case interoperability with Go libraries might be better: just running on the same runtime wouldn't bring many advantages (other than having a single GC instead of 2) without being able to easily call libraries written in another language. (Although TBH I'd run them as 2 separate processes and have them communicate via some form of RPC, OCaml would just need good integration with <insert-favourite-GO-rpc> protocol)
RPC is dramatically less powerful than than FFI. No sharing of state is a serious limitation.
There are ways to share state over RPC.
Agree. If Ocaml add 10 more users, it would more than double its users in the world. Also it is never too late to remind everyone again that JaneStreet uses Ocaml. If Go were any good JS would have used that.
With F# or TypeScript or similar things you can compile down to a common bytecode or to the base language and use the result. Unless you were writing an OCaml to Go transpiler you'd need to ship a copy of the Go source code alongside a new OCaml compiler and still have to build a new build system and ecosystem and such. You couldn't just bolt this on to an existing Go installation or something.
Which feature is prevalent in the go runtime that you must have? Or is it the ecosystem that is larger in go?