50 votes

Pourquoi devrais-je utiliser "appliquer" en Clojure?

C'est ce que Rich Hickey a dit dans un des articles de blog, mais je ne comprends pas la motivation dans l'utilisation de l'appliquer. S'il vous plaît aider.

Une grande différence entre Clojure et CL est que Clojure est un Lisp-1, de sorte funcall n'est pas nécessaire, et de les appliquer est seulement utilisé pour appliquer une fonction à une exécution de collecte définis d'arguments. Donc, (application de f [i]) peut être écrit f i).

Aussi, que veut-il dire par "Clojure est Lisp-1" et funcall n'est pas nécessaire? Je n'ai jamais programmé en CL.

Merci

58voto

Dirk Points 17809

Vous utilisez appliquer, si le nombre d'arguments à passer à la fonction n'est pas connue au moment de la compilation (désolé, je ne sais pas Clojure syntaxe de tout ce que le bien, le recours au Régime):

(define (call-other-1 func arg) (func arg))
(define (call-other-2 func arg1 arg2) (func arg1 arg2))

Tant que le nombre d'arguments est connu au moment de la compilation, vous pouvez passer directement comme c'est fait dans l'exemple ci-dessus. Mais si le nombre d'arguments n'est pas connu au moment de la compilation, vous ne pouvez pas le faire (eh bien, vous pourriez essayer quelque chose de semblable):

(define (call-other-n func . args)
   (case (length args)
      ((0) (other))
      ((1) (other (car args)))
      ((2) (other (car args) (cadr args)))
      ...))

mais que devient un cauchemar assez vite. C'est là que s'appliquent entre l'image:

(define (call-other-n func . args)
   (apply other args))

Il faut que le nombre d'arguments, qui sont contenues dans la liste donnée en dernier argument, et appelle la fonction passée en tant que premier argument s'applique avec ces valeurs.

43voto

Chuck Points 138930

Les termes Lisp-1 et Lisp 2 voir si les fonctions sont dans le même espace de noms de variables.

Dans un Lisp-2 (qui est, 2 espaces de noms), le premier élément d'un formulaire sera évalué comme un nom de fonction - même si c'est en fait le nom d'une variable avec une valeur de la fonction. Donc, si vous voulez appeler une variable de fonction, vous avez à passer la variable à une autre fonction.

Dans un Lisp-1, comme le Régime et Clojure, les variables qui permettent d'évaluer les fonctions peuvent aller dans la position initiale, de sorte que vous n'avez pas besoin d'utiliser apply afin de l'évaluer en fonction.

37voto

Rayne Points 14518

apply essentiellement déballe une séquence et applique la fonction à eux comme à des arguments personnels.

Voici un exemple:

(apply + [1 2 3 4 5])

Qui renvoie à 15. Essentiellement, il s'étend à d' (+ 1 2 3 4 5), au lieu de (+ [1 2 3 4 5]).

9voto

Thumbnail Points 2615

Vous utilisez apply convertir une fonction qui fonctionne sur plusieurs arguments pour celui qui travaille sur une seule séquence d'arguments. Vous pouvez également insérer des arguments avant la séquence de. Par exemple, map pouvez travailler sur plusieurs séquences. Cet exemple (à partir de ClojureDocs) utilise map - transposition d'une matrice.

user=> (apply map vector [[:a :b] [:c :d]])
([:a :c] [:b :d])

L'on insère ici, l'argumentation est - vector. Si l' apply se développe pour

user=> (map vector [:a :b] [:c :d])

Mignon!

PS Pour retourner un vecteur de vecteurs au lieu d'une séquence de vecteurs, envelopper le tout dans vec:

user=> (vec (apply map vector [[:a :b] [:c :d]]))

Alors que nous sommes ici, en vec pourrait être défini comme (partial apply vector), si elle n'est pas.

Concernant Lisp-1 et Lisp-2: les 1 et 2 indiquent le nombre de choses qu'un nom peut désigner dans un contexte donné. Dans un Lisp-2, vous pouvez avoir deux choses différentes (une fonction et une variable du même nom. Ainsi, où que ce soit peut-être valable, vous avez besoin pour décorer votre programme avec quelque chose pour indiquer que vous voulez dire. Heureusement, Clojure (ou Régime ...) permet à un nom pour désigner une seule chose, donc pas de décors qui sont nécessaires.

4voto

Steve Gilham Points 7829

Le schéma habituel pour appliquer des opérations de type est de combiner une fonction fournie au moment de l'exécution avec un ensemble d'arguments, idem.

Je n'ai pas fait assez avec clojure pour être en mesure de faire confiance sur les subtilités de cette langue en particulier, de savoir si l'utilisation de l'appliquer dans ce cas serait strictement nécessaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X