Ein paar Worte vorabHome   Letzte MeldungenNews   Index der Kapitel und der besprochenen FunktionenIndex   Wer ich bin, warum ich diese Seiten mache, KontaktImpressum   Ich freue mich über jeden Eintrag im Gästebuch!Gästebuch   Einige Links zu anderen AutoLisp-SeitenLinks   Copyrights und DisclaimerRechts
Hier können die kompletten Seiten als ZIP-File heruntergeladen werden!

Funktionen für komfortables Arbeiten mit Zeichenketten String-Tango
Noch mehr Funktionen für komfortableres Arbeiten mit Zeichenketten Kettenhunde
strtok zerlegt Zeichenketten anhand eines Trennzeichens Tock-Tock
Arbeiten mit Datum und Zeit in AutoLisp Zeitlos...
Dotted pairs - wie man den Programmabbruch verhindert Gepunktet?
Neue Funktionen für die Listenbearbeitung Strukturtapete
Weitere neue Funktionen für die Listenbearbeitung Listen to me!
Lambda expressions - dasSalz in der Suppe Lambada
Lambda expressions anhand eines Praxisbeispiels Unter der Erde
Where und whereever erleichtern den Umgang mit Listen Quo vadis?
Rekursion - Funktionen, die sich selbst aufrufen Katzenschwanz
Ein äusserst wichtiger Prototyp für Funktionen Nix passiert
Wo das lineare mapcar am Ende ist Tiefer rein!
Über Effekte und Neben(Seiten-)Effekte von Funktionen Seitensprünge
Die Namensräume (Sichtbarkeit) von Variablen Raumwunder
Let dient zur Schaffung kleinerer Namensräume Lass mal...
Sukzessive Verarbeitung von Listenresten mit mapcdr Der Bruder
Was in AutoLisp einfach nicht machbar ist (Teil I) Beschränkt
Was in AutoLisp einfach nicht machbar ist (Teil II) Limited Edition
Nicht mit Effekten arbeiten, sondern direkter Daten-Änderung Destruktiv
Sequenzielles vs. paralleles Abarbeiten von Argumenten Parallelwelten
Über den Umgang mit Funktionsschablonen Erwachet!
Ein Praxiskapitel über Auswahlsätze, Attribute, wcmatch und mehr Durch die Brust
Die Farben des AutoCAD Color Index und ihre RGB-Werte Alles so schön
Hier laufen die Fäden zusammen: Viele Konzepte vereint Lapsus Lispuli
Ein Spiel als Beispiel für lernfähige Funktionen Zug um Zug
Errorhandling in AutoLisp - Teil 1 Alles valsch!
Errorhandling in AutoLisp - Teil 2 Und foll Feler!


Zum Einsteiger-Tutorial

Zu den ActiveX-Seiten

Meine Private HP mit Fotos, Gedichten, Musik und Postkartenversand

Mein Online-Lexikon der Fotografie

Mein völlig abgedrehtes Reisebüro










lambda-expressions oder lambda-ausdrücke sind eines der grundlegenden Werkzeuge in AutoLisp. Wer diesen wunderbaren Mechanismus nicht richtig verstanden hat, wird sich schwer tun, komplexere Mechanismen zu verstehen. Deshalb geht es in diesem Kapitel nur darum, diese Abläufe noch einmal zu beleuchten und sie zu erklären.

lambda-expressions sind nichts weiter als Funktionen, die nicht an einen Namen gebunden sind. Da sie dies nicht sind, können sie auch nur einmal verwendet werden - Funktionen, die an ein Symbol gebunden sind, können immer wieder verwendet werden. lambda-expressions sind also eine Art Einmal- oder Wegwerffunktionen, die aber (anders als im richtigen Leben!) hervorragend dazu geeignet sind, 'Umweltschäden' zu vermeiden.

lambda-expressions entsorgen sich nach ihrer Anwendung selbst, d.h. es bleibt von ihnen absolut nichts im Speicher übrig, wenn sie ausgeführt worden sind. Benannte Funktionen hingegen bleiben dauerhaft im Speicher hängen, es sei denn, das Symbol bekommt ausdrücklich den Wert nil zugewiesen. Sie werden dann verwendet, wenn es darum geht, vorhandene Funktionen an bestimmten Stellen auf die jeweiligen Bedürfnisse anzupassen.

Abgesehen von ihrer Anonymität verhalten sich lambda-expressions wie ganz 'normale' Funktionen. Sie können Argumente bekommen, sie können lokale Variablen haben, sie haben eine Rückgabe und sie können Seiteneffekte haben. Wichtig ist, dass ihr Namensraum ebenso auf die Funktion selbst beschränkt ist wie bei allen anderen Funktionen.

