Impostazioni predefinite dei parametri


26

Emacs Lisp non ha supporto sintattico per valori predefiniti non nulli di parametri opzionali. Qual è il linguaggio raccomandato per fornire questi parametri?

Per chiarire il mio punto, ecco un modo eccessivamente esplicito per farlo.

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

Qual è lo stile consigliato?

Risposte:


24

A meno che non si utilizzino le estensioni Common Lisp come suggerito da @legoscia, è necessario verificare se è stato specificato l'argomento facoltativo. Si noti che non è necessario utilizzare letqui. Questo mi sembra più idiomatico:

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

Come suggerito nei commenti, unlessè preferibile utilizzare or:

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

Anche dai commenti: lo stile funzionale più puro sarebbe usare let, come nella domanda originale, ma non hai bisogno di nomi di variabili separati:

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

Naturalmente, se il parametro opzionale è necessario solo una volta, dovresti semplicemente fare questo:

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

7
-1: Non penso che sia un buon stile usare un'espressione con effetti collaterali come setqin una forma booleana “pura” come or. A mio avviso whenè sicuramente più appropriato qui, ma generalmente letè l'espressione della scelta di stabilire o modificare i vincoli locali. IOW, il codice originale mi sembra molto più bello.
lunaryorn,

3
Sono d'accordo che qualcosa di simile (unless b (setq b default)potrebbe essere migliore. Personalmente, penso che letsia ridondante qui perché bè già locale al defun.
Glucas,

3
È una questione di gusti, ma preferisco il codice puro e i vincoli puri, cioè letsu una forma che ha effetti collaterali come setq. È il codice per un parametro predefinito, ma l'uso liberale di setqmodificare le variabili locali rende il codice difficile da leggere e da seguire. Penso che sia meglio considerare immutabili tutti i binding locali e stabilire solo nuovi binding let. IOW, preferisco uno stile funzionale a uno imperativo.
lunaryorn,

22

È possibile utilizzare cl-defun, che consente di specificare un valore predefinito per argomenti facoltativi:

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

Il valore predefinito, in questo caso default-b, verrà valutato ogni volta che viene chiamata la funzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.