💾 Archived View for republic.circumlunar.space › users › dbane › gemlog › 2023-04-02.gmi captured on 2024-07-09 at 00:18:09. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-04-19)

-=-=-=-=-=-=-

High-level languages in production

I've been playing around with mostly Mercury lately. It has been fun.

Mercury Programming Language

I'm interested in a migration path from prototypes written in, e.g. Scheme or Prolog. So even though I really like ISLisp, it probably doesn't satisfy the requirements for commercial, production-quality. Notably, I've ignored my own advice and two of these platforms are non-standardised languages. I justify this because this is deciding for a commercial product, whereas deciding for learning is better limited. Also, although it may have only been half-hearted, I never was quite satisfied with SML for a real project. For example, if I use compiler extensions (as is very likely), libraries I try to integrate may not know about these extensions to interwork with them.

Software Design for Flexibility

Although I was careful to only look at native-code compilers to make server design easy, I also assume a two-level design where something like D (or the more complex C++) is used for low-level code.

D Programming Language

Anecdotally, I notice two patterns. First, languages converge gradually to have one main open source & one main commercial implementation, e.g. Forth & Lisp. Second, "academic" languages becomes associated with another language for "commercial use", e.g. Scheme/CL, SML/OCaml and Prolog/Mercury.

Mercury

This is new to me. I heard of it when I was trying to learn Prolog properly. I didn't realise back then how close it was to ISO Prolog though.

I spent some time with SWI-Prolog, but since it changed to be non-standard I think Mercury is a more coherent tool. For example you don't need to pick a package to do run-time "typechecking", compile-time typechecking is built into the language. Similarly for modes/determinism (which are important in logic programming).

I have a personal preference for logic programming, it reminds me of requirements written in the ISO-standardized Z or VDM. There is a clear migration path from a prototype written in ISO Prolog (e.g. GNU, Ciao) to Mercury. And it supports the features I desire in an extended Prolog (types, modes). Finally, Windows is supported as a 1st-class citizen.

As for disadvantages, it's not formally standardised, but is very similar to Prolog (especially syntactically). And it's supported by a small team, e.g. the package manager (mmc-get) only has 20-30 packages so for example if you want to do async I/O eio, you just have to use the C FFI to call POSIX aio_* functions.

Mercury Packages

Others

Poly/ML and Giraffe

This is the only standardised language I was looking at (for what that's worth). Using Giraffe also allows access to lots of extended features through GObject Introspection, e.g. async I/O.

For disadvantages, we're missing the nice native thread pool & async stuff ("domains") from OCaml and have to manage POSIX threads ourselves. And the package collection (smackage) only has 20-30 packages. Some of which I had to add, so I think OCaml may be a better choice for commercial development. Critically, there's no path other than rewriting from prototypes written in, e.g. Scheme.

Poly/ML Implementation of Standard ML

Giraffe Library

OCaml 5

This is a new release, notably most package repos still have the single-threaded V4 which isn't as interesting.

V5 added a great concurrency story, "domains". And the Opam package collection is very big (4,000, more than quicklisp's 1,500), including a ready-to-go sqlite wrapper.

As for disadvantages, there is only one implementation. But the language is very close to Standard/ML for a human. Windows support is 2nd-class for now, but that should change. And again, migrating from a prototype requires a rewrite.

OCaml

Conclusion

One question is library support. OCaml wins here, with the opam package collection. Patching the *compiler* is a different proposition, and something I would rather avoid.

Another question is if I want to consciously avoid tech that is commercially "fashionable". The end-point of this would be writing Java, so where do I want to draw the line? OCaml is probably the most commercially acceptable.

Finally, there's the possibility of re-enabling the development of products from prototypes, as in "Software Design for Flexibility". I reluctantly dropped this when I thought it was required for stricter semantics, e.g. ML-style static typing. Another way to do this is Shen, but that is worryingly niche and dependent on CL (although Mercury does depend on C).

My final favourite is heavily swayed by the "refining prototypes" capability, so that means Mercury (from Prolog prototypes) despite any disadvantages it might have.

Back to my gemlog