Euphoria
A deliberately tiny interpreted language built around just four data types - atoms, sequences, integers, and objects - that traded language complexity for readability and speed.
Created by Robert Craig (Rapid Deployment Software)
Euphoria is a general-purpose interpreted language that made an unusual bet: instead of growing a rich type system, it would ship with almost none. The entire language rests on four built-in data types - atoms, sequences, integers, and objects - and everything else, from strings to records to trees, is expressed as some arrangement of those. Created by Robert Craig in 1993 and released as MS-DOS shareware, it spent thirteen years as a commercial product before going open source in 2006. It remains a small but genuinely working language, with a community-maintained release as recent as 2021.
The name is an acronym: End-User Programming with Hierarchical Objects for Robust Interpreted Applications. It is widely suspected of being a backronym.
History & Origins
Robert Craig was working in Toronto, Ontario, when he began Euphoria as a personal project - an attempt to invent a programming language from scratch rather than to fill a market gap. The first implementation ran on an Atari Mega ST. Craig later described that version as “primitive,” and it was never publicly released.
Many of the design ideas came out of Craig’s Master’s thesis in computer science at the University of Toronto, which was heavily influenced by John Backus’s work on functional programming. That lineage shows up less in Euphoria’s syntax - which is resolutely imperative - than in its data model, where a single flexible aggregate type does the work that most languages spread across arrays, tuples, structs, and strings.
Craig ported the Atari implementation to MS-DOS and released version 1.0 in July 1993 through his company, Rapid Deployment Software (RDS). It was proprietary shareware, distributed through BBSes and later the rapideuphoria.com website. Development continued steadily and commercially for over a decade, working through the 1.x line - community histories place 1.1 and 1.2 in 1994, 1.3 in 1995, 1.4 in 1996, and 1.5 in 1997, though RDS’s surviving release notes only reach back as far as version 2.2.
Going Cross-Platform
The DOS-only era ended with version 2.0, reportedly released in 1998, which added a true Win32 interpreter (exw.exe) alongside the 32-bit DOS one. Version 2.2, released for Linux on 22 November 1999 and for Windows/DOS on 14 January 2000, made Euphoria a real cross-platform language.
The other pivotal addition arrived on 5 June 2001: the Euphoria To C Translator, released as an official 2.2 product. It converted Euphoria source into C that could then be compiled by WATCOM C, LccWin, or Borland C on Windows, GNU C on Linux, and WATCOM or DJGPP on 32-bit DOS. This gave Euphoria a rare property for a scripting language of that era - you could prototype interpreted and ship a compiled native binary from the same source.
Opening Up
Version 2.3 (February 2002) and version 2.4 (July 2003) continued the commercial line, the latter adding namespace qualifiers so that library authors could stop worrying about global name collisions. Version 2.5 (alpha in November 2004, official release 8 March 2005) restructured the implementation itself, splitting the interpreter into a front-end parser written in Euphoria and a back-end plus runtime library written in C. That front end became shared infrastructure for the interpreter, the translator, and the binder.
On 17 October 2006, with version 3.0.0, RDS announced that Euphoria would henceforth be free and open source under a BSD licence - a substantial reversal after thirteen years of selling it. RDS shipped a short run of further releases - 3.0.1, 3.0.2, and 3.1 - ending with 3.1.1 on 22 August 2007, which was both the last RDS version and the last to support MS-DOS.
Craig then stepped back from unilateral development, and the openEuphoria Group - with contributors including Jeremy Cowgar, Matt Lewis, and Derek Parnell - took over. Their version 4.0.0, released on 22 December 2010 after roughly three years of work, brought a rewritten standard library, a new logo and mascot, and a re-launched community site at openeuphoria.org. Point releases followed through 4.0.5, and 4.1.0 was published on 1 March 2021.
Design Philosophy
The openEuphoria project states four goals, and they explain nearly every decision in the language:
- Simplicity - four built-in data types and automatic garbage collection, with no manual memory management to get wrong.
- Legibility - the syntax prefers plain English keywords (
end if,end function,and,or) over punctuation-heavy delimiters. - Rapid development - an interpreter that encourages prototyping and incremental change.
- Performance - a reference-counting collector that handles cyclic references, plus an optional path to compiled C.
The recurring theme is subtraction. Where BASIC - Euphoria’s acknowledged influence - accumulated dialect-specific keywords, and where C demanded pointer discipline, Euphoria removed the category of problem entirely. There are no pointers in ordinary Euphoria code. Subscripts are checked at runtime. There is no way for a routine to index past the end of an array, and no way to leak memory by forgetting to free something.
Key Features
Four Types, and Only Four
| Type | Description |
|---|---|
| Atom | A single number, stored as a 31-bit signed integer or a 64-bit IEEE floating-point value. Euphoria switches representation automatically based on the current value. |
| Sequence | An ordered collection of zero or more elements, each of which may itself be an atom or another sequence. Length is not declared and can change at runtime. |
| Integer | An atom restricted to the 31-bit signed range (-1073741824 to 1073741823). More efficient than a general atom, but narrower. |
| Object | A generic type that may hold an atom, a sequence, or an integer, and may change which during execution. |
Sequences index from 1, and $ refers to the last index. Nested indexing follows naturally: X[3][2] is the second element of the sequence that is the third element of X.
Strings Are Just Sequences
There is no string type. A string literal is a sequence of integer character codes:
"ABC"
is exactly equivalent to:
{'A', 'B', 'C'}
which is exactly equivalent to:
{65, 66, 67}
This is the clearest expression of Euphoria’s economy - every string operation is a sequence operation, so slicing, concatenation, and searching need no separate string library.
Slicing and Concatenation
Because sequences are first-class and resizable, operations that other languages hide behind library calls are ordinary expressions. Deleting an item is a slice-and-concatenate:
global function delete_item( object old, sequence group )
integer pos
pos = find( old, group )
if pos > 0 then
group = group[1 .. pos-1] & group[pos+1 .. $]
end if
return group
end function
Note what is absent: no allocation, no deallocation, no bounds bug, no type parameter. The same function works on a sequence of numbers, a sequence of strings, or a sequence of nested sequences.
Copy-on-Write Parameter Passing
Arguments are always passed by value - there is no pass-by-reference. But parameters may be modified locally, and Euphoria implements this with copy-on-write: passing a sequence initially passes only a reference, and the copy happens only if the callee actually writes to it. Callers get value semantics; large read-only sequences cost nothing to pass.
Execution Modes
Euphoria offers an unusually wide set of ways to run the same source:
- Interpreter - direct execution for development and scripting.
- C translator (E2C) - emits C source, compiled with GCC or Open Watcom, producing standalone executables or shared libraries.
- Binder - joins the intermediate form of your program to the back-end to produce a single executable file.
- Shrouder - obscures source while keeping it runnable, historically important when Euphoria programs were commercial products.
Practical Extras
Euphoria ships a small built-in database engine (EDS), a debugger with an interactive trace screen, runtime error handling, and straightforward facilities for wrapping C libraries via define_c_func and define_c_proc. GUI work is done through community bindings: Win32Lib for the native Windows API, plus wrappers for wxWidgets, GTK+, and IUP.
Performance
The openEuphoria project describes Euphoria as “one of the fastest interpreted languages,” and the language’s speed was a central part of RDS’s original commercial pitch. Two claims are worth separating.
The first is architectural and verifiable: the C translator removes interpretation overhead entirely, so translated-and-compiled Euphoria runs as native machine code rather than through a dispatch loop. That is a design property, not a benchmark result.
The second is comparative - that the interpreter itself is fast relative to peers like Python, Perl, or Ruby. Those comparisons come largely from RDS-published benchmarks of the era and from community microbenchmarks, and they were measured on specific programs, on 1990s and 2000s hardware, against contemporaneous versions of those interpreters. They should not be read as a claim about how Euphoria 4.1 compares to a modern CPython or a JIT-compiled runtime; no current, independently-run benchmark suite covers that comparison. What is defensible is the narrower point the design supports: a reference-counted, four-type value model with no boxing hierarchy has genuinely less per-operation work to do than a fully object-oriented dynamic runtime.
The translator did ship targeted optimizations with stated conditions - for example the -fastfp option, a DOS-only switch used with the WATCOM toolchain that enabled direct hardware FPU code generation for floating-point-intensive translated programs, at the cost of requiring floating-point hardware. RDS-era documentation reported a substantial speedup for such programs, but the figure was never accompanied by a published benchmark program or baseline, and the option was dropped once DOS support ended.
Evolution
Euphoria’s arc is unusual among niche languages. Most either stay commercial and die with their vendor, or start open and stay hobbyist. Euphoria did the reverse of the usual sequence: thirteen profitable-enough years as shareware, then a deliberate handover to an open-source community that has kept it alive for nearly two decades since.
The technical evolution tracks that handover. The RDS era was about reach - DOS to Windows to Linux, interpreter to translator to binder. The openEuphoria era has been about consolidation: the 4.0 standard library rewrite replaced an ad-hoc collection of include files with an organized, namespaced library, and later work has focused on 64-bit support, platform maintenance, and tooling such as Visual Studio Code syntax support added in 2020.
Release cadence has slowed markedly. The gap between 4.0.5 and 4.1.0 spans most of a decade. The project remains administered by the openEuphoria Group, which joined the Open Source Collective in January 2025 and launched a contributor application program in 2024 - signs of an effort to broaden maintenance beyond a small core.
Current Relevance
Euphoria today is a dormant-but-living language. The source is on GitHub, the forum at openeuphoria.org still sees posts, and the project lists Windows, Linux, macOS, and three BSD variants (FreeBSD, NetBSD, OpenBSD) among its supported platforms. What it does not have is momentum: no package ecosystem to speak of, no commercial backing, no job market, and a documentation base that still carries traces of the DOS era.
Its most active descendant is Phix, Pete Lomax’s self-hosted hybrid interpreter/compiler, which adopted Euphoria’s data model wholesale and targets near-complete source compatibility. Phix reached its 1.0 line in 2021 and has continued to develop, with 1.0.5 released in June 2024; for programmers drawn to Euphoria’s ideas, it is often the more practical starting point.
For anyone actually learning Euphoria now, the appeal is pedagogical. It is one of the smallest languages in which you can write a real Windows application, and its four-type model makes the relationship between arrays, strings, and records unusually visible.
Why It Matters
Euphoria’s significance is not adoption - it never had much. It is that Euphoria ran a clean, decade-long experiment on a question most language designers answer by assumption: how much type machinery does a general-purpose language actually need?
The answer Euphoria arrived at was very little, provided the one aggregate type you do have is fully general and fully dynamic. A sequence that can hold anything, nest arbitrarily, resize freely, and slice cheaply turns out to cover strings, arrays, tuples, records, matrices, and trees. Python’s list, Lua’s table, and JavaScript’s array all reached similar conclusions from different directions; Euphoria got there in 1993 and pushed it further than most, refusing even a distinct string type.
It also demonstrated something that has become common practice and was not obvious in the 1990s: that “interpreted” and “compiled” are deployment choices, not language properties. Euphoria let you develop under an interpreter and ship a native binary from identical source, a full decade before that pattern became routine.
And its ending is instructive in its own right. A commercial language that its author chose to give away, rather than let it die with the business, is a rare thing. Euphoria is still here in 2026 because of that decision.
Timeline
Notable Uses & Legacy
The Euphoria front end itself
Since version 2.5 the parser and front end of the Euphoria toolchain have been written in Euphoria, with the same code reused by the interpreter, the C translator, and the binder. It remains the language's largest self-hosted proof of concept.
Language War
A DOS action game written by Robert Craig and shipped as a demo with the Euphoria distribution. It doubled as the language's performance showcase, demonstrating that an interpreted language could drive real-time pixel graphics on 1990s hardware.
Win32Lib
David Cuny's wrapper over the Windows API, later maintained by other community contributors. For years it was the standard way to build native Windows desktop applications in Euphoria.
Euphoria Database System (EDS)
A small file-based database engine shipped in the standard distribution, letting Euphoria programs store structured data without an external database server.
Phix
Pete Lomax's self-hosted hybrid interpreter/compiler adopted Euphoria's atom/sequence/object model and aims for near-complete source compatibility, carrying the design forward as an independent project.