But I'm ignorant: is the Go runtime built in any way to accomodate third party languages? Apart from writing an interepreter in Go, is there a good way to target it?
Edit: https://github.com/minio/c2goasm seems to slightly go in that direction.
Something else is that the semantics of the Go language itself are purposely limited in ways that help build an efficient runtime easily. So even if you could target the Go runtime easily, it would impose limits to what the language can do as I understand.
Compiles to native code, has a repl, version 5 is multicore for those not happy with Lwt or multiprocessing in the UNIX classical style of each tool does one thing, and a GC only second to GHC in handling immutable types.
I'm excited for version 5, but until it's out, it's hard for people to take seriously in conversations about _Go_ of all things.
Maybe they should spend more attention in their compiler design classes regarding runtime implementations and language semantics.
However, (stable) OCaml not having multithreading support is still a gigantic limitation. Also, OCaml supports fewer target platforms, and I believe it's worse at cross-compiling (though I admit I may be wrong on this).
Yes, multithreading support is only in version 5.0, yet for many decades UNIX was multi-process only, and thanks to the latest security exploits, sandboxing with multi-processing alongside IPC seems to be the latest fashion anyway, so no big deal.
OCaml has several backends, including a bytecode one that is used for the REPL and porting purposes.
For example, if you want a high-performance web server, it's much more efficient to serve requests through multiple threads (preferably also using efficient IO) than it is to spawn different processes for different requests. I imagine you can coordinate different processes in similar ways, but again, it's much more effort, and either way, those processes are far too intimately tied to each other at that point to call them "different tools".
OCaml 5 still seems a lot more real and coming-sooner than the imaginary OCaml-on-Go. Sure, it's not ideal that multicore OCaml isn't yet stable, but it does exist, and will become stable.
On similar lines, Fable [0] project recently announced rust & dart runtime support making F# a very attractive choice.
[0] https://fable.io/blog/2022/2022-06-06-Snake_Island_alpha.htm...
https://www.ptc.com/en/products/developer-tools/perc
https://www.aicas.com/wp/products-services/jamaicavm/
And while we are at it, for .NET as well,
OpenMP uses OS threads, doesn't it?
When you have coroutines that can be preempted, without explicit yielding in the source code, that's the line at which I would consider it a VM. Basically, it's a VM if some userspace code (JIT, GC, scheduler etc) runs in the background and does things to your code.
I don't think there's a definitive interpretation of VM, so this is all arguable. But e.g. Java and C# are generally considered VM languages even if AOT-compiled, despite the fact that there's no bytecode involved past that point.
And why the distinction between OS threads and green threads? Sure, in case of OS threads, it's not the language runtime that does the scheduling, but that just means that the operating system is now our virtual machine.
I would argue that what makes a language runtime a virtual machine is not the presence of a garbage collector, a jit compiler, or a scheduler (with or without preemption), but that it has well-defined semantics in terms of something that looks a bit like a real machine - hence the name! In particular, there's a set of instructions it understands. In case of the JVM, the instruction set is defined in the Java Virtual Machine Specification (with Java bytecode its representation), in case of the CLR, it's defined in the Common Language Infrastructure specification (with CIL bytecode its representation), in case of Smalltalk, it's defined in the Blue Book, in case of WASM, in the WebAssembly core specification.