Nemerle's most notable feature is the ability to mix styles of programming that are object-oriented and functional. Programs may be structured using object-oriented concepts such as classes and namespaces, while methods can be written in a functional style. Other notable features include:
def x = 1; // int def myList = List; // generic List, type T is deduced from the usage in the next line myList.Add; // compiler deduces type of T as int making myList type of List
Everything is an expression
def x = ; def x = if // if, using, try are also expressions "Monday" else "other day"; def x = try int.Parse catch ; def x = returnBlock : ;
Tuples
def k = ; // k : def = k; // a = 1, b = "one"
Pattern matching
def result = match
Functional types and local functions
using System.Console; // classes and modules can be put in namespaces def next ; // the type of x argument and other function arguments can be deduced from usage def mult ; def fibonacci WriteLine; // 10 similar to "Console.WriteLine;" WriteLine; // 4 WriteLine; // 55
Variants
are forms of expressing data of several different kinds: variant RgbColor
Metaprogramming
Nemerle's macro system allows for creating, analysing, and modifying program code during compiling. Macros can be used in the form of a method call or as a new language construct. Many constructs within the language are implemented using macros. "if" macro example: macro @if syntax ", e1, Optional // using this macro in code: def max = if a else b; // during a compile time the upper line will be transformed to this: def max = match
The traditional Hello World! can be implemented in a more C#-like fashion: class Hello
or more simply: System.Console.WriteLine;
Examples of macros
Macros allow generating boilerplate code with added static checks performed by the compiler. They reduce the amount of code that must be written by hand, make code generation safer, and allow programs to generate code with compiler checks, while keeping source code relatively small and readable.
String formatting
The string formatting macro simplifies variables to string manipulations using $ notation: def s = $"The number is $i"; //insert the value of the variable i where $i is placed def s = $"$x + $y = $"; // $ can be used to make calculations or access members
Declarative code generation
StructuralEquality, Memoize, json, and with are macros which generate code in compile time. Though some of them can look like C# attributes, during compiling, they will be examined by the compiler and transformed to appropriate code using logic predefined by their macros. // Implement IEquatable.Net interface using by element comparison equality. class Sample
Database accessibility
Using Nemerle macros for SQL you can write: ExecuteReaderLoop;
instead of string sql = "SELECT firstname, lastname FROM employee WHERE firstname = :a"; using
and this is not just hiding some operations in a library, but additional work performed by the compiler to understand the query string, the variables used there, and the columns returned from the database. The ExecuteReaderLoop macro will generate code roughly equivalent to what you would have to type manually. Moreover, it connects to the database at compilation time to check that your SQL query really makes sense.
New language constructs
With Nemerle macros you can also introduce some new syntax into the language: macro ReverseFor syntax defines a macro introducing the ford EXPR syntax and can be used like ford print ;
Nemerle with ASP.NET
Nemerle can be either embedded directly into ASP.NET: <%@ Page Language="Nemerle" %>
...Or stored in a separate file and entered with a single line: <%@ Page Language="Nemerle" Src="test.n" Inherits="Test" %>
PInvoke
Nemerle can take advantage of native platform libraries. The syntax is very similar to C#'s and other.NET languages. Here is the simplest example: using System; using System.Runtime.InteropServices; class PlatformInvokeTest