Question

il semble y avoir une limite au nombre de paramètres d'une fonction de Clojure peut prendre.

Lors de la définition d'une fonction de plus de 20 paramètres Je reçois le texte suivant:

#<CompilerException java.lang.RuntimeException: java.lang.RuntimeException: java.lang.Exception: Can't specify more than 20 params (NO_SOURCE_FILE:0) (NO_SOURCE_FILE:0)>

Il est évident que cela peut être évité, mais je frappais cette limite de portage du modèle d'exécution d'un DSL existant à Clojure, et j'ai construit assez facilement dans mon DSL comme ce qui suit, qui par l'expansion macro peut être mis en correspondance avec des fonctions à l'exception cette limite:

(defAlias nn1 ((element ?e1) (element ?e2)) number
"@doc features of the elements are calculated for entry into
      the first neural network, the result is the score computed by the latter"
(nn1-recall (nn1-feature00 ?e1 ?e2) (nn1-feature01 ?e1 ?e2) ... (nn1-feature89 ?e1 ?e2)))

qui est une instruction DSL pour appeler un réseau de neurones avec 90 nœuds d'entrée. Peut travailler autour d'elle bien sûr, mais je me demandais où la limite vient. Merci.

Était-ce utile?

La solution

Tout d'abord, la limite ne s'applique qu'aux arguments de position requis ; vous pouvez toujours utiliser le cas variable arité (& more-args dans la signature de la fonction) pour gérer autant d'arguments que vous voulez:

(defn foo [& args]
  (count args))

(foo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25)
;; returns 25

En fait, au premier coup d'œil, & args est susceptible d'être exactement la solution à votre problème. (Par exemple, vous serez en mesure de mapper une fonction sur vos noeuds d'entrée ont été recueillies dans une séquence, loop / recur sur ladite séquence, etc. - tend à faire plus de sens avec un grand nombre d'éléments similaires que l'attribution des noms distincts pour chacun des les.

(Notez que je ne prétends pas connaître la nature de la DSL spécifique que vous en transcrivant Clojure ou le genre de problèmes que vous avez affaire, suggérant que les points qui pourraient être vous intéresser si vous. avons eu une situation vraiment géniale où cela ne semble pas appliquer, peut-être vous pouvez fournir plus de détails et nous allons voir si quelqu'un ici peut offrir quelques conseils utiles pour traiter dans Clojure.)

Par souci d'exhaustivité, vous pouvez ajouter le bit & args à une fonction qui prend ses 19 premiers arguments args de position requis:

(defn bar [a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 & as]
  (+ 19 (count as)))

(bar 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25)
;; returns 25

Notez que si vous spécifiez 20 args de position et la arg & en plus de cela, apparemment bizarreries s'ensuivra.

En ce qui concerne les raisons, je crois que cela a à voir avec le fait que la machine virtuelle Java peut envoyer à une méthode arité très efficace, de sorte que la classe clojure.lang.Fn a la méthode de invoke surcharge pour arités jusqu'à 20. Je ne suis pas tout à fait que si elle pouvait aller plus haut que cela, mais je suppose que ce n'est pas quelque chose de gens exigent que souvent ... Je veux dire, je trouve certainement une API spécifiant plus de 20 arguments de position à une fonction un peu suspect.

Autres conseils

La réponse de Michal Marczyk vous dit très bien comment contourner la limite. Si vous êtes interressé dans la raison de cette limitation, vous voudrez peut-être jeter un coup d'oeil à ce morceau de source clojure: IFn

invocation étant une méthode surchargée java mis en oeuvre par l'interface Ifn, Rich surcharge pour prendre en charge jusqu'à 20 arguments. Lorsque vous appelez une fonction dans Clojure, les appels de mise en œuvre sous-jacente Invoke sur l'objet de fonction, une méthode qui prend en charge que jusqu'à 20 args.

Vous pourriez surcharger pour soutenir plus, mais je doute de l'utilité de chose telle. Si vous avez un tas de sources d'entrée, ils peuvent probablement être traités comme un tableau de toute façon.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top