Tools of the trade
I began my journey as a sysadmin at the time of SCO Unix 3.2 v4.2 for i486 CPUs and FreeBSD 1.1.5.1, long before fucking docker, kubernetes and this nix fucking abomination (just imagine creating an exact opposite to UNIX philosophy - standardized intefaces based on text streams - and apply it to unix-like systems).
Anyway, I started as a practitioner and ended up as a sort of a philosopher - investigating not just mathematical foundation of FP, but where that mathematics came from - the foundation of it.
But I still understand UNIX-like systems.
Runtimes
The most difficult and costly part is developing and maintaining a stable runtime system (which runs your code). There are several most famous:
- JVM (the most famous and widely used)
- libstdc++ and libc (yes, this is a runtime)
- Go (all the way from Plan9 and Bell labs)
- .NET (from MS research)
- Erlang (OTP - a telecom-grade)
- Haskell runtime (Rts)
- SML (the classics)
- MIT Scheme runtime (and stdlib)
- Chez Scheme (state of the art)
All of these are open-sourced, which means that, at least in theory, one could fix bugs in them or even adding required features (it is much better to send patches upstream due to “free” code-reviews and extensive testing for free).
One should absolutely prefer languages researched and created by mathematicians, especially good mathematicians (SML) or good researchers (Miranda, Haskell, Ocaml, Scala). A well-studied mathematical foundation (Liskov, Milner, Wadler, Cardelli, Odersky) is what matters in the long run.
Two highly pragmatic choices are:
- F# + .NET 6+ runtime
- Scala3 with OpenJDK17 runtime
In both cases we hanve an ML-family language and a widely used runtime. The crucial difference is that JVM ecosystem are orders of magnitude larger that .NET (ready-made libraries and tools).
In the Java ecosystem one just writes Scala3
to manipulate JVM objects. A whole books has been written about how bad Java is - all Scala books are such books. Java itself is a monument of human ignorance and stupidity (second only to PHP).
Considering language features, there is nothing better than Haskell and modern Ocaml (which will finally have a proper multicore support on 5.0).
- Haskell is a culmination of pure Lambda-Calculus, Miranda lineage (via the seminal Bird & Wadler book)
- Ocaml is a crown jewel of the ML family (continues from where SML left off).
Erlang and Go have their own niches respectively, with its own tooling and communities. They both are great.
So, when thinking about prototyping or bootstrapping of a project nothing can be compared to an ML-family language (a Hindley-Milner type system + sum-types + pattern-matching everywhere). Sum-types are the crucial part.
Everyone is already brainwashed about Python, of course, but Ocaml and F# are even better in any metrics. And, ironically, Python with type annotations is similar to imperative subset of Ocaml (minus libraries, of course).
Libraries
One absolutely wants to rely on well-researched, mature standard libraries from major research centers and never come close to amateur crap like node_modules
or Rust’s crates
.
The state-of-the-art stuff are:
- OTP (just a telecom-grade stuff)
- LLVM’s libc++ (a clean rewrite)
- Java’s class library is at least well-tested and stable
- SML Basis library (Bell Labs)
- Go stdlib (Bell Labs, the Plan9 project)
- .NET (MS research)
- Ocaml stdlib (NOT Core)
- Haskell platform (GHC + a set of libs)
- Scala3 collections (as a wrapper around Java classes)
A standard library nowadays has literally everything one need to write a modern compiler and network/concurrent code. One should restrict oneself to this highest quality stuff. Amateur code is just a junk-food level crap.
If you cannot write using stdlib, bootstrapping domain-specific libraries and languages as you go, you are not even close to a “good programmer”, and webshit is not programming at all, it is merely coding (filling structures).
Methodology
Tools are important (those who tried to debug weakly typed dynamic languages, when one misspelled a single letter in some structure’s member and nothing happened would appreciate static typing) but not enough.
Methodologies, which arise partially due to particular tooling, are much more important.