Optionale Standardparameter


26

Emacs Lisp unterstützt syntaktisch keine Nicht-Null-Standardeinstellungen für optionale Parameter. Was ist die empfohlene Redewendung für die Angabe dieser Parameter?

Um meinen Standpunkt zu verdeutlichen, hier ist eine übermäßig explizite Möglichkeit, dies zu tun.

(defun command (a &optional supplied-b)
  (let ((b (or supplied-b default-b)))
    (command-body a b)))

Was ist der empfohlene Stil?

Antworten:


24

Sofern Sie keine von @legoscia vorgeschlagenen Common Lisp-Erweiterungen verwenden, müssen Sie überprüfen, ob das optionale Argument angegeben wurde. Beachten Sie, dass Sie hier nicht wirklich verwenden müssen let. Das scheint mir idiomatischer zu sein:

(defun command (a &optional b)
  (or b (setq b default))
  (command-body a b))

Wie in den Kommentaren vorgeschlagen, unlesskann die Verwendung von vorzuziehen sein, um or:

(defun command (a &optional b)
  (unless b (setq b default))
  (command-body a b))

Auch aus den Kommentaren: Der reinere funktionale Stil wäre zu verwenden let, wie in der ursprünglichen Frage, aber Sie brauchen keine separaten Variablennamen:

(defun my-command (a &optional b)
  (let ((b (or b default)))
    (command-body a b)))

Wenn der optionale Parameter nur einmal benötigt wird, sollten Sie dies natürlich einfach tun:

(defun my-command (a &optional b)
    (command-body a (or b default)))

7
-1: Ich denke nicht, dass es ein guter Stil ist, einen nebenwirkenden Ausdruck wie setqin einer „reinen“ Booleschen Form wie zu verwenden or. Meiner Meinung nach whenist dies hier definitiv angemessener, aber im Allgemeinen letist es der Ausdruck der Wahl, lokale Bindungen herzustellen oder zu ändern. IOW, der ursprüngliche Code sieht für mich viel besser aus.
Lunaryorn

3
Ich bin damit einverstanden, dass so etwas (unless b (setq b default)besser sein könnte. Persönlich halte ich das hier für letüberflüssig, weil bdas schon lokal ist defun.
Glucas

3
Es ist Geschmackssache, aber ich bevorzuge reinen Code und reine Bindungen, dh letgegenüber einer nebenwirkenden Form wie setq. Es ist Code für einen Standardparameter, aber die großzügige Verwendung setqzum Ändern lokaler Variablen erschwert das Lesen und Verfolgen von Code. Ich denke, es ist am besten, alle lokalen Bindungen als unveränderlich zu betrachten und nur neue Bindungen mit einzurichten let. IOW, bevorzugen Sie einen funktionalen Stil gegenüber einem imperativen.
Lunaryorn

22

Sie können cl-defunFolgendes verwenden, um einen Standardwert für optionale Argumente anzugeben:

(cl-defun command (a &optional (b default-b))
  (command-body a b))

Der Standardwert wird in diesem Fall default-bbei jedem Funktionsaufruf ausgewertet.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.