This document details the changes made to Mars since its first release. This
is a fairly high-level document, describing only the visible changes. For
details on the individual bugs fixed, see the bugs targeted to each release
in the trunk series. For a complete
history of changes to Mars, see the commit log.
Released Thursday, 27 Oct 2011
This version focuses almost exclusively on redesigning the Mars internal
representation so that it is easier to implement in low-level back-ends such
as LLVM. While there are almost no publicly-visible changes, the instruction
set architecture is drastically different than in previous versions. The code
generator has to work much harder to generate lower-level code, but this pays
off in that the many different back-ends have a much easier job to do.
- Case-bound variables now conform to SSA, preventing internal errors for some
- Fixed temporary names being reused within a single-case switch.
- Fixed interactive mode not catching errors raised by evaluating CGCs.
- Fixed interactive mode remembering the value of every temporary variable in
the history of the session.
- Fixed mars.exec_main_func; now puts the result in the localtable.
- Internal software errors now go to stderr, not stdout.
- When printing the environment, fixed internally representing constructor
names with gvname, which they aren’t supposed to be represented as.
- Fixed the built-in show type (the variable a was not rigid).
- The test framework now reports test cases that crash and those that don’t
- Readline completion no longer shows internal (synthetic) functions.
- The “:e” display no longer shows subscripted variables.
- Fixed the ordering of blocks in the Mars IR code. It now reasonably well
follows the order of the original source code.
- The show and eq functions are now implemented
non-primitively using type dictionaries (see Type dictionaries). This
means back-ends do not need to supply an implementation for these
- Changed the semantics of the field access instructions so they are much
lower level. The code generator now generates field access functions in Mars
IR to non-primitively perform the high-level actions. The instructions
implemented by the back-end now perform very simple tasks.
- There is now an instruction for directly calling a constructor, rather than
having to load it into a local function first.
- Major change to Mars IR: global variables are no longer accessible as
variable names (only local variables). Rather, we provide special
instructions to call and load the value of global variables.
- Mars IR can no longer partially apply functions. Replaced this feature by
introducing “closure templates” which are much easier to implement on
low-level back-ends. The code generator must now generate a closure template
for each partial application, which explicitly accepts a certain number of
parameters in its closure.
- Removed instructions for loading int literals and constructor symbols;
instead, int literals and constructor symbols are considered to be “atoms”
along with variable names, and atoms can now be referenced by most
instructions that used to refer only to variable names.
- Renamed the internal function ir.varname_to_string_noescape to
Released Friday, 25 Jun 2010
Core language changes
- Pattern bindings in case statements are now like any other
assignment – scoped to the entire function and in the same namespace as all
the other locals. Patterns no longer create a new scope, and the variables
they create no longer shadow existing locals. It is now a type error if a
local variable has the same name but different type as a pattern variable
- It is now a compiler error if a switch statement does not cover
all possible constructors of the type it switches over, preventing the
possibility of runtime pattern match failure errors (backwards
- Variables no longer require declaration. Any variable assigned in a function
is now implicitly a local variable. It is no longer an error to assign to a
global variable or an undefined variable (this just creates a new local
- The field reference and replace expressions and the field update statement now work (previously they displayed
“not implemented” errors). It is now possible to access and update
individual fields of an object by name, without having to use a
- The field replace statement is now an
expression; its result is the updated object. It previously didn’t make much
sense because the statement performed an implicit assignment of its source
- The field update operator changed from
“=” to “=!”, reflecting its impure nature.
- It is now an error to have two fields of the same name in a given
- It is now an error to have two variables of the same name in a given
- Reading the value of (and therefore executing the body of) a computable
global constant now caches the result so subsequent reads do not re-execute
the body. Previously CGCs would be re-executed on each read.
- The built-in is function has been moved to the impure module.
- The is function now works on objects of user-defined types
(previously always returned 0).
- Added prelude function ref which gets the element of a list
with a particular index.
- Paul Bone: Fixed error compiling Mars on some systems, due to Readline code.
- Critical type safety problem – if a declared local variable and pattern
binding have different types, after the switch, the variable name
has the declared type, but the value bound by the case (of the wrong type).
Fixed by giving pattern bindings the full function scope, forcing them to
have the same type as any declared variable.
- Internal error “Phi missing predecessor in CFG” for programs with complex
- Internal error “Field reference to something not an ADT” for case statements
with a nested pattern with two fields.
- Type error for cases with int literals on polymorphic types.
- Internal error for string literals with '\0.
- Internal error calling error or get_env with '\0 in
- Library function encodeURIComponent gives garbage output on strings
with non-byte characters.
- Now correctly sets the exit status of Mars to the result of main –
rounds to a machine-size int with wraparound rather than using mod.
- The show function now correctly includes empty parens for terms
built from nullary constructors.
Test suite and internal changes
- Replaced “dummy term binding” technique with explicit rigid type variables
(as now described in documentation for type unification).
- The control-flow graph (CFG) representation now includes full type
- The t_switch instruction no longer includes fully-recursive patterns,
but a limited format which matches only a single tag. Switch
statements are now factored into this much lower-level
construct which is easier to compile into machine code.
- The interactive environment now uses SSA variable names, so variables which
are re-assigned are no longer physically clobbered in the environment; they
are assigned with a new qualified name. This makes the semantics of
interactive consistent with the rest of the language and fixes issues with
certain backends or analyses.
- Fixed test suite silently treating invalid “outcome” values as “fail”.
- No longer generates code for statements which are inaccessible because they
are preceded by a return statement. This prevents malformed code
- Fixed parser not allocating a type to subexpressions of expressions which
already have a type annotation.
- Interactive mode executes type-annotated versions of statements.
- Test suite is now orders of magnitude faster to run (fixed re-compilation
for every case, causing N^2 behaviour).
- Interpreter interface is now abstracted so it is possible to plug in
different interpreter backends.
- In the test framework, expecting a compile error now causes all of the
runtime tests to be expected to be skipped, so they don’t raise large errors
when they are.
- Terminator instructions now hold a context object.
- Function signatures no longer have an “argmode”. This was part of some
uniqueness information analysis which was abandoned for a different
representation, and has since been unused and completely obsolete.
- All library functions are now documented.
- The documentation is now syntax-highlighted for all Mars code.
- If a bug in Mars causes an internal error, it will be displayed much more
neatly, with a link to the “file bug” page on the bug tracker.
- The test framework no longer generates .py files with Mars assembly (a
bug dating back to when we actually generated Python output).
- The src directory now includes a Makefile, so Mars can be compiled
with a simple make.
- The Mars Vim script (misc/mars.vim) has an updated list of built-in
Released Friday, 27 Nov 2009
Core language changes
- Rather than searching the current directory for imports, searches the
directory the initial module is located in. This makes multi-module
programs possible, without having to run them from the current directory
or add them to MARSPATH.
- No longer searches for the prelude in the current directory.
- Mars now allows source files with DOS/Windows newlines.
- New built-in functions: array_add,
array_remove, __impure_array_delete (also added
array_delete to impure module).
- New prelude functions (based on the Haskell prelude): id,
const, min, max, filter, foldl1,
foldr1, minimum, maximum, index,
elem, range, array_filter, array_foldl1,
array_foldr1, array_elem, array_range.
- New prelude constants: false and true.
- Fixed unbounded stack growth during interpretation. Programs can now run
for arbitrary lengths of time.
- Cyclic imports now work properly (previously failed if the top-level
module was involved in an import cycle).
- String literals now have type Array(Int), not Array(a)
- Interactive: Fixed interactively-assigned variables sometimes losing part
of their type, causing them to be usable where they shouldn’t, and also
strange type errors.
- Interactive: Fixed exception associated with assigning an error expression
to a variable, and then reading the variable’s value.
- __impure_array_extend pre-grows the array to the full size, to avoid
- Fixed syntax error messages with special or non-ASCII characters.
- Now fails correctly if given a directory name on the command line.
- Interactive: Added readline support (proper command-line editing and
completion). Mars now depends upon the GNU Readline library.
Released Saturday, 03 Oct 2009
- Renamed impure primitives array_set, array_append and
array_extend to __impure_array_set, etc; these are now
deprecated. Added new module impure which provides the original names
for these functions.
- prelude – Added constant eof with a value of -1.
- Fixed software exceptions on user array bounds errors (now displays proper
Test suite and internal changes
- Fixed testing framework (was broken on compilation testing).
- Test cases – More tests for runtime errors.
- Internal representation – Now uses an instruction-based representation
rather than statement/expression-based. This is visible in the “asm”
- marsc - Removed “python” backend. Added “asm” backend.
- Documentation – Finished Introduction to Mars section. Added
more language features, and removed references to the language Venus.
- Documentation – Renamed “functions” to “procedures” when referring to a
function as defined in source code, and renamed “parameter-less function”
to “computable global constant”.
- Samples – Added sample input to samples/bfs.mar.
Released Wednesday, 07 Jan 2009
- First release of Mars. Includes complete interpreter/compiler and
documentation (though buggy and missing some features).