An experiment in implementing the same recursive counting problem across programming languages, from ALGOL, B, BCPL, and Simula to contemporary systems languages, functional languages, scripting languages, and foreign-function interfaces.
This is primarily a collection of source-code examples and historical build notes, not a curated set of verified modern builds or a standardized performance benchmark. Some compilers and interpreters are obsolete or require patches. The 150 directories are implementations and language combinations, not 150 distinct programming languages.
- The counting problem
- Reference results
- Quick start
- Language catalog (A–Z)
- Cross-language interoperability
- Language families and lineages
- Versions and historical toolchains
- Build status and reproducibility
- Contributing
- License
The programs count ordered sequences of card ranks that can be drawn without exceeding a running total of 21, from a finite single deck, after a dealer's exposed card has been removed.
The deck is represented by ten ranks, with values 1, 2, ..., 10 and initial multiplicities
rank: 1 2 3 4 5 6 7 8 9 10
multiplicity:4 4 4 4 4 4 4 4 4 16
Here rank 1 represents an ace, always counted as 1; rank 10 combines tens, jacks, queens, and kings. The programs do not implement the complete rules of casino Blackjack.
For each possible dealer upcard rank d, the program:
- Removes one card of rank
dfrom the deck. - Considers each possible rank
jfor the player's first card, removing one such card. - Recursively draws at least one additional player card; each legal new prefix (total at most 21) contributes one outcome, representing the choice to stop after that draw.
- Also explores further draws when the running total is below 21. Draws that bust are discarded, and a total of exactly 21 cannot be extended.
- Sums these counts over the ten possible initial player ranks.
Important conventions: A hand with only one player card is not counted. Rank order matters, but individual physical cards of the same rank are indistinguishable for counting purposes. The rank multiplicities limit the available draws; they are not probability weights. Thus the result is not the number of suit-distinct deals, nor a probability, nor the number of winning Blackjack hands.
Let c = (c_1, ..., c_10) be the available rank multiplicities, and let F(c, s) count the admissible nonempty continuation sequences from subtotal s. Writing e_k for the unit vector of rank k,
F(c, s) = sum over k with c[k] > 0 and s+k <= 21 of
(1 + (s+k < 21 ? F(c-e[k], s+k) : 0)).
The 1 counts the option to stop after drawing rank k. The recursive term counts longer sequences. Starting from the full deck c0, the count for a dealer upcard of rank d is
N[d] = sum over available initial player ranks j of
F(c0-e[d]-e[j], j).
The implementations use direct recursion and, in some cases, variations or cross-language calls. The formulas above specify the intended reference calculation; they do not prescribe an optimization strategy.
The reference C implementation is c/outcomes.c. Its checked-in output is c/outcomes.txt.
| Dealer's visible rank | Count |
|---|---|
| 1 (ace) | 417,334 |
| 2 | 560,954 |
| 3 | 658,854 |
| 4 | 679,464 |
| 5 | 680,299 |
| 6 | 680,305 |
| 7 | 680,305 |
| 8 | 680,305 |
| 9 | 680,305 |
| 10 (ten-valued) | 680,305 |
| Sum over dealer ranks | 6,398,430 |
Some programs print zero-based rank indices (Dealer showing 0 through Dealer showing 9) instead of card values (1 through 10). The output labels therefore differ by one, but the reference counts are in the same order. The final sum is over rank categories, without weighting by the number of physical dealer upcards.
outcomes.txt files may also include wall-clock or CPU timings measured on their original systems. Those timings are historical and should not be compared as a controlled language benchmark.
From the repository root:
cd c
cc -O2 -std=c11 -o outcomes outcomes.c
./outcomesThe final line should be:
Total partitions = 6398430
cd python
python3 outcomes3.pyPython 2 and Python 3 variants are kept separately where they existed historically; Python 2 is obsolete and is not required for the Python 3 example.
- Cyclone: a safer dialect of C; historical
cyclonetoolchain required. - ALGOL W: can use the companion aw2c translator.
- SuperPascal: uses the companion SuperPascal compiler/interpreter.
- Niecza: an implementation targeting the CLR for Perl 6 / Raku.
- BCPL and B: early predecessors in the C family.
These entries illustrate historical toolchains; their build commands are not certified against current Linux distributions.
121 single-language or runtime-variant directories, in alphabetical order. The first link opens this repository's implementation; the last link opens the compiler/interpreter project or language documentation. The descriptions summarize each language or variant, not a tested compiler version. For exact historical commands, consult the directory's own README.md when available.
Some entries are distinct implementations of the same language (such as CPython/PyPy/MicroPython/Jython or several Scheme compilers), and others are embedded languages or scripting environments (such as PostgreSQL SQL and shell languages). They are retained as separate implementation directories, not counted as 121 different language specifications.
| Language / implementation | Description | Compiler, interpreter or reference |
|---|---|---|
| Ada | Statically typed systems language emphasizing reliability and concurrency | GNAT / Ada |
| AFNIX | Functional/object-oriented scripting language with its own interpreter | AFNIX |
| ALGOL 68 | Expression-oriented ALGOL-family language with orthogonal types | ALGOL 68 Genie |
| ALGOL W | Wirth's ALGOL-family language; source-to-C translation in this project | aw2c (companion repository) |
| AmbientTalk | Actor-oriented distributed object language | AmbientTalk |
| Awk | Pattern/action text-processing language | GNU Awk |
| B | Early systems language descended from BCPL, preceding C | Amsterdam Compiler Kit (ACK) |
| Bash | Bourne-family Unix shell and scripting language | GNU Bash |
| BASIC | BASIC implementation built with FreeBASIC (fbc) |
FreeBASIC / historical BASIC |
| bc | Arbitrary-precision command-line calculator language | GNU bc |
| BCPL | Richards's Basic Combined Programming Language, predecessor of B | BCPL compiler (see local notes) |
| Bigloo | Scheme implementation compiling to C and other backends | Bigloo |
| Boo | Python-like statically typed language targeting .NET/Mono | Boo |
| Boron | REBOL-inspired small extensible scripting language | Boron |
| C | General-purpose systems language; direct recursive baseline | GCC / C |
| C# | C-family managed language for .NET | C# / .NET |
| C++ | C++ systems language with classes and templates | GCC / C++ |
| Ceylon | Statically typed language originally targeting JVM and JavaScript | Ceylon (archived) |
| Chapel | Parallel language for scalable scientific computing | Chapel |
| Chez | Optimizing implementation of Scheme | Chez Scheme |
| Chicken | Scheme implementation that translates to C | CHICKEN Scheme |
| CLISP | Common Lisp implementation and interpreter/compiler | CLISP |
| Clojure | Functional Lisp dialect on the JVM | Clojure |
| COBOL | Business-oriented language; classic procedural style | GnuCOBOL |
| Cobra | Original Chuck Esterbrook .NET/Mono language, influenced by Python and Eiffel | Historical Cobra reference |
| Crystal | Ruby-like statically typed compiled language | Crystal |
| Cyclone | Research dialect of C with regions and safer pointer types | Cyclone compiler (historical) |
| Cython | Python superset translated to C with optional static types | Cython |
| Cython (array) | Alternative Cython variant emphasizing array representation | Cython |
| D | D systems language with C-like syntax | DMD / LDC |
| Dart | Object-oriented language used by Flutter | Dart |
| Elixir | Functional concurrent language on the Erlang VM | Elixir |
| Euphoria | High-level interpreted/compiled imperative language | OpenEuphoria |
| F# | Functional-first .NET language of the ML family | F# |
| Fantom | Portable object-oriented language on JVM/.NET | Fantom |
| Felix | Functional/systems language targeting native code | Felix |
| Fish | User-friendly interactive shell scripting | fish |
| Forth | Stack-based concatenative language | Gforth |
| Fortran | Scientific and numerical programming language | GNU Fortran |
| FriCAS | Computer-algebra language and environment; input script in FriCAS | FriCAS |
| Language / implementation | Description | Compiler, interpreter or reference |
|---|---|---|
| Gambit | Scheme-to-C compiler and runtime | Gambit Scheme |
| Go | Concurrent compiled systems language | Go |
| Gosu | Statically typed JVM language with Java interoperability | Gosu |
| Gravity | Lightweight embeddable scripting language | Gravity |
| Groovy | Dynamic JVM language with Java interoperability | Groovy |
| Guile | GNU Scheme implementation | GNU Guile |
| Hack | Gradually typed PHP-family language | Hack |
| Haxe | Cross-platform language compiling to multiple targets | Haxe |
| Icon | Goal-directed expression-evaluation language | Icon |
| IDL | IDL-like array programming; the README uses the open-source GDL interpreter | GNU Data Language (GDL) |
| Io | Prototype-based object language with message syntax | Io language |
| Java | Managed object-oriented JVM language | OpenJDK |
| JavaScript | ECMAScript scripting language | JavaScript / Node.js |
| Julia | High-performance dynamic numerical language | Julia |
| Jython | Python implementation targeting the JVM; version-sensitive | Jython |
| Kotlin | Statically typed JVM and multiplatform language | Kotlin |
| Ksh | KornShell, Bourne-shell descendant | KornShell |
| Larceny | R6RS-oriented Scheme implementation | Larceny |
| Lily | Small dynamically typed scripting language | Lily |
| Lua | Small embeddable scripting language | Lua |
| Language / implementation | Description | Compiler, interpreter or reference |
|---|---|---|
| Maple | Symbolic and numerical computing language | Maple |
| Mathematica | Wolfram symbolic-computing language | Wolfram Language |
| MATLAB | Array-based commercial numerical programming language | MATLAB |
| MicroPython | Compact Python implementation for microcontrollers | MicroPython |
| MIT Scheme | MIT/GNU implementation of Scheme | MIT Scheme |
| Modula-2 | Wirth's modular successor to Pascal | GNU Modula-2 |
| Modula-3 | Modula-family systems language with safe modules and interfaces | Critical Mass Modula-3 |
| Myrddin | Small statically typed systems language influenced by C and ML | Myrddin |
| Nemerle | Typed .NET language combining OO and metaprogramming | Nemerle |
| Niecza (Raku/Perl 6) | Perl 6 compiler/implementation targeting the CLR; pre-Raku era | Niecza (companion fork) |
| Nim | Compiled language with Python-like syntax and metaprogramming | Nim |
| Numba | Python variant using LLVM-based JIT on numeric kernels | Numba |
| Oberon | Wirth's minimal Pascal/Modula successor | Oberon |
| Objeck | Object-oriented VM language | Objeck |
| Octave | MATLAB-compatible numerical language | GNU Octave |
| Odin | Data-oriented compiled systems language | Odin |
| ParaSail | Pointer-free parallel language descended from Ada design ideas | ParaSail |
| Pascal | Structured imperative language; local implementation uses a Pascal compiler | Free Pascal |
| Perl | Dynamic text-processing and general scripting language | Perl 5 |
| Perl 6 / Raku | Perl 6 language, now named Raku | Raku / Rakudo |
| PHP | Dynamic language frequently used for web programming | PHP |
| Pike | Dynamic object-oriented language with C-family syntax | Pike |
| PL/I | IBM PL/I: combined scientific/business programming language | PL/I |
| Pony | Actor-model concurrent language with reference capabilities | Pony |
| PostgreSQL | SQL with PostgreSQL function/procedure extension, not a standalone compiler | PostgreSQL |
| PowerShell | Object-pipeline shell and automation language | PowerShell |
| PureBasic | Compiled BASIC-family language | PureBasic |
| PyPy | Python implementation with a tracing JIT | PyPy |
| Python | Python 2 and Python 3 versions preserved | Python / CPython |
| Qore | Dynamic language supporting multithreaded integration | Qore |
| R | Statistical computing and graphics language | GNU R |
| Racket | Lisp/Scheme descendant emphasizing language-oriented programming | Racket |
| REBOL | Data-exchange and dialecting language | REBOL |
| Red | REBOL-inspired language with a native systems component | Red |
| Regent | Task-based parallel language embedded in Terra, using Legion | Regent |
| REXX | String-oriented scripting language | Regina REXX |
| Ruby | Dynamic object-oriented scripting language | Ruby |
| Rust | Memory-safe compiled systems language | Rust |
| Language / implementation | Description | Compiler, interpreter or reference |
|---|---|---|
| Sage | Python-based computer-algebra environment | SageMath |
| SBCL | Optimizing Common Lisp compiler/runtime | SBCL |
| Scala | JVM language combining functional and object-oriented programming | Scala |
| Seed7 | Extensible compiled/interpreted general-purpose language | Seed7 |
| Simula | Historic object-oriented language from the ALGOL family | GNU Cim / Simula |
| Squirrel | Small embeddable C-like scripting language | Squirrel |
| Stalin | Whole-program optimizing implementation of Scheme | Stalin Scheme compiler |
| SuperCollider | Real-time audio synthesis and object-oriented language | SuperCollider |
| SuperPascal | Per Brinch Hansen's parallel extension of Pascal | SuperPascal (companion port) |
| Swift | Compiled multiparadigm language with safety features | Swift |
| Tcl | Embeddable command language | Tcl |
| TypeScript | Typed superset of JavaScript | TypeScript |
| Unicon | Object-oriented evolution of the Icon language | Unicon |
| V | Small compiled Go-inspired systems language | V |
| Vector Pascal | Pascal extended with array/SIMD operations | Vector Pascal compiler |
| Vicare | R6RS Scheme implementation | Vicare Scheme |
| Visual Basic | Visual Basic .NET source compiled with vbc and run under Mono |
Visual Basic |
| Wren | Compact class-based embeddable scripting language | Wren |
| X10 | Partitioned-global-address-space parallel language | X10 |
| Yorick | Interpreted array language for scientific computing | Yorick |
| Zig | Low-level compiled language with explicit memory management | Zig |
| Zonnon | Modula/Oberon-descended language for .NET; active objects | Zonnon |
| Zsh | Extended Bourne/Korn-style shell | Zsh |
Important historical name collisions: cobra/ is the older Chuck Esterbrook .NET/Mono language (not later languages also called Cobra). idl/ uses the GNU Data Language (gdl) interpreter, as shown in its README. niecza/ is a Perl 6 implementation targeting the CLR, not a separate language specification. Likewise, stalin/, chez/, chicken/, gambit/, larceny/, and vicare/ are distinct Scheme implementations.
The remaining 29 directories deliberately mix languages or build separate native libraries. They are indexed separately so they do not inflate the number of distinct programming languages. Descriptions below are based on the checked-in README commands and representative source calls; no recent end-to-end build is implied.
| Directory | What it demonstrates | Toolchains / interface references |
|---|---|---|
| Ada ↔ Zig | Ada driver calling a Zig-built native shared library | GNAT + Zig |
| C ↔ C | C executable loading a C shared library at runtime (dlopen) |
GCC + POSIX libdl |
| C ↔ Fortran | C driver linked with a Fortran recursive function | GCC + gfortran |
| Fortran ↔ C | Fortran driver calling a C implementation | gfortran + GCC |
| Julia ↔ C | Julia driver using ccall to invoke a C shared library |
Julia + GCC |
| Julia ↔ Nim | Julia ccall into a Nim-built shared library |
Julia + Nim |
| Python ↔ Ada | Python caller and a GNAT-compiled Ada library; README assumes older GNAT development headers | Python + GNAT |
| Python ↔ Basic | Python caller and FreeBASIC shared library | Python + FreeBASIC |
| Python ↔ C | Python ctypes calling a C shared library; Python 2/3 variants |
Python + GCC |
| Python ↔ C / CFFI | Python cffi.FFI().dlopen() calling a C shared library |
CFFI + GCC |
| Python ↔ C++ | Python caller with C++ compiled as a shared library | Python + G++ |
| Python ↔ D | Python calling a D shared library; DMD/LDC build recipes | D + Python |
| Python ↔ D / CFFI | Python CFFI-style interface to a D shared library | CFFI + D |
| Python ↔ Fortran | Python calling a gfortran-built shared library | Python + gfortran |
| Python ↔ Fortran / CFFI | Python CFFI-style caller and Fortran shared library | CFFI + gfortran |
| Python ↔ Go | Python calling a Go -buildmode=c-shared library |
Python + Go |
| Python ↔ Nim | Python calling a Nim --app:lib shared library |
Python + Nim |
| Python ↔ Nim / CFFI | Python CFFI-style interface to a Nim library | CFFI + Nim |
| Python ↔ Pascal | Python calling a Free Pascal-built library | Python + Free Pascal |
| Python ↔ Rust | Python ctypes calling a Cargo-built Rust library |
Python + Rust |
| Python ↔ Rust / Slice | Python 2 ctypes example passing pointer and explicit length to Rust |
Python + Rust |
| Python ↔ Swift | Python calling a Swift -emit-library shared library |
Python + Swift |
| Python ↔ Zig | Python calling a Zig native shared library; zig build-lib recipe |
Python + Zig |
| R ↔ C ↔ C | R .C() interface to a C shared library built using R CMD SHLIB |
R + C |
| Ruby ↔ C | Ruby FFI gem calling a C shared library | Ruby FFI + GCC |
| Ruby ↔ D | Ruby FFI caller and DMD/LDC-generated library | Ruby FFI + D |
| Ruby ↔ Fortran | Ruby FFI caller and Fortran shared library | Ruby FFI + gfortran |
| Ruby ↔ Go | Ruby FFI caller and Go c-shared library |
Ruby FFI + Go |
| Ruby ↔ Nim | Ruby FFI caller and Nim --app:lib library |
Ruby FFI + Nim |
In particular, the repositories illustrate several different FFI mechanisms, not just calling a second program: native shared libraries with C-compatible ABIs, dynamic linking (dlopen), Python ctypes, Python cffi, Julia ccall, R .C(), and Ruby FFI. These APIs have different ownership and ABI assumptions; a successful call is not by itself a portable interface contract.
This is a conceptual map, not a rigid taxonomy. Arrows indicate major historical descent or influence; shared runtimes and similar syntax do not imply direct descent. A language may appear in more than one family.
- ALGOL line: ALGOL 60 influenced ALGOL W and ALGOL 68 along different branches. Simula extended ALGOL 60 with classes and coroutines and became an important ancestor of object-oriented programming.
- Wirth line: ALGOL W and other ALGOL ideas informed Pascal → Modula-2 → Oberon. Modula-3 developed from Modula-2 ideas; Zonnon is a later Pascal/Modula/Oberon-family language.
- Pascal extensions: SuperPascal extends Pascal with structured concurrency; Vector Pascal extends it with array and SIMD operations. They are parallel derivatives, not sequential revisions of Pascal.
- Direct historical chain: BCPL → B → C.
- C extensions and descendants: C++ adds major object-oriented and generic features; Cyclone retains much of C's syntax while adding safer pointer/region typing. D is heavily C/C++ influenced, but not a drop-in successor.
- Other C-syntax relatives: Java, C#, JavaScript, TypeScript, Go, Rust, Zig, Odin, and V share varying C-style syntax or systems-programming goals; they are not one linear genealogy.
- Lisp / Common Lisp: CLISP and SBCL implement Common Lisp.
- Scheme: MIT Scheme, Chez Scheme, CHICKEN, Gambit, Guile, Larceny, Vicare, Bigloo, and the Stalin compiler cover several Scheme implementations and compilation strategies. Racket originated as a Scheme implementation and later expanded into a language-creation platform.
- Other Lisp descendants: Clojure targets the JVM with persistent functional data structures. F# belongs principally to the ML/OCaml functional tradition rather than Scheme.
- BASIC family: BASIC, PureBasic, and Visual Basic reflect distinct dialects or descendants of BASIC, and should not be assumed source compatible.
- JVM languages: Java, Kotlin, Scala, Groovy, Gosu, and Ceylon share a runtime target, but have differing language origins. Jython is a Python implementation on that runtime.
- .NET / CLR: C#, Visual Basic, F#, Boo, Nemerle, the original Cobra, and Niecza demonstrate different language designs on a common managed platform.
- BEAM: Elixir builds on the Erlang virtual machine and ecosystem; unlike JVM/.NET languages above, its direct ancestor in runtime terms is Erlang (not represented by a standalone directory here).
- Python contains historical Python 2 and Python 3 programs. PyPy runs Python with a JIT; Jython targets the JVM; MicroPython targets constrained systems.
- Cython and Cython (array variant) compile a Python-derived language into extension code; Numba JIT-compiles selected Python functions. They are alternative implementations or acceleration strategies, not independent unrelated languages.
- REBOL lineage: REBOL influenced Boron and Red.
- Unix shells: Bash, KornShell, and Zsh are related Bourne-shell descendants; fish is a different shell design. PowerShell is object-pipeline oriented, not Bourne-shell compatible.
- Scientific / array languages: Fortran, MATLAB, Octave, Julia, R, IDL/GDL, Yorick, Maple, Mathematica, and SageMath form an application/ecosystem grouping, not a single historical ancestry. MATLAB and Octave are intentionally related; SageMath uses Python as its interface language.
- Concurrency / distributed / parallel experiments: Chapel, Regent, X10, ParaSail, Pony, AmbientTalk, and SuperPascal illustrate distinct approaches to parallelism, actors, locality, and type-enforced concurrency.
A language name is not a compiler version. Unless a README records a number, a build recipe usually establishes only a toolchain identity. Source extensions, language syntax, target runtimes, and flags can narrow the dialect, but cannot by themselves establish a precise compiler release. In particular, the links above are references to upstream documentation, not claims that their latest versions compile this code.
Some identifiable cases worth retaining in future per-directory READMEs:
| Directory | Evidence in repository | What can responsibly be concluded |
|---|---|---|
basic/ |
fbc -O 3 outcomes.bas |
FreeBASIC compiler; exact release unknown |
b/ |
ack -mlinux386 |
Amsterdam Compiler Kit targeting a 32-bit Linux platform; exact ACK release unknown |
algol-w/ |
./aw2c and generated outcomes.c |
Companion ALGOL W → C compiler; exact build/version not recorded |
cobra/ |
cobra ... -turbo:yes and .cobra |
Historical Chuck Esterbrook Cobra compiler, not one of the newer homonymous languages |
cyclone/ |
.cyc and cyclone outcomes.cyc |
Original Cyclone C dialect; compiler version and 64-bit support not established |
idl/ |
gdl -q run.idl |
GNU Data Language is the implementation used, rather than proprietary IDL |
vb/ |
vbc /optimize+ outcomes.vb and mono outcomes.exe |
Historical Visual Basic .NET compiler targeting the Mono CLR |
niecza/ |
Niecza.exe outcomes.p |
CLR-targeted Perl 6 implementation; precise Niecza build unknown |
python/ |
outcomes2.py, outcomes3.py |
Separate Python 2 / Python 3 source variants; Python 2 is end-of-life |
python-ada/ |
Old libgnatvsn7-dev/GCC 7 library paths |
Historical GNAT installation assumptions; adaptation likely needed on new systems |
python-rust-slice/ |
xrange in Python driver |
Python 2 code even though the native library uses Rust |
superpascal/ |
Separate compilation then ./interpret |
Per Brinch Hansen SuperPascal; see the companion Free Pascal port |
Proposed per-language README convention (to implement gradually): language and dialect; compiler/interpreter and exact tested version (or unknown); canonical upstream source/docs; prerequisites; build and run commands; observed results; portability notes; and date/platform of last actual verification. Historical commands should be preserved without silently replacing them.
Most directories contain an outcomes.* driver and often a partitions.* helper, a short README.md, and an outcomes.txt transcript. Some tools emit C as an intermediate artifact; some scripts require a shared library, external runtime, or source files from a companion repository.
This repository expands the related octonion/puzzles/blackjack collection. recursion covers 150 implementation directories, compared with 136 under puzzles/blackjack. All 136 directory names occur here, but a few files exist only in the earlier tree (including a compiled SuperPascal artifact and an optimized SBCL variant). Review those differences before consolidating.
Do not assume every example still builds. Many READMEs preserve commands used at the time of development; there is currently no repository-wide CI matrix that verifies all 150 directories on modern toolchains.
For reproducible comparisons, record:
- Operating system and architecture, plus compiler/interpreter and version.
- Exact build and execution commands (including optimization flags).
- Whether the program completes and matches all ten reference counts and the total.
- Any patches needed for compatibility, and whether they change the algorithm.
- Timing methodology, if performance is being reported (including warmup, repetitions, and hardware).
A successful build is not necessarily a successful execution; and matching a total alone is weaker evidence than matching all ten counts. Historical outcomes.txt files serve as reference artifacts, not evidence that a current toolchain has been tested.
Contributions that recover older toolchains, document build dependencies, add missing language READMEs, repair portability problems, or expand regression tests are welcome. In particular:
- Keep the original language implementation and historical notes intact where feasible; isolate modern compatibility changes.
- Document the compiler/runtime version and a command that runs from the relevant language directory.
- Report whether the output matches the ten reference counts above; distinguish untested code from a verified build.
- Avoid calling measurements a cross-language benchmark unless algorithms, compilation settings, and measurement conditions are controlled.
A useful longer-term goal is an automated test matrix for readily available compilers, plus an optional, separately documented suite for historical and unsupported environments.
MIT. Copyright © 2018 Christopher D. Long.