Nemerle
This page was last modified on 24 May 2016, at 20:20.
Paradigm | multi-paradigm, object-oriented, functional, imperative |
---|---|
Designed by | Wrocław University; Michał Moskal, Kamil Skalski, Paweł Olszta and others. |
Developer | JetBrains |
First appeared | 2003 |
Stable release | 1.0 Google Code GitHub / 5.12 2011 |
Typing discipline | static |
Website | http://nemerle.org/About/ |
Influenced by | |
C#, ML, OCaml, Haskell, Lisp |
Nemerle is a general-purpose high-level statically typed programming language designed for platforms using the Common Language Infrastructure (.NET/Mono). It offers functional, object-oriented and imperative features. It has a simple C#-like syntax and a powerful metaprogramming system. In June 2012, the core developers of Nemerle were hired by the Czech software development company JetBrains. The team is focusing on the development of Nitra; a framework for implementing new and existing programming languages. This framework will likely be used to create future versions of Nemerle.
The language was named after the Archmage Nemmerle, a character in the fantasy novel A Wizard of Earthsea by Ursula K. Le Guin.
Contents
Features
Nemerle's most notable feature is the ability to mix object oriented and functional styles of programming. Programs may be structured using object oriented concepts such as classes and namespaces, while methods can (optionally) be written in a functional style. Other notable features include:
- strong type inference
- a flexible metaprogramming subsystem (using macros)
- full support for Object-oriented programming|OOP (in the style of C#, Java, and C++)
- full support for functional programming (in the style of ML, OCaml, Haskell) with the following features:
- higher-order functions
- pattern matching
- algebraic types
- local functions
- tuples and anonymous types
- partial application of functions
The metaprogramming system allows for a great deal of compiler extensibility, embedding of domain specific languages, partial evaluation, and aspect-oriented programming, taking a high-level approach to lift as much of the burden from the programmer as possible. The language combines all CLI standard features, including parametric polymorphism, lambdas, extension methods etc. Accessing the libraries included in the .NET or Mono platforms is as easy as in C#.
Type inference
def x = 1; // int
def myList = List(); // generic List[T], type T is deduced from the usage in the next line
myList.Add(x); // compiler deduces type of T as int making myList type of List[int]
Everything is an expression
def x =
{ // similar to x = 3
def y = 1;
def z = 2;
y + z // this last statement is a block return value
};
def x =
if (DateTime.Now.DayOfWeek == DayOfWeek.Monday) // if, using, try are also expressions
"Monday"
else
"other day";
def x = try int.Parse(someString)
catch { | FormatException() => 0 };
def x = returnBlock :
{
foreach (i in [1, 2, 3])
when (i > 2)
returnBlock(true); // exit block (x = true)
false // x = false
};
Tuples
def k = (1, "one"); // k : (int * string)
def (a, b) = k; // a = 1, b = "one"
Pattern matching
def result = match (number)
{
| 0 => "zero"
| 1 => "one"
| x when x < 0 => "negative"
| _ => "more than one"
}
Type matching with variable binding:
def check (o : object) {
match (o)
{
| i is int => $"An int: $i"
| s is string => $"A string: $(s.ToUpper())"
| _ => "Object of another type"
}
}
Tuple pattern matching:
match (tuple)
{
| ( 42, _ ) => "42 on first position"
| ( _, 42 ) => "42 on second position"
| ( x, y ) => $"( $x, $y )"
}
Regexp matching:
using Nemerle.Text;
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");
}
}}
Functional types and local functions
using System.Console; // classes and modules (static classes) can be put in namespaces
def next(x) { x + 1 }; // the type of x argument and other function arguments can be deduced from usage
def mult(x, y) { x * y };
def fibonacci(i)
{
| 0 => 0
| 1 => 1
| other => fibonacci(i - 1) + fibonacci(i - 2)
};
WriteLine(next(9)); // 10 similar to "Console.WriteLine(next(9));"
WriteLine(mult(2, 2)); // 4
WriteLine(fibonacci(10)); // 55
Variants
Variants (called data types or sum types in SML and OCaml) are forms of expressing data of several different kinds:
variant RgbColor{
| Red
| Yellow
| Green
| Different {
red : float;
green : float;
blue : float;
}
}
Metaprogramming
Nemerle's macro system allows for the creation, analysis, and modification of a program's code during the compilation process. Macros can be used in the form of a method call or as a new language construct. Many constructs within the language were implemented using macros (if, for, foreach, while, using etc.).
"if" macro example:
macro @if (cond, e1, e2)
syntax ("if", "(", cond, ")", e1, Optional (";"), "else", e2)
{
/*
<[ ]> defines an area of quasi-quotation, the Nemerle compiler transforms the code in it
to an AST tree, such transformations are somewhat similar to an Expression compiling in C#
*/
<[
match ($cond : bool)
{
| true => $e1
| _ => $e2
}
]>
}
// using this macro in code:
def max = if (a > b) a else b;
// during a compile time the upper line will be transformed to the following:
def max = match (a > b)
{
| true => a
| _ => b
}
IDE
Nemerle can be integrated into Visual Studio 2008. It also has a completely free IDE based on Visual Studio 2008 Shell[4] (like Visual Studio Express Editions) and SharpDevelop (link to plugin source code).
Nemerle can be also integrated into Visual Studio 2010 using the add-in.
Examples
Hello, World!
The traditional "Hello World!" can be implemented in a more C#-like fashion:
class Hello
{
static Main () : void
{
System.Console.WriteLine ("Hello, world!");
}
}
or more simply:
System.Console.WriteLine("Hello, world!");
Nemerle with ASP.NET
Nemerle can be either embedded directly into ASP.NET:
<%@ Page Language="Nemerle" %>
<script runat="server">
Page_Load(_ : object, _ : EventArgs) : void {
Message.Text = $"You last accessed this page at: $(DateTime.Now)";
}
EnterBtn_Click(_ : object, _ : EventArgs) : void {
Message.Text = $"Hi $(Name.Text), welcome to ASP.NET!";
}
</script>
<html>
<body>
<form runat="server">
Please enter your name: <asp:TextBox ID="Name" runat="server" />
<asp:Button OnClick="EnterBtn_Click" Text="Enter" runat="server" />
<p><asp:Label ID="Message" runat="server" /></p>
</form>
</body>
</html>
...Or stored in a separate file and entered with a single line:
<%@ Page Language="Nemerle" Src="test.n" Inherits="Test" %>
Присоединяйся к команде
ISSN:
Следуй за Полисом
Оставайся в курсе последних событий
License
Except as otherwise noted, the content of this page is licensed under the Creative Commons Creative Commons «Attribution-NonCommercial-NoDerivatives» 4.0 License, and code samples are licensed under the Apache 2.0 License. See Terms of Use for details.