I’ve written code in well over a dozen programming languages. I’m always ready to learn another, and there’s always someone eager to sell me on their favorite.

However, if I’m going to learn a new language at this point, it has to be a better fit for me than the ones I’m already using and the ones I’ve already tried and abandoned. No language is perfect, and I could criticize even my favorites, but some are a better match to my needs and desires than others.

So to save time, here’s what I’m looking for in any new programming language, with examples to try to clarify what I mean.

Platform support

Unix family, specifically including macOS and Linux.

AMD64, ARM and RISC-V.

I don’t care about Windows.

Licensing

Open source with a free software license, so it can’t suddenly be destroyed by a malicious corporation.

Syntax

I have a hard time remembering syntax, so I want something that’s simple. Ideally it should also be clean and easy to read, with a minimum of sigils and operators.

Good: Scheme, Go, Ruby
Adequate: Java, Swift
Horrible: C++, Perl, Rust

Library

I want the standard library to have good coverage of POSIX APIs. Again, I don’t care about Windows. The standard library should have support for TCP/IP connections, UDP, Unix domain sockets, Unix permissions, standard cryptographic algorithms, JSON and XML and base64, Unicode, and so on, or else it’s just a toy language.

I also want a standard package manager. Just one, maybe two tops.

Good: Ruby, Go
Adequate: Java
Horrible: Scheme, JavaScript

Interoperability

Since I’m not going to be able to find everything for this new language, I need to have the option of occasionally using code written in something else. That means I want some reasonable FFI option.

Good: C, Zig, Kotlin.
Adequate: Go.
Horrible: Java.

Language features

These are in approximate descending importance:

  • Basic types: unsigned bytes, 32 and 64 bit unsigned integers, signed integers, strings, variable-length arrays, hashes/maps.

  • Decimal floating point numbers (decimal64 and decimal128).

  • UTF-8 support throughout the entire language.

  • Static typing with compile-time type checking.

  • Lexical scoping.

  • Object-orientation through composition.

  • Automatic memory management, either through a fast garbage collector or through some sort of unintrusive and robust reference-counting system. (Examples: Go, Rust.)

  • First-class functions.

  • Functions that can return tuples. (Examples: Ruby, JavaScript, Go.)

  • Fast compile times. (Example: Go. Horrible: C++.)

  • Trivially easy cross-compilation. And by trivially easy, I mean “set one option on the compile command and you’re done” easy. (Example: Go.)

  • More advanced types: arbitrary precision integers, arbitrary precision decimal floating point numbers, rationals.

  • Immutability by default. (Examples: Scala, Haskell.)

  • Tail-call elimination.

  • Function overloading.

  • Parametric polymorphism.

  • Facilities to make safe concurrency easier, such as CSP structures. (Examples: Go, Kotlin.)

  • Small binaries and a lightweight runtime. (Examples: Zig, C.)

  • A good native GUI option for macOS and Linux.

  • One defined standard set of formatting conventions, and a formatter to implement them. (Example: Go.)

Unimportant

Things I don’t particularly want or care about but I’m OK with them:

  • OO class inheritance.

  • Ubiquitous type inference. (I prefer to state my types, thanks.)

  • Multiple implementations.

  • Option types.

  • Binary floating point numbers.

Undesirable

Things I don’t want, but I’m willing to put up with them:

  • Pointers.

  • Null (used to represent an absent value, like in SQL).

  • Nil (a zero value, like in Go).

Deal killers

There are some things I’m just not willing to put up with:

  • Semantic whitespace. (Examples: Python, YAML.)

  • A de facto requirement for containers or virtual environments. (Examples: Python, JavaScript.)

  • A required special IDE. (Examples: Smalltalk.)