Est. 2003 Intermediate

Nemerle

Nemerle is the statically typed, C#-flavoured hybrid language for .NET and Mono that three master's students at the University of Wrocław started in 2003 - ML-style variants, pattern matching and type inference wrapped in familiar curly-brace syntax, plus a Lisp-inspired, hygienic, syntax-extending macro system that lets library code teach the compiler new statements

Created by Michał Moskal (project coordinator and compiler author), Kamil Skalski (macro system) and Paweł Olszta (compiler developer), master's students at the Institute of Computer Science, University of Wrocław, Poland, supervised by Prof. Leszek Pacholski, the institute's director; from about 2006 development passed to Vlad Chistiakov (VladD2) and the Russian Software Development Network (RSDN) community, whose core members were hired by JetBrains in June 2012

Paradigm Multi-paradigm: functional (variants, pattern matching, first-class local functions, type inference), object-oriented and imperative in the C# mould, with compile-time metaprogramming (hygienic macros, syntax extensions, code quotations) that makes most control-flow constructs library macros
Typing Static, strong, nominal; type inference for local variables, local functions and generic arguments, with a deferral-based inference algorithm that can infer types from later usage
First Appeared 2003 (development at Wrocław; the oldest surviving revision in the project repository is a 25 September 2003 import from an earlier Subversion server named 'roke'); the first public release, Nemerle 0.1.0, followed on 17 February 2004
Latest Version Nemerle 1.2.547.0 (1 September 2017, the last build listed on nemerle.org; also published to NuGet as Nemerle 1.2.547 on 11 December 2017). The last substantive commits to the rsdn/nemerle repository date from June 2020

Nemerle is a general-purpose, statically typed programming language for the Common Language Infrastructure - Microsoft .NET and Mono - that began in 2003 as a student project at the University of Wrocław in Poland. Its pitch was simple and, for its time, unusual: take the object model and curly-brace syntax that C# programmers already knew, add the things ML programmers missed most (variants, pattern matching, type inference, first-class local functions), and then go one step further than either camp with a Lisp-style macro system that runs inside the compiler and can extend the language’s own syntax. The 2004 release announcement described it as “a new hybrid (functional, object-oriented and imperative) programming language for the .NET platform”, and the official site later summed up the strategy as “one may start using it as an advanced C# and then, as learning goes on, employ a range of cool features enabling metaprogramming and functional programming.”

The language is named after Nemmerle, the Archmage of Roke in Ursula K. Le Guin’s A Wizard of Earthsea; the single m was a deliberate choice, and the team’s original Subversion server was called roke. Nemerle went through three lives: the Wrocław years (2003-2008), when Michał Moskal, Kamil Skalski and Paweł Olszta designed it and wrote the papers and theses that describe it; the RSDN years (roughly 2006-2012), when Vlad Chistiakov and the Russian Software Development Network community took it to 1.0 with Visual Studio integration; and the JetBrains years (2012-2017), when its core developers were hired to build the Nitra language-tooling framework in Nemerle. Development has been dormant since about 2020, but the compiler, its macro library and nearly a decade of documentation remain available on GitHub.

History and origins

A student project at Wrocław (2003-2005)

Nemerle was born in the Institute of Computer Science at the University of Wrocław. Its authors were three master’s students: Michał Moskal, who coordinated the project and wrote most of the compiler; Kamil Skalski, “responsible for the macro system design and implementation”; and Paweł Olszta, a compiler developer with industry experience including an internship at Microsoft in Redmond. Professor Leszek Pacholski, the institute’s director from 1996 to 2005 (and the university’s rector from 2005 to 2008), lent the project his name and supervision, and Marcin Młotkowski and Tomasz Wierzbicki of the faculty are listed alongside them in the team’s response to Microsoft’s second Rotor (Shared Source CLI) request for proposals, a document that survives in the project repository and describes “a bootstrapping Nemerle compiler featuring an almost complete CLS integration and a meta-programming system, making Nemerle probably the first .NET language supporting powerful statically typed macros.”

