Padrões de parâmetro opcionais


26

O Emacs Lisp não possui suporte sintático para padrões não nulos de parâmetros opcionais. Qual é o idioma recomendado para fornecer esses parâmetros?

Para esclarecer meu argumento, aqui está uma maneira excessivamente explícita de fazê-lo.

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

Qual é o estilo recomendado?

Respostas:


24

A menos que você use extensões Common Lisp, como sugerido por @legoscia, você precisa verificar se o argumento opcional foi especificado. Observe que você realmente não precisa usar letaqui. Isso me parece mais idiomático:

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

Conforme sugerido nos comentários, unlesspode ser preferível usar or:

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

Também a partir dos comentários: o estilo funcional mais puro seria o de usar let, como na pergunta original, mas você não precisa de nomes de variáveis ​​separados:

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

Obviamente, se o parâmetro opcional for necessário apenas uma vez, você deve fazer isso:

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

7
-1: Não acho que seja bom estilo usar uma expressão de efeito colateral como setqem uma forma booleana "pura" or. Na minha opinião, whené definitivamente mais apropriado aqui, mas geralmente leté a expressão de escolha para estabelecer ou alterar ligações locais. IOW, o código original parece muito melhor para mim.
23715 lunaryorn

3
Concordo que algo como (unless b (setq b default)pode ser melhor. Pessoalmente, acho que leté redundante aqui, porque bjá é local para o defun.
glucas

3
É uma questão de gosto, mas eu prefiro código puro e ligações puras, ou seja, letsobre uma forma de efeito colateral como setq. É o código para um parâmetro padrão, mas o uso liberal de setqpara alterar variáveis ​​locais torna o código difícil de ler e seguir. Eu acho que é melhor considerar todas as ligações locais imutáveis ​​e apenas estabelecer novas ligações com let. IOW, prefira um estilo funcional ao imperativo.
23715 lunaryorn

22

Você pode usar cl-defun, o que permite especificar um valor padrão para argumentos opcionais:

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

O valor padrão, neste caso default-b, será avaliado toda vez que a função for chamada.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.