Im Grunde geht es darum, eine Funktion lokal und mit Zugriff auf den lokalen Kontext definieren zu können und diese dann dort oder sogar außerhalb des eigentlichen Kontextes verwenden zu können. Manche Sprachen erwarten für lokale Funktionen einen Namen, andere erlauben namenlose (anonyme) Funktionen.
Mit Closures lassen sich sehr elegant interne Iteratoren definieren, siehe WardsWiki:InternalIterator. In Sprachen, denen Closures fehlen, werden deshalb häufiger externe Iteratoren ( WardsWiki:ExternalIterator) verwendet. Diese Spracheigenschaft hat daher Einfluß auf das Schnittstellen-Design von Container-Bibliotheken.
Siehe auch Wikipedia deutsch, Wikipedia englisch und FolDoc, WardsWiki:BlocksInManyLanguages
SpracheD |
SpracheHaskell |
In der SpracheHaskell benutzt man das ständig, entweder ausdrücklich mit der Lambda-Notation
|
oder mit teilweiser Funktionsauswertung
|
Übrigens kann man in Sprachen, die Closures unterstützen, auch Modaden ausdrücken: http://moonbase.rydia.net/mental/writings/programming/monads-in-ruby/00introduction.html
SpracheJava |
In der SpracheJava kann man AnonymeInnereKlassen? benutzen. Ist zwar ein wenig umständlich, funktioniert aber.
|
Nicht jeder ist davon angetan:
|
http://c2.com/ppr/wiki/JavaIdioms/BlocksInJava.html
Mittlerweile tut sich was:
SpracheModula3 |
In der SpracheModula3 sind Unterprogramme in Unterprogrammen erlaubt, sie müssen aber immer einen Namen tragen.
|
SprachePerl |
|
Von perlsub(1).
Inplace sortieren:
|
Elemente einer Liste bearbeiten:
|
Liste filtern:
|
SprachePython |
Inplace sortieren einer Liste (als Parameter wird eine Funktion erwartet, die -1, 0, oder 1 zurückgibt:
|
Gegen eine lokale Variable vergleichen:
|
Den Block durchreichen, obwohl dieser eine lokale Variable referenziert. (Dank GarbageCollector ist das auch für fette Objekte möglich!)
|
alternativ (für komplexere Abläufe)
|
Erzeugen einer parametrisierten Funktion
|
In Python kann man nur LambdaExpressions? unbenannt definieren. Ein komplexer Ablauf muss benannt werden und als Funktion definiert werden. Man kann also in Python keine echten Kontrollstrukturen definieren wie in Smalltalk oder Ruby. Man kann aber eine Funktion einer anderen als Parameter übergeben. Hier ein Beispiel für eine Funktion, die eine andere x-mal aufzurufen versucht. Die Parameter der wiederholten Funktion werden erst beim Aufruf übergeben:
|
Ein Generator, der mehrere Werte zurückgibt:
|
Ein, recht dumm programmierter Generator, der alle Teiler einer Zahl zurükgibt:
|
SpracheRuby |
SpracheSmalltalk |
Ein Standard-Beispiel in Smalltalk wäre ein Sortblock:
|
Gegen eine lokale Variable vergleichen:
|
Den Block durchreichen, obwohl dieser eine lokale Variable referenziert. (Dank GarbageCollection ist das auch für fette Objekte möglich!)
|
Blöcke spielen in Smalltalk ein überaus zentrale Rolle, weil Kontrollstrukturen nicht in die Sprache eingebaut sind, sondern über Blöcke realisiert wurden:
|
Hier ist true eine globale Instanz von True und True eine Smalltalk-Klasse, die Methode ifTrue:ifFalse: mit Ausführung des ersten Blockes implementiert.
Überflüssig zu sagen, dass man Blöcke schachteln kann:
|
Sehr platzsparend sind Iterator-Methoden mit mehreren Blöcken:
|
SpracheCsharp |
Lt. http://gnuvince.net/?p=55 wird es in C# 3.0 soetwas wie Lambda-Ausdrücke geben. Mehr dazu auch unter http://joe.truemesh.com/blog//000390.html.
SpracheGroovy |
http://groovy.codehaus.org/Closures