The earliest surviving code is a 25 September 2003 import into a fresh Subversion repository from the older roke server, and the commits of the following days show a language still very much in its ML phase: let (?x, ?y) = foo in bar, apostrophes in identifiers, “true multi-argument functions” being added for the first time. The team’s own 2005 report to the Rotor workshop is candid about the trajectory: “Back when the project started two years ago we had a far more ML-like language than we have today. After a year of extensions, semantic and syntactic changes we ended up creating something that could be called Extended C# with better functional programming support.”

The first public release, Nemerle 0.1.0, appeared on 17 February 2004. The announcement email promised “simplicity, C#-like syntax, .NET integration, an easy to use object system (derived directly from the .NET), easy access to both functional and imperative features, powerful code-generating macros, variants, pattern matching, static and on-demand dynamic typing, type inference”, and noted that the compiler, “written in Nemerle itself”, had been tested on .NET Framework 1.1 under Windows XP and on Mono 0.29 and 0.30 under Debian, Mandrake and PLD Linux. Source was released “under a BSD-like license” - the University of Wrocław’s three-clause BSD variant that still heads the repository’s COPYRIGHT file - with RPM, DEB and MSI packages.

Releases came quickly through 2004 and 2005: 0.1.2 (28 April 2004) made macros hygienic and moved them into namespaces; 0.2.0 (12 September 2004) and 0.3.0 (29 April 2005) reworked the syntax toward C#; 0.9.0 (13 September 2005) signalled that the design had settled. On 2 June 2004 the three authors presented Nemerle at the Second International Workshop on .NET Technologies in Plzeň, and their paper “Meta-programming in Nemerle” (Skalski, Moskal and Olszta, 2004) became the standard citation for the macro system, and Nemerle is sometimes described in later metaprogramming literature as the first statically typed, object-oriented language in the Java/C# vein with hygienic, syntax-extending macros. The two signature subsystems were each written up as a master’s thesis in 2005: Moskal’s Type Inference with Deferral (submitted 27 June 2005) and Skalski’s Syntax-extending and type-reflecting macros in an object-oriented language.

Adoption, packaging and the RSDN takeover (2006-2011)

By 2006 Nemerle had a modest but real following. Sebastian Dröge packaged 0.9.2 for Debian (accepted 17 March 2006), which put ncc and the nemish interpreter into Debian testing and Ubuntu; the Mono project listed Nemerle among the languages targeting its runtime; and InfoQ ran a profile (David Totzke, 7 June 2006) that singled out the SQL macros, which connect to a database at compile time to validate a query’s syntax and types. Nemerle 0.9.3 shipped on 15 May 2006 and 0.9.4 on 22 February 2008. Moskal, meanwhile, used the language for his Fx7 SMT solver, which placed second in the AUFLIA division of SMT-COMP 2007.

The original authors were graduating and moving on - Moskal to Microsoft Research, Skalski eventually to Google - and the centre of gravity shifted east. Vlad Chistiakov, known everywhere in the project as VladD2, of the Russian Software Development Network (RSDN) had started committing in 2006, and by 2008 he and other RSDN members (Igor Tkachev, Dmitry Ivankov, Pavel Bludov, Stanislav Matveev) accounted for most of the activity. On 7 September 2009 Skalski moved the repository to Google Code and told the mailing list to send write-access requests to VladD2, “who is also added as owner of the project” - the formal hand-over.

RSDN’s priorities were pragmatic: Visual Studio integration, a stable 1.0 and a richer macro library. The 1.0 cycle ran from Beta 1 on 12 March 2010 through a series of release candidates, adding LINQ macros, computation expressions, XML literals, a C# parser (so C# files could be compiled as part of a Nemerle project) and the PegGrammar macro, a PEG parser generator that first appears in the repository in March 2010, ships in the October 2010 Beta 2 and would become the seed of Nitra (N2, its direct ancestor, was started in May 2011). Nemerle 1.0 was announced on 17 May 2011, bundling the compiler, Visual Studio 2008 integration and the standalone Nemerle Express Edition IDE. The project moved to GitHub as rsdn/nemerle in July 2011, and 1.1 reached beta that October. Debian, whose package had been stuck at 0.9.3 since 2006, removed it in September 2011.

JetBrains, Nitra and the long tail (2012-2020)

