Ceci n'est pas une réponse à votre question, mais dans l'intérêt de l'écriture de "gentil" code clojure, je voulais souligner quelques points avec votre exemple.
Un des avantages du style fonctionnel est la possibilité de composer des fonctions ensemble. Mais si vous jetez un coup d'œil aux fonctions que vous avez écrites, elles ne font pas grand-chose individuellement, selon les fonctionnalités fournies ailleurs.
Par exemple, stream-builder
renvoie simplement une liste de deux éléments de n
et une fonction anonyme pour gérer la pseudo-récursivité. Je suppose que vous essayiez d'opter pour une séquence fainéante, mais cela nécessite des fonctions de support qui sont conscientes des détails d'implémentation pour réaliser l'élément suivant, à savoir stream
et second$
. Heureusement, vous pouvez à la place l'accomplir comme suit:
(defn stream-builder [f x] ; f is idiomatic for a function arg
(lazy-seq ; n is idiomatic for a count, so use x instead
(cons x
(stream-builder f (f x)))))
Le retourneront au-dessus d'une suite infinie de valeurs, nous avons donc besoin de tirer le comportement limite qui est empaqueté dans stream
:
(defn limit [n coll] ; coll is idiomatic for a collection arg
(lazy-seq ; flipped order, fns that work on seqs usually take the seq last
(when (pos? n)
(when-let [s (seq coll)]
(cons (first s)
(limit (dec n) (next s)))))))
ci-dessus se paresseusement revenir jusqu'à n
éléments de coll
:
user=> (limit 5 (stream-builder inc 1))
(1 2 3 4 5)
À la fin, chaque fonction fait une chose bien, et est composable avec d'autres fonctions:
Enfin, vous avez défini odd
comme la séquence paresseuse des entiers impairs. Le danger est que cette séquence reste collée au fur et à mesure de sa réalisation (c'est ce qu'on appelle «se tenir sur la tête» d'une séquence). Cela peut prendre inutilement de la mémoire en trop pour tenir sur chaque élément jamais réalisé, et empêche la récupération de place.
Pour résoudre ce problème, soit ne déf pas la séquence paresseux, ou def avec la limite, par exemple:
(def odds (limit 23 (stream-builder #(+ 2 %) 1)))
Pour référence ultérieure, ce que nous venons d'écrire est disponible dans le répertoire lib de base comme iterate
et take
, respectivement:
user=> (take 5 (iterate inc 1))
(1 2 3 4 5)
Je ne suis pas sûr de ce que vous demandez. On dirait que vous avez déjà trouvé 3 noms pour cela. Qu'est-ce qui, selon vous, rendrait une réponse plus "correcte" que n'importe quel autre de ces synonymes? – Ken