binding - Argumentos de palabras clave Clojure
lisp common-lisp (3)
Para actualizar esta respuesta para Clojure 1.2, ahora existe un soporte completo de argumentos de palabras clave con valores predeterminados proporcionados por las formas de mapa de desestructuración vinculante
user> (defn foo [bar &{ :keys [baz quux]
:or {baz "baz_default" quux "quux_default"}}]
(list bar baz quux))
#''user/foo
user> (foo 1 :quux 3)
(1 "baz_default" 3)
En Common Lisp puedes hacer esto:
(defun foo (bar &key baz quux)
(list bar baz quux))
(foo 1 :quux 3 :baz 2) ; => (1 2 3)
Clojure no tiene argumentos de palabras clave. Una alternativa es esta:
(defn foo [bar {:keys [baz quux]}]
(list bar baz quux))
(foo 1 {:quux 3 :baz 2}) ; => (1 2 3)
Son demasiados paréntesis anidados para tener que escribir y leer todo el tiempo. También requiere que un hash-map explícito se pase como un argumento en lugar de una lista plana.
¿Cuál es el equivalente idiomático de Clojure a los argumentos de palabras clave que no parecen que alguien haya disparado una bomba de puntuación?
Una adición reciente a clojure.contrib.def
es la macro defnk
, que permite la definición de funciones con argumentos de palabras clave (consulte here ).
Una forma sencilla de simular argumentos de palabras clave en clojure es usar hash-map en parámetros de descanso como este:
> (defn kwtest [x & e] (:foo (apply hash-map e)))
#''user/kwtest
> (kwtest 12 :bar "ignored" :foo "returned")
"returned"
Rich Hickey proporcionó una macro en este mensaje del grupo de google clojure que le da los parámetros de palabras clave. El hilo correspondiente contiene información sobre por qué los parámetros de palabras clave no son compatibles con clojure. Básicamente para evitar los gastos generales de ejecución. Rich explica el método que he mostrado anteriormente en este mensaje.