On 27 June 2012 JetBrains’ Hadi Hariri announced that “the core developers behind a project called Nemerle” had joined the company. Their job was N2, “a language framework that’s primary goal is to make the development of languages and tools as easy and simple as possible”, and Nemerle itself was brought “under the JetBrains umbrella” to guarantee N2’s viability. N2 was renamed Nitra, introduced publicly in November 2013 and open-sourced on 27 May 2014 under what the announcement called the Simplified BSD licence (the repository’s licence file is the three-clause variant); it was written in Nemerle, and the JetBrains blog noted that “Nitra is built by the Nemerle team, in Nemerle, so requires Nemerle in order to compile”.

Nemerle kept moving under JetBrains’ patronage - v1.2 was tagged on 29 May 2013 and a stream of 1.2.x builds ran through 2015-2017, published on nemerle.org and, from September 2015, on NuGet - but the commit graph tells the story: about 1,000 commits a year in 2010-2011, 285 in 2013, 73 in 2015, 32 in 2017. Nitra’s last commit landed on 24 July 2017 and JetBrains never shipped a product on it. Build 1.2.547.0 (1 September 2017) is the last release on the official download page. VladD2 continued fixing the Visual Studio 2017 extension and build scripts into June 2020; since then the repository has received only a security-policy file (March 2025) and a typo fix (June 2026). The website, still maintained by the RSDN team, carries a 2013 copyright.

Design philosophy

The Rotor workshop report sets out the reasoning. Functional languages, the authors argued, had always been starved of libraries; building on .NET made “a large variety of libraries for performing everyday programming tasks immediately available”. But ports of existing functional languages carried backward-compatibility baggage that made the .NET side awkward. A new language designed “for the .NET since the very beginning” could let a programmer “design an application or a library at the high level using the familiar model known from C# but implement the method bodies in a functional style”, and the result would be usable from any other .NET language “without any additional effort”. Crucially, “Nemerle doesn’t force the programmer to use functional paradigm… User can even choose to ignore functional features and program as he would in C#, with minor syntactic differences.”

Three principles follow from this and run through every version:

  • Be a full CLS consumer and producer. Classes, interfaces, properties, events, delegates, generics, attributes and P/Invoke all work exactly as in C#, so Nemerle assemblies are ordinary .NET assemblies and can be referenced from C# or VB.NET.
  • Keep the core small and push everything else into macros. if, when, unless, while, for, foreach, &&, ||, printf, using, lock, yield, LINQ query syntax and even the $"..." string interpolation are macros that ship in the standard macro library. As the official tutorial puts it, “Most of the operators in the language are macros written in the language itself. The base language is quite compact.”
  • Infer what can be inferred, but stay nominal and static. Local variables, local function signatures and generic type arguments are inferred - including, unusually, from later uses of a value - while class members keep explicit signatures so that the assembly’s public surface is always fully typed.

Key features

C#-shaped syntax with functional defaults

using System.Console;

WriteLine("Hello world")

A file can be a bare sequence of statements; more commonly it is a module (a static class) or class. Type annotations come after the name, name : type, and functions omit return because the last expression is the value:

def fahrenheitToCelsius(fahrenheit : int) : double
{
  (5.0 / 9) * (fahrenheit - 32)
}

def binds an immutable value or a local function; mutable declares a variable that may be reassigned. Semicolons are separators, not terminators, and a #pragma indent directive at the top of a file switches on a Python-style off-side rule that replaces braces with indentation.

Type inference

Locals and generic arguments are inferred, and Moskal’s deferral algorithm lets the compiler leave a type undetermined until a later expression pins it down. The official site’s example is a Dictionary whose type parameters are settled by the first Add:

def dict = Dictionary();      // type parameters not yet known
dict.Add("key", 42);          // now inferred as Dictionary[string, int]

Generic type arguments are written with square brackets (list[int], Dictionary[string, int], array[double]) rather than angle brackets, which keeps the parser simple.

Variants and pattern matching

Variants are algebraic data types that compile to a class hierarchy - each option is a nested class, so they are visible to other .NET languages - and match destructures them with the | pattern => expression syntax that Nemerle also uses for try/catch cases:

using System.Console;

variant Shape
{
  | Circle    { radius : double }
  | Rectangle { width : double; height : double }
  | Point
}

