Nemerle is a new hybrid (functional, object-oriented and imperative) programming language for the .NET platform. It tries to combine the featureset of MlLanguage with a syntax familiar to C/C++/C#/Java programmers.
Key features of the language include:
For an example of the flavour of the language, here are a few example programs:
module Hello { Main(): void { Nemerle.IO.printf("Hello world\n"); //System.Console.WriteLine?() would work, too } }or a graphical version, using Gtk#:
using System; using Gtk; using GtkSharp; module hello { Main(): void { Application.Init(); def button = Button("Hello World"); button.Clicked += (fun(_,_) { Console.WriteLine("Hello World") }); // extra parentheses around the anonymous function unfortunately // necessary due to a tweak that was made to keyword precedences // in version 0.1.4. This issue is being reconsidered, however, // and may be changed back at some point. def window = Window("Helloworld"); window.DeleteEvent += (fun(_,_) { Application.Quit() }); window.Add(button); window.ShowAll(); Application.Run() } }And something a little more complex - a macro definition, for an alternative exception-handling syntax (based [very roughly] on the syntax presented in http://research.microsoft.com/~akenn/sml/ExceptionalSyntax.pdf):
macro AttemptUnless(tryexpr, catchexpr, exc: funparm, thenexpr) // would be "try" instead of "attempt", but the current macro system is // unable to disambiguate between multiple syntactic forms using the // same keywords, and try is already taken by the normaltry-catch-finally // exception-handling syntax syntax("attempt", "(", tryexpr,")", "catch", "(", exc, ")", catchexpr, "else", thenexpr) { match(tryexpr) { | <[$(nm: name) = $attempt]> => match(exc) { | <[ funparm: $(exc: name): $ty ]> => <[ mutable $(exc: name) = null; def $(nm: name) = try { Some($attempt) } catch { exception: $ty => $(exc: name) = exception; None () } match($(nm: name)) { | Some($(nm: name)) => $thenexpr | None => $catchexpr } ]> | _ => Message.fatal_error("oops") } | _ => Message.fatal_error("d'oh!") } }This allows things like this:
public static Collect(fileNames : list <string>) : string { | [] => "" | fileName :: rest => attempt (f = File.OpenText (fileName)) catch(ex : Exception) { Log (ex); Collect (rest); } else { def s = f.ReadToEnd (); f.Close(); s + Collect (rest) } }Where the else block is only executed when File.OpenText() doesn't throw. The full code it expands out to is roughly:
public static Collect(fileNames : list <string>) : string { | [] => "" | fileName :: rest => mutable ex = null; def f = try { Some (File.OpenText (file_name)) } catch { e : Exception => ex = e; None () } match(f) { | Some(f) => def s = f.ReadToEnd (); f.Close (); s + Collect(rest) | None => Log(ex); Collect(rest) } }There's currently [September 2004] some discussion on the nemerle wiki [http://nemerle.org/cgi-bin/wiki/NemerleWiki] (which is otherwise somewhat quiet, unfortunately) (and on the mailing list, which is somewhat more active), about the best choice of syntax for this kind of construct: http://nemerle.org/cgi-bin/wiki/TryUnlessFeedback
The macro above was just something I hacked together (and later improved, to use Nemerle's option type (the Some(a) and None() bits in the macro above - equivalent to the Haskell Just a and Nothing), after I realised it didn't work with value types) to see if I could do it - the final solution will no doubt be significantly better. (It'll probably have proper error messages, for a start...)
-- MikeRoome
How about comparisons to ScalaLanguage? Where Scala is basically Java + Functional + syntax, Nemerele is basically CeeSharp + Functional + Syntax. However, they do have distinct features.
Scala: