Arguments Clojure

En Common Lisp, vous pouvez le faire:

(defun foo (bar &key baz quux) (list bar baz quux)) (foo 1 :quux 3 :baz 2) ; => (1 2 3) 

Clojure n’a pas d’arguments de mots clés. Une alternative est la suivante:

 (defn foo [bar {:keys [baz quux]}] (list bar baz quux)) (foo 1 {:quux 3 :baz 2}) ; => (1 2 3) 

C’est trop de crochets nesteds à saisir et à lire tout le temps. Il faut également qu’un hachage explicite soit transmis sous forme d’argument plutôt que de liste plate.

Quel est l’équivalent de Clojure le plus idiomatique des arguments de mots-clés qui n’ont pas l’air de déclencher une bombe de ponctuation?

Un moyen simple de simuler des mots-clés args en clojure consiste à utiliser une table de hachage sur des parameters de repos comme celui-ci:

 > (defn kwtest [x & e] (:foo (apply hash-map e))) #'user/kwtest > (kwtest 12 :bar "ignored" :foo "returned") "returned" 

Rich Hickey a fourni une macro dans ce message du groupe gojure clojure qui vous donne des parameters de mots clés. Le thread correspondant contient des informations sur la raison pour laquelle les parameters de mot-clé ne sont pas pris en charge par clojure. Fondamentalement, pour éviter la surcharge d’exécution. Rich explique la méthode que j’ai montré ci-dessus dans ce message

Pour mettre à jour cette réponse pour Clojure 1.2, il existe maintenant un support d’argument de mot clé complet avec les valeurs par défaut fournies par les formes de carte de liaison de déstructuration :

 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) 

Un ajout récent à clojure.consortingb.def est la macro defnk , qui permet de définir des fonctions avec des arguments de mots-clés (voir ici ).