def area(shape : Shape) : double
{
  match (shape)
  {
    | Circle(r)       => System.Math.PI * r * r
    | Rectangle(w, h) => w * h
    | Point           => 0.0
  }
}

foreach (s in [Shape.Circle(1.0), Shape.Rectangle(2.0, 3.0), Shape.Point()])
  WriteLine($"$(area(s))");

Patterns can match literals, tuples, lists (x :: rest), variant options with positional or named fields, types (| x is string), and carry when guards; the compiler warns about incomplete or redundant matches. option[T] and immutable list[T] come from the standard library, and list comprehensions such as $[ x | x in [1 .. 12] ] and the pipeline operator |> round out the functional toolkit.

Macros: the compiler as a library

Nemerle’s defining feature is a macro system in which macros are ordinary Nemerle code, compiled into a separate assembly and loaded by the compiler, that receive syntax trees and return syntax trees. Quotations <[ ... ]> build trees; $ splices values in. The official tutorial’s example defines short-circuit &&:

macro @&& (e1, e2)
{
  <[
    match ($e1)
    {
      | true  => $e2
      | false => false
    }
  ]>
}

A macro can also declare a syntax clause that adds new keywords to the parser. The real when from the standard macro library is a one-liner of that kind (simplified here from macros/core.n):

macro whenmacro (cond, body)
syntax ("when", "(", cond, ")", body)
{
  <[ if ($cond) $body else () ]>
}

Because macros run inside the compiler they can consult the type checker (Skalski’s “type-reflecting” macros), generate class members (macro attributes such as [Record], [Memoize], [StructuralEquality] and [Accessor]), or do arbitrary work at build time: the sql macro in the 2004-2006 releases opened a database connection during compilation to validate a query, and the later xml macro embedded XML literals with $foreach and $when directives. The PegGrammar macro turns a parsing-expression grammar written inside an attribute into a complete parser class, and was the basis of Nemerle’s own C# parser. Hygiene - each macro expansion gets its own namespace for generated identifiers, so macro-introduced names cannot capture user variables - has been in place since 0.1.2 in April 2004.

Everything else from .NET

Classes, structs, interfaces, enums, properties (including auto-properties), events, indexers, operator overloading, delegates, generics with constraints and variance, custom attributes, yield-based iterators, LINQ (via macros), P/Invoke and unsafe-free interop all work as a C# programmer expects. Tuples ((1, "a")) and anonymous types are built in, and the Nemerle.Linq library can compile lambdas to expression trees.

Evolution