Am häufigsten, aber nicht notwendigerweise, werden lambda-expressions in Verbindung mit (mapcar ...) eingesetzt. Daher folgen hier einige Beispiele für solche (mapcar '(lambda ...)...) - Anwendungen.

(princ "Sorry - Beispiele werden nachgereicht!")
                  
Ein recht einfaches Beispiel für die Anwendung von lambda-expressions wird im Kapitel über die Funktionen (where ...) und (whereever ...) vorgestellt. Etwas schwieriger wird dann schon das Kapitel über (mapin ...), auch diese Funktion erwartet eine lambda-expression als Argument. Übrigens lassen sich lambda-expressions durchaus mit set oder setq an eine Variable binden. Dann haben wir die etwas merkwürdige Situation, dass eine anonyme Funktion doch einen Namen hat.

Ein etwas komplexeres Beispiel für unsere lambda-expressions ist der hier vorgestellte Funktionsplotter: Er kann dazu verwendet werden, bestimmte in der Draufsicht rechteckige PMESHs in AutoCAD zur erzeugen. Die jeweilige Z-Koordinate ist eine Funktion von X und Y. Die Lisp-Funktion besorgt die ganze Schleifensteuerung, das Inkrementieren von X und Y usw. und die grafische Ausgabe, das Berechnen von Z aus X und Y bleibt aber frei und wird der Plot-Funktion jeweils als lambda-expression übergeben.

Der Code des Funktionsplotters:
(defun fplot(expr steps xpi ypi /
                 xn yn zn tlist plist _plot)
  (defun _plot(l / i j)
    (setq i 0)
    (command "_3dmesh" (length l)(length(car l)))
    (repeat(length l)
      (setq j 0)
      (repeat(length(car l))
        (command (nth j(nth i l)))
        (setq j(1+ j))
      )
      (setq i(1+ i))
    )
  )
  ;**********************
  (setvar "blipmode" 0)
  (setvar "cmdecho" 0)
  (setq plist nil)
  (setq xn 0.0 yn 0.0)
  (repeat(* xpi steps)
    (setq tlist nil)
    (setq yn 0.0)
    (repeat(* ypi steps)
      (setq zn((eval expr) xn yn))
      (setq tlist(append tlist(list(list xn yn zn))))
      (setq yn(+ yn(/ pi steps)))
    )
    (setq plist(append plist(list tlist)))
    (setq xn(+ xn(/ pi steps)))
  )
  (_plot plist)
)
                  
Erstes Argument ist also eine lambda-expression, die z aus x und y berechnet. Das zweite Argument gibt die Auflösung pro pi an, die Feinheit also. Die beiden letzten Argumente geben die Ausdehnung des Meshs in den beiden Richtungen in pi an.

Der Code ist kurz und verzichtet auf alles Unnötige. Ein Error-Handling ist nicht eingebaut, und sicher wäre alles auch noch zu beschleunigen. Das hier vorgestellte Programm soll aber nur die Verwendung von lambda-expressions verdeutlichen und dient daher nur als Grundlage für weitere Experimente.

Und so sehen verschiedene Aufrufe mit lambda-expressions und ihre Resultate dann aus:
(fplot '(lambda(x y / )(*(cos x)(cos y))) 10 10 10)
                  
'(lambda(x y / )(*(cos x)(cos y)))

Goraud-Shade


Die lambda-expression '(lambda(x y / )(*(cos x)(cos y))) ist also offensichtlich für das Erzeugen von Eierpappen zuständig.

Noch eine weitere Eierpappen-Variante bekommen wir mit
(fplot
 '(lambda(x y / )
    (max -0.5(min 0.5(*(cos x)(cos y))))
  )
)
                  
'(lambda(x y / )(max -0.5(min 0.5(*(cos x)(cos y)))))


Eine etwas andere Anordnung unserer Ostereier erreichen wir mit der folgenden lambda-expression, die Ostereier stehen etwas übereinander angeordnet:
(fplot
 '(lambda(x y / )
    (/(*(+(cos x)x)(+(cos y)y))50.0)
  )
)
                  
Noch mehr Eierpappen

Goraud-Eierpappen


Versuchen wir doch mal etwas anderes (nein, keine neuen Eierpappen!):
(fplot '(lambda(x y / )(cos(* x y))) 20 3 3)
                  
'(lambda(x y / )(cos(* x y)))