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










Hier geht es um eine weitere Funktion, die in Lisp-Dialekten eigentlich zum Standard gehört, aber in AutoLisp nicht implementiert wurde: (let ...) schafft einen lokalen Namensraum für Variablen und bindet Werte an die Symbole. Lokale Variablen, die hinter dem Schrägstrich in der Argumentenliste deklariert werden, sind ja hinlänglich bekannt. Aber es gibt ja dann auch noch Bindungen, deren Namensraum noch kleiner ist: Denken wir doch mal an (foreach item ...)! foreach schafft für das Symbol item einen Namensraum, der auf die foreach-Schleife beschränkt ist. Es daher unnötig, das Symbol item in der Argumentenliste der umgebenden Funktion lokal zu deklarieren (tut man es trotzdem, hat man es mit zwei verschiedenen Variablen zu tun, die zwar den gleichen Namen haben, aber in verschiedenen Namensräumen existieren).

Solche verkleinerten Namensräume innerhalb von Funktionen entstehen aber auch durch die Verwendung von (lambda ...). Ganz streng genommen entsteht allerdings wieder ein neuer Funktions-Namenraum, da lambda natürlich eine neue Funktion einlagert. Eine 'Verkleinerung' wie bei foreach ist also eigentlich gar nicht gegeben. Genau diesen lambda-Mechanismus nutzen wir nun, um unser let zu definieren. Der Code fällt recht kurz aus:
(defun let(bindings body / )
  (eval
    (cons
      (append
        (list'lambda(mapcar 'car bindings))
        (list body)
      )
      (mapcar 'cadr bindings)
    )
  )
)
                  
Zunächst einmal ein Anwendungsbeispiel, das gleichzeitig demonstriert, wie schön die im Argument bindings eigene, zu let lokale Variablen erzeugen, die die vorhandenen, zur Testfunktion lokalen Variablen zeitweise überdecken:
(defun let-test( / localvar1 localvar2)
  (setq localvar1 3 localvar2 "X")
  (princ "localvar1 in let-test: ")
  (princ localvar1)
  (terpri)
  (princ "localvar2 in let-test: ")
  (princ localvar2)
  (terpri)
  (let '((localvar1 7)(localvar2 "Y"))
   '(progn
      (princ "localvar1 in let: ")
      (princ localvar1)
      (terpri)
      (princ "localvar2 in let: ")
      (princ localvar2)
      (terpri)
    )
  )
  (princ "localvar1 in let-test: ")
  (princ localvar1)
  (terpri)
  (princ "localvar2 in let-test: ")
  (princ localvar2)
  (terpri)
)
                  
Und nun zu den möglichen Anwendungen von (let ...). Grundsätzlich können wir mit let erst einmal Variablen auf Ausschnitte von Funktion begrenzen, z.B. bei Schleifen:
(let '((i 0)) '(while (/= i ...
                  
Die hat den Vorteil, dass die Variable i wirklich nur innerhalb dieser Schleife bekannt ist. Insbesondere, wenn mehrere solcher Schleifen innerhalb einer Funktion vorkommen, kann man so sicherstellen, dass jede Schleife ihren eigenen Zähler i bekommt, ungewollte Einflüsse werden recht einfach ausgeschlossen. Interessanter wird die Sache aber dann, wenn die bindings gar nicht direkt angegeben werden, sondern an ganz anderer Stelle erzeugt werden. Eine solche Verwendung von let könnte z.B. so aussehen:
(let (dialog-starten)
 '(if(not aborted)
    (if checker_1
      ...
      ...
    )
  )
)
                  
aborted und checker_1 könnte hier zu let lokale Variablen sein, die irgendwo in den mit einem Dialog zusammenhängenden Funktionen zu einem bindings-Paket zusammengeschnürt wurden. In diesem Paket sind die Dialog-Keys (natürlich mit (read ...) in Symbole umgewandelt) zusammen mit den aus dem Dialog ausgelesen Werten verpackt. Jeder Key des DCL-Dialogs steht dann innerhalb der let-Anweisung als lokale Variable zur Verfügung.