PeriodVersionsCharacter
2003-2004pre-release, 0.1.x, 0.2.xML-flavoured syntax giving way to C# style; hygienic macros arrive in 0.1.2
2005-20080.3.x, 0.9.0-0.9.4Design settles (“Extended C# with better functional programming support”); Debian packaging; Fx7
2009-20111.0 betas and RCs, 1.0 (17 May 2011), 1.1 betaRSDN stewardship; Visual Studio integration, LINQ, computation expressions, PegGrammar, C# source support
2012-20171.2 (tagged May 2013) through 1.2.547.0 (1 Sep 2017)JetBrains era; .NET 4.x and Visual Studio 2010-2017 builds; NuGet packages; Nitra written in Nemerle
2018-2026noneMaintenance commits only until June 2020, then dormancy

The most consequential change across these years was the audience. The Wrocław team wrote papers and theses and shipped tarballs for Mono; RSDN wrote a Windows installer, a Visual Studio plug-in and Russian-language tutorials, and turned the macro system toward practical code generation (ORM-style persistence, state machines, parsers). JetBrains, finally, treated Nemerle less as a product than as the implementation language for Nitra.

Current relevance

Nemerle is dormant. The last official build is from September 2017, the last meaningful commits from June 2020, and neither the website nor the compiler has been updated for .NET Core or modern .NET; the README still documents builds for .NET 3.5 through 4.5.1 and Mono xbuild. Nitra, the project that was supposed to secure its future, is an archived GitHub repository. The two Docker images on Docker Hub date from 2015 and 2018.

What survives is substantial nonetheless: a 10,000-commit repository with a self-hosting compiler, a standard library and macro library, a Visual Studio extension, hundreds of test cases, and the RSDN wiki’s multi-part tutorial in English and Russian. Nemerle still appears on the Baekjoon Online Judge’s list of accepted languages. And its people went on to notable things - Moskal to seventeen years at Microsoft Research (VCC, TouchDevelop, MakeCode) and then OpenAI, Skalski to Google, the RSDN team to JetBrains - which is why Nemerle turns up in the acknowledgements and bibliographies of a good deal of later language-tooling work.

Why it matters

Nemerle’s historical claim is that it was, as its authors put it in 2004, “probably the first .NET language supporting powerful statically typed macros” - and more broadly one of the first languages to combine a mainstream, curly-brace, nominally typed object model with hygienic, syntax-extending, type-aware compile-time metaprogramming. The Lisp world had macros, but not static types or a C#-style object system; MetaML and Template Haskell had typed staging, but not C# syntax or .NET interop; C# and Java had neither. Nemerle showed that a language could ship its own if and foreach as library code, validate SQL at compile time, and generate parsers from grammars in attributes, all while remaining an ordinary citizen of a commercial runtime. The ideas that Scala macros, Rust procedural macros and the various C# source-generator schemes later made commonplace were being demonstrated in Wrocław in 2004.

It also matters as an early, serious attempt at the ML-on-.NET hybrid that F# would go on to make mainstream from 2005 onward. Nemerle chose to look like C# where F# chose to look like OCaml, and in the long run Microsoft’s backing decided the contest; but the variant-plus-match idiom that Nemerle put in front of .NET programmers in 2004 is the same one that C# itself has been absorbing, piece by piece, since pattern matching arrived in C# 7.

Finally, Nemerle is a case study in how small-language projects live and die: a university team that produced excellent papers but graduated; a volunteer community that added the tooling users actually wanted; a corporate sponsor whose interest was in a by-product; and a compiler that, in the end, outlived all three sets of maintainers and still compiles.

Further reading

  • rsdn/nemerle on GitHub - the main repository, including the NEWS file, the doc/presentation directory of early papers and slides, and the wiki tutorial
  • nemerle.org - the official site, with the About page, downloads and build history (HTTP only)
  • Kamil Skalski, Michał Moskal and Paweł Olszta, “Meta-programming in Nemerle” (2004)
  • Michał Moskal, Type Inference with Deferral, MSc thesis, University of Wrocław, 2005
  • JetBrains blog: “JetBrains and Nemerle” (27 June 2012) and “Nitra goes Open Source!” (27 May 2014)
  • JetBrains/Nitra on GitHub - the archived framework written in Nemerle

Timeline

2003
Michał Moskal, Kamil Skalski and Paweł Olszta begin Nemerle at the University of Wrocław under Prof. Leszek Pacholski; the oldest surviving revision is a 25 September 2003 import from a Subversion server called 'roke', and early commits still use ML-style 'let ... in' syntax
2004
Nemerle 0.1.0, the first public release, ships on 17 February under a BSD-style licence with a self-hosting compiler tested on .NET Framework 1.1 and Mono 0.29/0.30; 0.1.2 (28 April) makes macros hygienic; the team presents the language at the Second International Workshop on .NET Technologies in Plzeň on 2 June and circulates the paper 'Meta-programming in Nemerle'; 0.2.0 follows on 12 September
2005
0.3.0 (29 April) and 0.9.0 (13 September) mark the shift from an ML-like language to what the team's Rotor workshop report calls 'Extended C# with better functional programming support'; Moskal's MSc thesis 'Type Inference with Deferral' (submitted 27 June) and Skalski's thesis on syntax-extending, type-reflecting macros document the two signature subsystems
2006
Sebastian Dröge packages Nemerle 0.9.2 for Debian (accepted 17 March), and 0.9.3 ships on 15 May; InfoQ profiles the language in June; Vlad Chistiakov (VladD2) of the Russian Software Development Network becomes a major committer, the start of the RSDN era
2007
Moskal's Fx7 SMT solver, written in Nemerle apart from a C# port of MiniSat, places second in the AUFLIA division of SMT-COMP 2007 - the language's most visible use in research software
2008
Nemerle 0.9.4 (22 February) is the last release of the Wrocław-era 0.9 line; by now most commits come from RSDN contributors rather than the original authors
2009
Kamil Skalski moves the Subversion repository to Google Code on 7 September and hands write access to VladD2, formally passing stewardship to RSDN
2010
1.0 Beta 1 (12 March) opens a long release-candidate cycle with Visual Studio 2008/2010 integration, LINQ macros and computation expressions; the PegGrammar macro, a PEG parser generator, ships in the October Beta 2 (work on it in the repository dates from March)
2011
Nemerle 1.0 is released on 17 May with the ncc compiler, Visual Studio 2008 integration, the Nemerle Express Edition IDE and support for mixing C# 4.0 source files into projects; the rsdn/nemerle GitHub repository is created on 7 July; 1.1 beta is tagged in October; Debian removes the long-stale 0.9.3 package on 23 September
2012
JetBrains announces on 27 June that it has hired the core Nemerle developers to build N2 - later Nitra - a language-tooling framework, and brings Nemerle 'under the JetBrains umbrella' to guarantee N2's viability
2013
v1.2 is tagged on 29 May and the final 1.1 build (1.1.1119.0) appears on 5 June; JetBrains introduces Nitra publicly on 12 November
2014
Nitra, written in Nemerle, is open-sourced on 27 May under a BSD licence (announced as Simplified BSD; the repository's licence file is three-clause) at github.com/JetBrains/Nitra
2017
Build 1.2.547.0 (1 September) becomes the last release listed on nemerle.org, published to NuGet on 11 December; the Nitra repository receives its final commit on 24 July as JetBrains apparently winds the project down
2020
VladD2 makes the last substantive commits to rsdn/nemerle in June (build-script fixes and Visual Studio 2017 extension work); only a SECURITY.md (March 2025) and a typo fix (June 2026) follow

Notable Uses & Legacy

JetBrains Nitra

The language-tooling framework that the Nemerle team developed at JetBrains after being hired in June 2012 (its ancestor, N2, had been started inside the RSDN Nemerle project in May 2011, growing out of the PegGrammar parser generator). Nitra compiles grammar definitions into parsers and AST classes intended to give any language syntax highlighting, folding, navigation and refactoring; it is written in Nemerle (the GitHub repository is classified as such, with over a thousand .n source files), was open-sourced under a BSD licence in May 2014 - announced as 'Simplified BSD', although the repository's licence file is the three-clause form - and received its last commit in July 2017

Fx7 SMT solver

Michał Moskal's satisfiability-modulo-theories prover, developed at Wrocław for software-verification queries heavy in quantifiers. Fx7 was written in Nemerle apart from a C# port of the MiniSat SAT solver, introduced new E-matching algorithms (SMT Workshop 2007) and finished second in the AUFLIA division of SMT-COMP 2007

The Nemerle compiler (ncc) and standard macro library

Nemerle has been self-hosting since its first public release in February 2004: ncc is written in Nemerle and bootstraps from binaries kept in the repository's boot/ directory. Almost all of the language's control flow - if, when, unless, while, for, foreach, the short-circuit operators, printf-style I/O - is implemented as ordinary macros in the macros/ library rather than in the compiler proper

Baekjoon Online Judge

The Korean competitive-programming site acmicpc.net lists Nemerle among the languages it accepts for submissions, and maintains a dedicated grading image, baekjoon/onlinejudge-nemerle (tag 1.2, August 2015), on Docker Hub - probably one of the few places where Nemerle programs are still being compiled and run at scale (the image has not been updated since 2015, so which compiler build the judge currently uses is unclear)

Debian and Ubuntu

Sebastian Dröge packaged Nemerle 0.9.2 and 0.9.3 for Debian between March 2006 and March 2009, making ncc and the Nemish interpreter an apt-get install on Debian and Ubuntu; the package fell behind the RSDN-era releases and was removed from Debian unstable in September 2011

Language Influence

Influenced By

Running Today

Run examples using the official Docker image:

docker pull splessons/nemerle:1.2

Example usage:

docker run --rm -it -v $(pwd):/app -w /app splessons/nemerle:1.2 # community image, untested; inside: ncc hello.n -out:hello.exe && mono hello.exe
Last updated: