Czym jest Nemerle i dlaczego warto go poznać
Nemerle to multi-paradygmatowy język programowania stworzony na Uniwersytecie Wrocławskim (tak, polski akcent!), który działa na platformie .NET/Mono. Łączy programowanie funkcyjne, obiektowe i imperatywne w jednym spójnym języku, z silnym systemem typów i potężnym systemem makr.
Nemerle jest jak szalony naukowiec wśród języków .NET — ma features, które C# dostał dopiero lata później (albo wcale), a jego system makr pozwala na metaprogramowanie na poziomie, o którym Roslyn w C# może tylko pomarzyć. Jeśli interesujecie się projektowaniem języków i chcecie zobaczyć, jak mogłaby wyglądać alternatywna historia .NET — Nemerle jest waszym oknem do tego świata.
Dla polskich programistów Nemerle ma dodatkowy urok — to jeden z nielicznych języków programowania stworzonych w Polsce, przez polski zespół badawczy, z polskim rodowodem akademickim.
Krótka historia i ewolucja
Nemerle narodził się w 2003 roku na Uniwersytecie Wrocławskim, stworzony przez zespół pod kierunkiem Kamila Skowronka, Michała Moskala i innych badaczy. Nazwa pochodzi od Nemmerle — postaci z Władcy Pierścieni Tolkiena (czarodziej, który stworzył palantíry). Ambicja była podobna: stworzyć coś potężnego i wieloznacznego.
Język od początku działał na platformie .NET (i Mono na Linuksie), co dawało mu dostęp do bogatego ekosystemu bibliotek. Nemerle zyskał pewną popularność w kręgach akademickich i wśród entuzjastów, szczególnie w Polsce i Europie Środkowej. W szczytowym okresie (około 2008-2012) miał aktywną społeczność, wiki, forum i regularne wydania.
Niestety, Nemerle podzielił los wielu akademickich języków — brak krytycznej masy użytkowników, ograniczone zasoby na rozwój i rosnąca dominacja C# na platformie .NET sprawiły, że projekt stopniowo tracił impet. Dziś Nemerle jest raczej archiwalnym projektem niż aktywnie rozwijanym językiem, ale jego idee żyją dalej — wiele z nich znajdziecie w C# (pattern matching, records) i F# (funkcyjne features).
Kluczowe cechy i filozofia
Multi-paradygmatowość to fundament Nemerle. Możecie pisać czysty kod funkcyjny, klasyczny OOP albo imperatywne skrypty — wszystko w jednym języku, z płynnym przechodzeniem między paradygmatami. Nemerle nie zmusza was do jednego stylu.
System makr to killer feature Nemerle. Makra w Nemerle to nie proste substytucje tekstowe — to pełnoprawne programy, które operują na AST (Abstract Syntax Tree) w czasie kompilacji. Możecie rozszerzać składnię języka, tworzyć DSL-e, implementować nowe konstrukcje kontrolne — wszystko jako makra. To poziom metaprogramowania, który w C# jest nieosiągalny bez zewnętrznych generatorów kodu.
macro Repeat(expr, count) {
<[ for (mutable i = 0; i < $(count : int); i++) $expr ]>
}
To makro tworzy nową konstrukcję Repeat(Console.WriteLine("hello"), 5) — kompilator rozwija ją do pętli for.
Pattern matching w Nemerle jest bogatszy niż w C# — wspiera dekonstrukcję algebraic data types, guard clauses, nested patterns i active patterns. W połączeniu z variant (sum types) daje to potężne narzędzie do modelowania domen.
Variant types (algebraic data types) są natywne w Nemerle:
variant Option['a] {
| None
| Some { value : 'a }
}
To jest dokładnie to, co C# próbuje emulować za pomocą records i pattern matching, ale w Nemerle było to od początku.
Type inference działa dobrze — nie musicie pisać typów wszędzie, kompilator sam je odgaduje. Ale w przeciwieństwie do Haskella, Nemerle pozwala na annotacje tam, gdzie są potrzebne (np. w interfejsach publicznych API).
Integracja z .NET jest bezszwowa — każda biblioteka .NET jest dostępna, a kod Nemerle kompiluje się do standardowego IL, więc może być używany z C# i odwrotnie.
Gdzie Nemerle sprawdza się najlepiej
Nemerle był używany w kilku projektach komercyjnych, głównie w Polsce i Europie Środkowej. Jego najsilniejszym zastosowaniem były systemy wymagające bogatego metaprogramowania — generatory kodu, DSL-e dla domen biznesowych, frameworki z rozbudowaną konfiguracją w compile time.
W edukacji Nemerle bywał używany na Uniwersytecie Wrocławskim do nauczania zaawansowanego programowania i projektowania języków. Studenci mogli eksperymentować z makrami i rozszerzeniami składni w sposób, który w C# czy Javie jest niemożliwy.
Dziś Nemerle jest przede wszystkim źródłem inspiracji. Jego idee — makra operujące na AST, variant types, zaawansowany pattern matching — żyją w nowszych językach i w ewolucji C#.
Jak wygląda kod w Nemerle
Klasyczny przykład z pattern matching i variant types:
using System.Console;
variant Shape {
| Circle { radius : double }
| Rectangle { width : double; height : double }
| Triangle { a : double; b : double; c : double }
}
def area(shape : Shape) : double {
match(shape) {
| Circle(r) => System.Math.PI * r * r
| Rectangle(w, h) => w * h
| Triangle(a, b, c) =>
def s = (a + b + c) / 2.0;
System.Math.Sqrt(s * (s - a) * (s - b) * (s - c))
}
}
def main() {
def shapes = [Circle(5.0), Rectangle(3.0, 4.0), Triangle(3.0, 4.0, 5.0)];
foreach (s in shapes)
WriteLine($"Area: $(area(s))");
}
A oto przykład z makrami — prosty DSL do walidacji:
macro validate(expr, message) {
<[ unless ($(expr : bool)) {
throw System.ArgumentException($(message : string));
}
]>
}
def processOrder(order : Order) {
validate(order.Quantity > 0, "Quantity must be positive");
validate(order.Price >= 0.0, "Price cannot be negative");
// business logic...
}
Makro validate rozwija się do unless (który sam może być makrem) z throw — zero boilerplate, pełna czytelność.
Ekosystem i narzędzia
Nemerle miał własne IDE — Nemerle Studio (bazujące na Visual Studio Shell) oraz plugin do Visual Studio. Na Linuksie działał z MonoDevelop. Kompilator ncc (Nemerle Compiler Compiler) generował kod IL kompatybilny z .NET i Mono.
Biblioteka standardowa Nemerle obejmowała kolekcje funkcyjne (listy, sekwencje leniwe), obsługę makr i integrację z .NET BCL. Istniały też biblioteki do parsowania (PEG parser), web developmentu i baz danych.
Społeczność Nemerle była skupiona wokół nemerle.org (wiki, forum, bug tracker). Dziś strona jest nieaktywna, ale kod źródłowy jest dostępny na GitHubie i można go studiować jako materiał edukacyjny.
Mocne i słabe strony
Nemerle miał wizję, która wyprzedzała swoje czasy. System makr operujących na AST to coś, co C# zaczął realizować dopiero z Roslyn (2014) i source generators (2020). Variant types i pattern matching były w Nemerle od początku — C# dostał je w okrojonej formie w C# 7-9. Nemerle pokazał, że multi-paradygmatowy język na .NET może być potężny i elegancki.
Słabą stroną była mała społeczność i brak krytycznej masy. Nemerle konkurował z C# (który miał za sobą Microsoft) i F# (który miał wsparcie korporacyjne i rosnący ekosystem). Bez institutional backing, Nemerle nie mógł nadążyć z rozwojem toolingu i bibliotek.
Kolejnym problemem była krzywa uczenia się — system makr był potężny, ale trudny do opanowania. Dla większości programistów .NET, Nemerle był zbyt egzotyczny, a dla fanów funkcyjnych — zbyt związany z ekosystemem .NET.
Podsumowanie
Nemerle to dowód na to, że polska informatyka ma światowej klasy pomysły. Język, który w 2003 roku oferował features, na które C# czekał do 2020, zasługuje na szacunek i pamięć. Dla twórców języków i entuzjastów PLT, kod źródłowy Nemerle to kopalnia wiedzy.
Jeśli interesujecie się metaprogramowaniem, makrami i alternatywnymi podejściami do .NET — zajrzyjcie do repozytorium Nemerle na GitHubie. A jeśli szukacie produkcyjnego języka funkcyjnego na .NET — F# jest oczywistym wyborem. Ale pamiętajcie: Nemerle był pierwszy.

