Programming language for "special forces" of developers.
Nemerle is a general-purpose, multi-paradigm programming language for the .Net platform. It is as easy to learn and use as C# or VB.NET but Nemerle is by far more powerful. 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 metaprogramming is based on macros bearing some similarity to Lisp.
General information
Supported paradigms: Object-Oriented Programming (OOP), Functional Programming (FP), Metaprogramming (MP), Component-Oriented Programming (COP), DSL-Oriented Programming (DOP) or Language Oriented Programming (LOP).
Type system: static typing, strong typing, inferred, nominal.
Influenced by: C# (OOP & Imperative support), ML (FP support), Lisp (macros support).
Supported Platforms: CLI (.Net & Mono).
Key features
Type inference
Nemerle can infer type from initialization and from usage:
def dict = Dictionary(); // Dude, where are my type params?
dict.Add("key", 42); // The type params infered from usage!
def theType = dict.GetType();
WriteLine(theType);
def expected = typeof(Dictionary[string, int]);
Trace.Assert(theType.Equals(expected));
Metaprogramming
Flexible and very powerful metaprogramming subsystem using the Nemerle macros:
def title = "Programming language authors";
def authors = ["Anders Hejlsberg", "Simon Peyton-Jones"];
// 'xml' - macro from Nemerle.Xml.Macro library which alows to inline XML literals into the nemerle-code
def html = xml <#
<html>
<head>
<title>$title</title>
</head>
<body>
<ul $when(authors.Any())>
<li $foreach(author in authors)>$author</li>
</ul>
</body>
</html>
#>
Trace.Assert(html.GetType().Equals(typeof(XElement)));
WriteLine(html.GetType());
Object-oriented programming
Full support for OOP that will be familiar to C# / Java / C++ programmers:
module Program
{
class Initializer
{
public Name : string { get; set; }
public event HelloHandler : Action[string];
public SayHello() : void
{
HelloHandler?.Invoke($"Hello, $Name!");
}
public static Test() : void
{
def hellower = Initializer() <-
{
Name = "David Hilbert";
HelloHandler += Console.WriteLine;
};
hellower.SayHello();
}
}
Main() : void
{
Initializer.Test();
}
}
Functional programming
Full support for functional programming inherited from the ML family of languages (ML, OCaml, F#, Haskell) and can solve problems not only quick and easy but also very beautiful.
- higher-order functions;
- local functions;
- lambdas;
- tail-call elimination optimization;
- pattern matching;
- algebraic types;
- tuples and anonymous types;
- partial application of functions.
def factorial(n, acc)
{
| (0, _)
| (1, _) => acc
| _ => factorial(n - 1, n * acc)
}
def partedFactorial = factorial(_, 1);
Console.WriteLine(partedFactorial(5));
IDE support
The presence of integration with Visual Studio allows reducing the threshold of entry. Current Nemerle Studio IDE integration supports all language features including information about derived types and macro expansion. [Screenshot]
Macro Libraries
Macros allow you to raise the level of the program to unprecedented heights without sacrificing the richness of the language’s syntax as in Lisp. You can develop macros which simplify a solution of your every day tasks. One of the Nemerle paradigms is the Language-Oriented Programming (LOP). It’s a new approach of software development. The LOP allows you to create your own domain specific language (DSL) to solve the problem by describing it in completely declarative manner. Macros allow you to implement and maintain DSL. Macros allow getting automatic support for IDE much faster and easier. Using macros you get high speed of the generated code, etc.
The standard distribution of Nemerle’s compiler includes a lot of ready-to-use macros which can be easily extended by third-party developers. The following outstanding solutions were implemented with the help of Nemerle’s macros:
Nemerle.Peg
Implements a generator of parsers based on the PEG notation. It has notable advantages:
- ease of use (using of Nemerle.Peg is as easy as using of regular expressions);
- an incredibly high speed of work of produced parser — ~ 4 MB / sec. on the grammar of C # 4.0 (with the construction of AST);
- dynamic extensibility (rules of grammar may be included on the fly);
- support for left recursion and associativity (through intellectual memoization and integration of Pratt’s algorithm);
- support for syntactic predicates (allows you to easily parse C#\C++ style languages);
- “Scope” support (allows you to parse a number of context-sensitive languages like C\C++\Nemerle);
- separation of grammar and semantic actions;
- IntelliSense (IDE) support (real-time error reporting, navigation).
Nemerle 2.0 macros system will be based on Nemerle.Peg.
Nemerle.Xml (XML-literals)
Allows using of XML quasi-quotes inside Nemerle-code (XML-literals allow active areas and control structures). This feature is analogous to that in languages like Scala and VB.NET but is available as a separate module (macro) or source code. XML-literals support inline operators: foreach, when and unless.
Computation Expressions
Gives similar possibility of F# language (Computation Expressions). Such beautiful syntactic sugar (on monads) greatly simplifies the creation of features like “comp async” (parallelization of code execution ) or “comp enumerable” (generating a sequence inside a expression).
Nemerle on Rails
Library of Nemerle’s macros on Rails (NoR) is analog of Ruby on Rails but in a statically typed language. The world of statically typed languages has the same framework (Scala’s Lift). But the implementation for Nemerle is based on macros and recognized standards such as LINQ.
As well as…
…many small macros that make the code shorter and clearer: Late (late binding), Lazy (deferred execution), Logging, Profiling, Record (automatic creation of constructors which initialize the fields), Surroundwith (fast creation of operators similar to "using") as well as:
- Splice-strings. Ruby style "active" strings that were implemented using macros.
- LINQ support - this feature is also implemented using macros.
- Extended operators: Groovy's “safe navigation operator” – “?.”, Swap operator – “<->”, ....
- Macro that allows you to walk through a complex data structures. It’s similar to using a visitor pattern but without the manual work.
- Macros which automate the implementation of OOP design patterns: Abstract factory pattern, Aggregation (Composite), Proxy, Singleton.
- DependencyProperty – easily helps to implement WPF’s properties.
- AOP – the support of aspect-oriented programming.