Wenn ich mich in die Materie einarbeite, würde ich aber vermutlich die erste Version für "ästhetischer" halten, weil sie alle relevanten Schritte zu einem umfangreichen Ausdruck kombiniert, anstatt sie in mehrere abgehackte Einzelschritte zu zerlegen, deren Zusammenhang man erst mühsam wieder herstellen muss.
Ich weiß nicht. Ich bin ja durchaus kein Feind von umfangreichen und mächtigen Ausdrucken, schließlich gehe ich immer mehr in die Richtung von higher order functions wie map, reduce, currying und so. Aber dennoch finde ich, dass man versuchen sollte, konzeptionelle Einzeiler zu vermeiden, auch wenn sie wie hier etwas sauberer geschrieben werden. Programmieren ist zu einem Großteil die Kunst, Probleme in Einzelschritte zu überlegen. Aus verschiedenen Gründen, einer ist zum Beispiel Testbarkeit von Einzelschritten. Aber eben auch das, und das ist, was ich in meinem Posting oben ansprach, dass definierte Einzelschritte weniger kognitive Last mit sich bringen und ein Programm somit klarer und verständlicher für den Lesenden und Programmierenden machen.
• Anonyme Lambdas ...
Was soll das sein? Den Begriff habe ich noch nie gehört.
Ein weißer Schimmel. Lambda ist der klassische Ausdruck für on-the-fly definierte Funktionen. Bist Du bestimmt schon tausendmal drüber gestolpert. Vergleiche mal diesen pythonischen Quellcode, der die Zahlen einer Liste verdoppelt:
~~~python
def double(number):
return number*2
a = [1, 2, 4, 5]
b = map(double, a)
vs.
~~~python
a = [1, 2, 4, 5]
b = map(lambda x: x*2, a)
Das Konstrukt findet sich überall, in JS als function expressions, Rubys Blocks, etc. Ist ja auch praktisch, nicht nur wegen des on-the-fly-Aspektes, sondern auch dann, wenn man diverse Funktionen (evtl. mit Closure) erzeugt und rumreichen will. Lambda ist nur ein Name dafür, der, wie Jeena schon sagt, aus dem Lambda Kalkül kommt.
pattern matching/guards aus Haskell ... anonyme Lambda ... lazy list
Wenn du nicht so sehr mit extrem spezifischen Buzzwords um dich werfen würdest, könnte man vielleicht sogar verstehen, was du sagen möchtest.
Nun ja, ich fange ja schon relativ früh an, über funktionalen Stil zu reden und denke, die Zielgruppe meines Postings sind Leute, die mit diversen Programmierstilen vertraut sind und auch schon mal in funktionalen Sprachen reingeschnuppert haben. Oder sich schnell bei Wikipedia schlau lesen können.
Pattern matching ist syntaktischer Zucker, um diverse Funktionsvarianeten anhand der übergebenen Daten unterscheiden zu können. Nimm mal diese aus Real World Haskell entnommene Funktionen:
~~~haskell
-- Eine Funktion, die die Zahlen einer Liste quadriert
square :: [Double] -> [Double] -- Typ-Definition. Ignorier's
square (x:xs) = x*x : square xs -- Nimm das erste Element der Liste und
-- quadriere es, bilde mit dem Ergebnis des
-- rekursiven Aufrufs der Funktion auf den
-- Rest der Liste eine neue Liste
square [] = [] -- Bei der leeren Liste gib eine leere Liste
-- zurück. Abbruch der Rekursion.
Guard erweitern diese Möglichkeit um Vorbedingungen:
~~~haskell
-- Eine Funktion die eine Liste nur auf ungerade Zahlen filtert.
oddList :: [Int] -> [Int]
oddList (x:xs) | odd x = x : oddList xs -- Hier ist der Guard. Mach dies,
-- wenn das erste Listenelement
-- ungerade its.
| otherwise = oddList xs -- Ansonsten das.
oddList _ = []
Kann man auch alles klassisch machen, mit vielen if-Klauseln und so. Kann man. Aber wenn man so eine schöne deklarative Syntax hat, ist es netter. Und lesbarer, ist man es gewöhnt.
Leider nein, denn ich fürchte, die Ansichten und Meinungen dazu sind sehr zahlreich und kontrovers.
Nun ja, ich will mir ja selber mein Interesse befriedigen und eine fundiertere Meinung bilden. Dafür sind kontroverse Diskussionen nicht schlecht.