Skip to content
Alex Zimin edited this page Aug 19, 2011 · 8 revisions

This is a small guide to nearly all Nemerle features, specially for people coming from C#:

Table of Contents

Variables

  • mutable a = 5;: mutable variables can be changed later
  • def b = 4;: normal variables cannot be changed
In all variables, type inference works
  • def c : float = 4;: a type annotation

Lists

  • def nil = [];: the empty list is []
  • def numbers = [1, 2, 3];: generate a list with those values
  • def more_numbers = 4 :: numbers; : :: adds a new item to the list

List comprehensions

  • $[ (x, y) | x in list1, y in list2, x < y]: get all pairs on the lists for which the condition is true.
  • $[1, 3 .. 8]: range from 1 to 8 step 2 (3-1)
  • $[1 .. 5]: range from 1 to 5 step 1
  • $[ (x, y) | x in [1 .. 3], y in [2, 4 .. 10] ]: generate all pairs
more...

Useful methods on lists

  • Length, Head, Tail, Last, Nth
  • FirstN: return first N elements of the list
  • ChopFirstN: return the list without the first N elements
  • LastN: return the last N elements
  • Reverse
  • Remove: removes an element
  • Contains
  • Iter (f : 'a -> void): executes the function in all elements
  • Map (f : 'a -> 'b): returns a new list['b], executing the function in all elements of the list['a]
  • Group (f : 'a * 'a -> int): return a list of lists, grouping the elements whose function returns the same value
  • FoldLeft, FoldRight: returns a result of executing the function recursively on the list, with a first element, in normal or reverse order
  • ForAll (f : 'a -> bool): returns true if all elements return true
  • Exists (f : 'a -> bool): returns true if at least one application of the function in the elements returns true
  • Find (pred : 'a -> bool): finds the first element whose predicate is true
  • Filter (pred : 'a -> bool): returns a new list containing all elements whose predicate is true
  • Sort (cmp : 'a * 'a -> int): sorts the list based on the method. The reason underlying the fact that the function returns an int is that CompareTo functions in .NET return an int
  • RemoveDuplicates
  • ToArray
Most of the BCL collection types have extended counterparts in Nemerle library, that add methods such as Iter, Map or Fold, for example, Hashtable (that extends Dictionary) or LinkedList.

Arrays

  • def a = array(3);: specifies the number of elements
  • def b = array[1, 2, 3]: specifies the elements
You can also specify array type:
def a = array(3) : array[byte];
def b = array[1 : byte, 2, 3];

Tuples

  • def t = (1, "one");: a tuple is a set of values with no name to recognise them
  • def fst = t[0];: use 0-based index to get the items

Nemerle.Utility.Pair

This class contains three methods that work with pairs (tuples of two elements):

  • First and Second retrieve the first or second element of the tuple, respectively
  • Swap exchanges both elements of the pair

Decisions

  • when (condition) code: execute code if condition is true
  • unless (condition) code: execute code if condition is false
  • if (condition) code1 else code2: execute code1 if condition is true, code2 if it is false

Loops

  • for (mutable i = 0; i < 10; i++) code: for loop as of in C
  • foreach (i in $[0..9]) code like the above, using range
  • foreach (i in $[9,8..0]) code reverse order
  • while (condition) code: execute code while condition is true
  • do code while (condition): the same as above, but checks the condition at the end of the code, so it is always run at least once
  • foreach (x in list) code: execute the code for every member x of the enumerable collection list
  • foreach (x when x != null in list) code: like the above but only for not null members
  • repeat (10) code: repeats the code the specified number of times

Exceptions

  • throw ArgumentException();: throws a new exception of the desired type
  • Syntax for try-catch-finally handler resembles the one from C#, although catch handlers use a pattern matching-like syntax:
try {
  code
}
catch {
  | e is ArgumentNullException => ...
  | e is OverflowException => ...
  | e is MyException when e.Reason == Reason.Warn => ...
  | _ => ...
}
finally {
  // Finally code is always executed
  // no matter an exception were thrown or not
}

Variants

  • Create a variant with empty options and options with extra information
variant Volume {
  | Max
  | Min
  | Other { v : int }
}
  • def v1 = Volume.Max ();: an empty constructor is used for empty options
  • def v2 = Volume.Other (5);: the constructor for non-empty elements gets all fields as parameters, in the order they were written in code
  • You need to include [XmlSerializable] on top of the variant to make it serializable via XML

Enums

As in C#, are just a good face for ints:

enum Seasons {
  | Spring
  | Autumn
  | Winter
  | Summer
}

Nullable types

Value-types (structs) cannot be null (that's a platform requirement). However, sometimes you need nullable integers or booleans.

  • def t : int? = 3;: declare a new nullable int with a value
  • def t : int? = null;: declare a new nullable int with null value
  • when (t != null) {...}: boolean expressions are overloaded to check for values on nullable types. This is the same as saying when (t.HasValue) {...}
  • a = b ?? -1;: a gets the wrapped value of b if is isn't null. Otherwise, it gets the value after the two question marks
  • a = b?.P;: Returns P if b is not null, or default(typeof(b.P)) otherwise. Avoids NullReferenceException. The left side of the operator (b) must be a reference type.

Pattern Matching

Literal matching

  • Numbers:
match (value) {
  | 1 => "one"
  | 2 => "two"
  | _ => "more"
}
  • Strings:
match (value) {
  | "one" => 1
  | "two" => 2
  | _ => 0
}
  • Enums:
match (value) {
  | Seasons.Spring
  | Seasons.Summer => "hot"
  | _ => "cold"
}

List matching

match (some_list) {
  | [42, 42] => "two forty-two"
  | [42, _] => "forty-two on first position of two-element list"
  | [_, 42] => "forty-two on second position of two-element list"
  | 42 :: _ => "forty-two on first position"
  | _ :: 42 :: _ => "forty-two on second position"
  | [] => "an empty list!"
  | _ => "another list"
}

Variable pattern

Binds the variable names:

def display (l) {
  match (l) {
    | head :: tail =>
      Write ($ "$head, ");
      display (tail)
    | [] =>
      WriteLine ("end")
  }
}

Tuple pattern

match (tuple) {
  | ( 42, _ ) => "42 on first position"
  | ( _, 42 ) => "42 on second position"
  | ( x, y ) => $"( $x, $y )"
}

Type check

Checks if the value is of given type, binding the new value with the new type

def check (o : object) {
  match (o) {
    | i is int => $"An int: $i"
    | s is string => $"A string: $(s.ToUpper())"
    | _ => "Object of another type"
  }
}

Record pattern

Binds on field or properties

def check_class (c) {
  match (c) {
    | MyClass where (foo = 0) => true
    | _ => false
  }
}
If the type is known to the compiler, the where clause is not needed
def check_class (c) {
  match (c) {
    | (foo = 0) => true
    | _ => false
  }
}

as pattern

Binds a value matched with an identifier

variant Foo {
  | A { x : int; mutable y : string; }
  | B
}
 
match (some_foo ()) {
  | A (3, _) as a =>
    a.y = "three";
  | _ => {}
}

Type hint pattern

Used to explicitly declare types where the compiler cannot infer it

def foo (l) {
  | (s : string) :: _ => s [0]
  | [] => '?'
}

with clause

Used to specify a default value in cases where we need to match both a small and a big structure with the same code.

def foo (_) {
  | [x] with y = 3
  | [x, y] => x * y
  | _ => 42
}

Regular Expressions match

regexp match (str) {
  | "a+.*" => printf ("a\n");
  | @"(?<num : int>\d+)-\w+" => printf ("%d\n", num + 3);
  | "(?<name>(Ala|Kasia))? ma kota" =>
     match (name) {
       | Some (n) => printf ("%s\n", n)
       | None => printf ("noname?\n")
     }
  | _ => printf ("default\n");
}

you must add a reference to Nemerle.Text to use this functionality (using Nemerle.Text)

Yield

  • Works as in C#, used for enumerating sequences:
Range (from : int, to : int) : IEnumerable[int] {
  for (mutable i = from; i <= to; i++)
    yield i;
}

Imperative programming and Blocks

To use return, break and continue we need to open the Nemerle.Imperative namespace:

  • return x;: cuts the execution of the function, method or property, stablishing x as the return value
  • continue;: on a loop, continues with the next iteration
  • break;: on a loop, cuts the execution of the loop and continues with the following code
Blocks are a set of instructions, preceded with an identifier and a colon. The result of the block is the last value computed, except if the name of the block is used,along with the return value, to jump out the block.
def x =
  foo: {
    when (some_cond) foo (3); // if some_cond is true, the block will return 
    qux ();
    42 // else it will return 42
  }

more...

Functions

  • Functions can be declared inside methods, and type inference works for them:
public Greet (people : list[string]) : void {
  def say_hello (s) {
    System.Console.WriteLine ($"Hello $s");
  }

  foreach (person in people)
    say_hello (person);
}
  • compute (f : int * int -> int, x : int, y : int) { ... }: functions can be passes as parameters, whose types are divided by * and its return type is told after ->
  • compute ( fun (x, y) { x + y }, 3, 4): anonymous functions can be created inline, just preceding them with fun and its list of parameters
  • compute ( (x, y) => x + y, 3, 4): anonymous functions have multiple forms
  • def addFive = compute (fun (x, y) { x + y }, _, 5): partial application, substitutes one or more parameters, then yielding another function with a smaller set of parameters
  • def addFive = _ + 5;: partial application substituting the parameter with _
  • def name = _.Name;: you can also use this type of partial application to access members
  • lambda x -> Console.WriteLine (x): a easier construct to create a function with just one parameter

String formatting

  • def s = $"The number is $i";: insert the value of the variable i where $i is placed
  • def s = $"$x + $y = $(x+y)";: $(...) can be used to make calculations or access members

print Functions

These functions require opening the Nemerle.IO namespace:

  • print (value), sprint, fprint: substitutes variable names with $ notation in the string and returns it to Console, string or TextReader, respectively
  • printf (value), sprintf, fprintf: as above, but with formatting
  • scanf (format), sscanf, fscanf: returns a string extracted from console, string or TextReader that keeps the specified format

Type conversions

  • def s = n :> int;: cast may fail with an InvalidCastException
  • def s = n : int;: cast cannot fail, only for supertypes

Namespaces

  • namespace NS { ... }: declares a new namespace
  • using System;: open the namespace, that is, makes all members inside it not to requiere full qualifying. It also opens namespace inside it (different with C#)
  • using System.Console;: open the type, making its methods visible
  • using C = System.Console;: create an alias to refer the type or namespace

Classes and Modules

  • class Example { ... }: creates a class Example
  • module Example { ... }: creates a module Example, that is, a class with all members static

Interfaces

Defines a set of public methods an adhering class must implement

interface IExample {
  Method() : void;
}

class Example : IExample {
  public Method () : void { ... }
}

Accessibility

  • public: everyone can access
  • internal: only classes in the current assembly (DLL or EXE) can access
  • private only current type can access
  • protected: access is limited to current type and its derived types
  • protected internal means protected or internal - access limited to derived types or types in the current assembly

Modifiers

  • static: no instance is needed for accessing
  • mutable: if not set for field, they are read-only
  • volatile: only for fields, it means that the field has to be always read from the memory, and written instantly. Useful for multithreaded programs
  • extern: used on methods, along with DllImport attributes to call out to native code
  • partial: only on type definitions, it means that a given type definition is split across several files

Constructors

  • Take this as its name:
class Example {
  mutable Name : string;
  public this (name : string) {
    Name = name;
  }
}
  • def n = Example ("serras");: no new keyword is used to create new objects

Static Constructors

Executed once per type. No parameters.

class Example {
  static public this() { ... }
}

: operator will be used by compiler to automatically convert from one value to another if it is needed, like passing objectRecord] macro]

Generates a constructor which assigns a value to every field:

[Record] class Point {
  public x : int; public y : int;
}
is the same as:
class Point {
  public x : int; public y : int;
  public this (x : int, y : int) {
    this.x = x; this.y = y
  }
}

Inheritance

  • class Human &#58; Mammal &#123; ... &#125;: class Human inherits from Mammal, or implements Mammal interface

Modifiers

  • abstract: the method contains no actual implementation, that must be provided in child classes
  • override: redefinition of a virtual or abstract method
  • virtual: the most derived method will always be called
  • new: allows name redefinition in nested or derived classes
  • sealed: no derivation or redefinition is possible in derived classes

Parameters

  • method (x &#58; int, y &#58; int, z &#58; bool &#61; false) &#123; ... &#125;: default parameters
  • method (i &#58; ref int) &#123; ... &#125;: passes the parameter by reference, that is, changing the actual value
  • method (i &#58; out int) &#123; ... &#125;: specifies an out parameter, used for returning values
  • Values passed as ref or out parameters must be decorated with the ref or out keyword
  • Write (method (3, z &#61; true, y &#61; 1))&#59;: parameter names can be used, after unnamed ones

Properties

public Property : string {
  get { property }
  set { property = value }
}

Property Accessors

  • &#91;Accessor (Sum)&#93; mutable sum &#58; int&#59;: generate a public property with name Sum, getting the value from the field sum, with just a getter
  • &#91;Accessor (Sum, flags&#61;Internal)&#93; mutable sum &#58; int&#59;: change the accessibility
  • &#91;Accessor (Sum, flags&#61;WantSetter)&#93; mutable sum &#58; int&#59;: generate both getter and setter
  • &#91;Accessor&#93; mutable sum_of_sam &#58; int&#59;: property name used, capitalized and underscores removed : SumOfSam
more...

Flag Accessors

For setting individual bits of enumerations fields, making boolean propeties:

[System.Flags] enum States {
  | Working = 0x0001
  | Married = 0x0002
  | Graduate = 0x0004
}

[FlagAccessor (Working, Married, Graduate, flags=WantSetter)]
mutable state : States;

Indexers

class Table {
  public Item [row : int, column : int] {
    get { ... }
    set { ... }
  }
}

Operator Overloading

[Record]
class Vector {
  [Accessor] x : double;
  [Accessor] y : double;
  [Accessor] z : double;

  // + operator
  public static @+ (v1 : Vector, v2 : Vector) : Vector {
    Vector (v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z)
  }
 
  // implicit cast operator
  public static @: (p : Point) : Vector {
    Vector (p.X, p.Y, p.Z)
  }

  // explicit cast operator
  public static @:> (p : double) : Vector {
    Vector (p, 0.0, 0.0)
  }
}

: operator will be used by compiler to automatically convert from one value to another if it is needed, like passing object to method expecting some different type. Cast :> must be explicitly written by user, like def x = A() :> B;

Delegates and Events

  • delegate Foo (_ &#58; int, _ &#58; string) &#58; void&#59;: creates a new delegate type
  • def f1 &#61; Foo (method)&#59;: creates a delegate instance containing a reference to a method or function
  • def f2 &#61; Foo ( fun (i, s) &#123; ... &#125; )&#59;: creates a delegate containing an anonymous function
  • event MyEvent &#58; Foo&#59;: creates an event field of delegate type Foo
  • Foo +&#61; method&#59;: adds a method to the delegate
  • Foo &#45;&#61; method&#59;: remove a method from the delegate
  • Foo (2, &quot;two&quot;)&#59;: invokes a delegate, that is, calls all the methods in it, in the order they were added, passing these parameters

Genericity

  • A generic type:
class Example[T] {
  mutable item : T;
  public foo [Z] () : void { }
}
  • Generic functions, variants and methods use the same syntax
  • def x &#61; Example&#91;int&#93;.foo.&#91;string&#93;()&#59;: for rare cases where generic parameter cannot be inferred

Constraints

  • class Example&#91;&#39;a&#93; where &#39;a &#58; IComparable&#91;&#39;a&#93; &#123; ... &#125;: 'a must implement or inherit the class or interface stated
  • class Example&#91;&#39;a&#93; where &#39;a &#58; class &#123;...&#125;: 'a must be a reference type
  • class Example&#91;&#39;a&#93; where &#39;a &#58; struct &#123;...&#125;: 'a must be a value type
  • class Example&#91;&#39;a&#93; where &#39;a &#58; enum &#123;...&#125;: 'a must be an enumeration type
  • class Example&#91;&#39;a&#93; where &#39;a &#58; new () &#123;...&#125;: 'a must implement a parameterless constructor. That's the only way you can create instances of classes defined by type parameters

Co- and contra-variance

  • class Example&#91;+T&#93; &#123; ... &#125;: makes the argument type covariant, that is, you can assign, to a variable of type Example&#91;T&#93; an instance of Example&#91;U&#93; if U subclasses T (for example, you could assign an instance of Example&#91;string&#93; to an Example&#91;object&#93; variable). Covariant type parameters can only be used as return types.
  • class Example&#91;&#45;T&#93; &#123; ... &#125;: makes the argument type contravariant, that is, you can assign, to a variable of type Example&#91;T&#93; an instance of Example&#91;U&#93; if T subclasses U (for example, you could assign an instance of Example&#91;object&#93; to an Example&#91;string&#93; variable). Contravariant type parameters can only be used as argument types or in generic interfaces.

Extension methods

  • You can declare an extension method by adding this to the first parameter:
namespace ExtensionExample {
  class ExtensionClass {
    public static PlusOne (this i : int) {
      i + 1
    }
  }
}
more...
  • You need to open the namespace to use the extension method as member methods:
using ExtensionExample;

def n = 3;
def m = n.PlusOne (); // that will call the extension method

Design by contract

All types needed are included in the Nemerle.Assertions namespace. By default, if contract is violated a Nemerle.AssertionException is thrown. You can change it by means of otherwise

getfoo (i : int) : int
requires i >= 0 && i < 5 otherwise throw
  System.ArgumentOutOfRangeException ()
{ ... }

Preconditions

  • On a method:
class String 
{
  public Substring (startIdx : int) : string 
  requires startIdx >= 0 && startIdx <= this.Length
  { ... }
}
  • On a parameter:
ConnectTrees (requires (!tree1.Cyclic ()) tree1 : Graph,
              requires (!tree2.Cyclic ()) tree2 : Graph, 
              e : Edge) : Graph 
{ ... }

Postconditions

public Clear () : void
ensures this.IsEmpty
{ ... }

Class invariants

  • Assign class invariants:
class Vector [T]
invariant position >= 0 && position <= arr.Length
{ ... }
  • Use expose to change the invariants
expose (this) {
  x += 3;
  y += 3;
}

more...

Lazy evaluation

  • def l &#61; lazy (MethodWithBigCost ())&#59;: declares a variable whose value will be retrieved only when needed
  • method (&#91;Lazy&#93; x &#58; int, y &#58; int) &#123; ... &#125;: the parameter will only be fetched in rare cases
  • The field Next will only be evaluated when requested, because or its LazyValue type:
class InfList {
  public Val : int;
  public Next : LazyValue [InfList];
 
  public this (v : int) {
    Val = v;
    Next = lazy (InfList (v + 1)); 
  }
}

more...

Late Binding

Late expressions are executed dynamically at runtime, which makes it perfect for uses such as COM. No strict checks are done, so you must take care of calling the correct method on the correct instance and so on.

  • late (expr) or late expr: executes a valid Nemerle expression with late binding.
  • nolate (expr) or nolate expr: allows executing a expression as if it wasn't late in a late binding environment.
  • late obj.Length: the Length property or field is retrieved at runtime, so you could use it over strings, lists, arrays... without worrying of the type. Of course, if the object does not contain a Length member, an exception will be thrown.
  • late o.Name.&#91;1&#93;: calls the default indexer on o.Name. You must be aware that calling o.Name.Chars&#91;1&#93; calls the indexer named Chars on o.Name.
more...

Aliases

Type alias

  • type int &#61; System.Int32&#59;: establishes an alias for the System.Int32 type. int can be used anywhere in code with the exact same meaning as System.Int32.

Alias macro

[Alias (F2, F3 ())]
public static F1 () : int { System.Random ().Next () }
This code generates a F2 property and a F3 method with no arguments:
public F2 : int { get { System.Random.Next () } }
public F3 () : int { System.Random.Next () }

[Alias (Hd, Head2 (), Head3 (l))]
public static Head (l : list ['a]) : 'a { 
  match (l) { ... }
}
Arguments not specified as treated as this. Method arguments must match the ones from the method being aliased, but their order can be changed. The previous code generates:
public Hd : 'a { get { def l = this; match (l) { ... } } }
public Head2 () : int { def l = this; match (l) { ... } }
public static Head3 (l) : int { match (l) { ... } }

Operators

  • a &#61; b&#59;: assignment. In Nemerle, this operator doesn't return a value, so multiple assignments are not allowed
    • Compound assignment is allowed: a +&#61; b&#59;
  • +: number addition, string concatenation
  • &#45;, &#42;, /, %: number substraction, multiplication, division and modulo
  • a &amp;lt&#59;&#45;&amp;gt&#59; b&#59;: swap, exchanges values of a and b
  • ++, &#45;&#45;: adds or substract 1 to the value
  • +, &#45;

Logical Operators

  • &#61;&#61;, &#33;&#61;: equal, not equal
  • x.Equals(y): compare any two objects. x and y may have different types. Types are allowed to provide their own override of the Equals method, by default, it checks by reference in reference types and by value in value types (including enums)
  • &amp;gt&#59;, &amp;lt&#59;, &amp;gt&#59;&#61;, &amp;lt&#59;&#61;: greater than, less than, greater or equal to, less or equal to
  • &amp;&amp;: short-circuiting and
  • &#124;&#124;: short-circuiting or
  • &#33;: not
You can also use and, or, not if you open the Nemerle.English namespace

Bit Operators

  • &amp;, &#124;, ^: bit-level and, or and xor operations
  • %&amp;&amp;, %&#124;&#124;, %^^: bit-level and, or and xor, returning true if the result is non-zero
  • &amp;gt&#59;&amp;gt&#59;, &amp;lt&#59;&amp;lt&#59;: right and left bitwise shift

Checked and unchecked contexts

  • unchecked &#123; ... &#125;: any number operation that goes beyond the limits of the type will silently go into an overflow
  • checked &#123; ... &#125;: operations overflowing will throw a OverflowException

Some things inherited from C#

  • using (resource) &#123; ... &#125;: the resource must implement the IDisposable interface. This block assures the resource is correctly disposed even though an exception is thrown
  • lock (object) &#123; ... &#125;: for multithreaded application. Assures that no other code executes this block if the block object is being used

Logging

All macros are inside the Nemerle.Logging namespace:

  • &#91;assembly&#58; LogFunction (DoLog)&#93;: specifies a logging function
  • &#91;assembly&#58; LogFunction (DEBUG &#61;&gt; log4net_category.Debug, TRACE &#61;&gt; log4net_category.Info)&#93;: specifies different logging functions for different compilation flags
  • log (VERB, &quot;example&quot;, 2): calls the logging function if the compilation flag is set, with those parameters
  • whenlogging (VERB) &#123; code &#125;: executes the code only if the compilation flag is set
  • &#91;assembly&#58; LogFlag (VERB, true)&#93;: sets the compilation flag for VERB to true
  • &#91;assembly&#58; LogCondition (EnableLogging), LogFlag (DEBUG, true)&#93;: add a condition that will be cheked each time the log function is called
  • &#91;assembly&#58; LogFormat (PrependFlag)&#93;: prepend logging flag to each message
more...

Assertions

  • assert (condition, &quot;message&quot;)&#59;: if condition is false, a AssertionException will be thrown, with the actual line and column number in the code file

Profiling macros

  • &#91;assembly&#58; ProfSetup&#93;: add initial setup for profiling
  • &#91;Profile&#93; foo () &#58; int &#123; ...&#125;: tell the profile to include this method
  • &#91;ProfDump&#93; Dump () &#58; void &#123; &#125;: each call to this method will show the results of the profiling
more...

SQL macros

  • &#91;ConfigureConnection (connectionString, name)&#93;: applied to a class, tells the compiler about the connections used later in other SQL macros
  • ExecuteNonQuery (&quot;INSERT INTO employee VALUES (&#39;John&#39;, &#39;Boo&#39;)&quot;, connection)&#59;: executes the query returning no results, via the specified connection
  • def count &#61; ExecuteScalar (&quot;SELECT COUNT FROM employee WHERE firstname &#61; $myparm&quot;, connection)&#59;: retrieves just one result, using the specified connection. See you can use the $ notation to substite variables
  • Execute a code for every returned result, binding the column names to variables. Beware that the code is just another parameter, so you need to end parenthesis after them
ExecuteReaderLoop ("SELECT * FROM employee WHERE firstname = $myparm",
dbcon, 
{
  Nemerle.IO.printf ("Name: %s %s\n", firstname, lastname)
});

more...

Concurrency macros

All this macros are in Nemerle.Concurrency namespace

  • async &#123; ... &#125;: You can execute any block of code asynchronously:
  • Additionally, you can create a method that will always execute asynchronously: async Read (s &#58; string) &#123; ... &#125;

Chords

Chords are sets of methods that only return a value when some exact amount of them are called in some order. This example states very well both the syntax and uses of chords:

class Buffer [T]
{
    [ChordMember]
    public Put (msg : T) : void;

    public Get () : T
    chord {
      | Put => msg
    }
}
More examples can be found at the SVN repository

Nemerle Standard Library

Collection classes

All in Nemerle.Collections namespace:

  • ICollection&#91;&#39;a&#93;: extends .NET ICollection by adding contract for mapping, folding, itering...
  • Hashtable&#91;&#39;a, &#39;b&#93;: extends System.Collections.Generic.Dictionary&#91;K, V&#93; by adding Fold, Map and Iter methods. Hastable saves items with an unique key
  • Heap: saves a list of objects, allowing only to extract the first removing (ExtractFirst) or not removing (Top) it. Like usual, allows Map, Iter and Fold operations.
  • LinkedList&#91;&#39;a&#93;: extends .NET generic LinkedList, adding some useful, list-like methods
  • Queue&#91;&#39;a&#93;: like always, extends .NET Queue&#91;&#39;a&#93; by adding the useful list-like methods like Iter, Fold, Map... Queues are data structures which only allow to add or remove items at the end or the start of them
  • Set&#91;&#39;a&#93;: an implementation of mathematical sets. It allows all normal operations on list plus:
    • Sum: adds two sets yielding only one replica of each duplicated element
    • Substract: returns all elements of the first set that are not in the second one
    • Intersect: return the elements that appear on both sets
    • Xor: return the elements that appear in one of the sets, but not in both
  • Stack&#91;&#39;a&#93;: extends .NET Stack, a class which allows to add or remove items only on the top of them
  • Tree contains an implentation of Red-Black trees, an useful structure
  • RList (Random Access List) is a purely functional data structure

Array and String extensions

This methods live in Nemerle.Utility namespace, in NArray and NString classes, but can be used in arrays and string in code in a normal way. The methods adds functionality a la list for these two types.

Nemerle.IO

Contains helper functions for handling an input stream: ReadIntDigits, ReadRealDigits, ReadString, ReadChar, ConsumeWhiteSpace and CheckInput.

Option

The type option&#91;&#39;a&#93; allows to save values that can be null. option.None tells that it has no value. option.Some (value) saves a value. You can also use the nullable types (discussed above), but they are limited to valuetypes.

Clone this wiki locally