Uma macro para fazer o que você deseja
Como um exercício de uma espécie:
(defmacro setq-every (value &rest vars)
"Set every variable from VARS to value VALUE."
`(progn ,@(mapcar (lambda (x) (list 'setq x value)) vars)))
Agora tente:
(setq-every "/foo/bar" f-loc1 f-loc2)
Como funciona
Como as pessoas têm curiosidade em saber como isso funciona (de acordo com os comentários), aqui está uma explicação. Para realmente aprender a escrever macros, escolha um bom livro Common Lisp (sim, Common Lisp, você poderá fazer o mesmo no Emacs Lisp, mas o Common Lisp é um pouco mais poderoso e possui melhores livros, IMHO).
Macros operam em código bruto. Macros não avaliam seus argumentos (ao contrário de funções). Portanto, temos aqui uma avaliação valuee uma coleção de vars, que para nossa macro são apenas símbolos.
prognagrupa várias setqformas em uma. Essa coisa:
(mapcar (lambda (x) (list 'setq x value)) vars)
Apenas gera uma lista de setqformulários, usando o exemplo do OP, será:
((setq f-loc1 "/foo/bar") (setq f-loc2 "/foo/bar"))
Veja, o formulário está dentro do formulário de aspas anteriores e é prefixado com uma vírgula
,. Dentro do formulário com aspas retroativas, tudo é cotado como de costume, mas ,
a avaliação mapcaré ativada temporariamente, e toda a avaliação é avaliada no momento da macroexpansão.
Finalmente @remove os parênteses externos da lista com setqs, para obtermos:
(progn
(setq f-loc1 "/foo/bar")
(setq f-loc2 "/foo/bar"))
As macros podem transformar arbitrariamente seu código-fonte, não é ótimo?
Uma ressalva
Aqui está uma pequena ressalva: o primeiro argumento será avaliado várias vezes, porque essa macro se expande essencialmente para o seguinte:
(progn
(setq f-loc1 "/foo/bar")
(setq f-loc2 "/foo/bar"))
Veja bem, se você tiver uma variável ou string aqui, tudo bem, mas se você escrever algo como isto:
(setq-every (my-function-with-side-effects) f-loc1 f-loc2)
Então sua função será chamada mais de uma vez. Isso pode ser indesejável. Aqui está como corrigi-lo com a ajuda de once-only(disponível no
pacote MMT ):
(defmacro setq-every (value &rest vars)
"Set every variable from VARS to value VALUE.
VALUE is only evaluated once."
(mmt-once-only (value)
`(progn ,@(mapcar (lambda (x) (list 'setq x value)) vars))))
E o problema se foi.