Je suis nouveau à Clojure. Je peux comprendre le code que j'écris mais il devient trop difficile de le comprendre plus tard.
Il devient difficile de faire correspondre les parenthèses.
Quelles sont les conventions génériques à suivre concernant les conventions de dénomination et l'indentation dans diverses situations?
Par exemple, j'ai écrit un exemple d'exemple de déstructuration pour comprendre, mais il semble complètement illisible la deuxième fois.
(defn f [{x :x y :y z :z [a b c] :coll}] (print x " " y " " z " " a " " b " " c))
En cas de déstructuration, vaut-il mieux le faire directement au niveau des paramètres ou démarrer une forme let puis continuer là?
readability
clojure
Amogh Talpallikar
la source
la source
Réponses:
Conventions de nommage
utiliser
-
pour la césure (ce qui serait souligné ou cas de chameau dans d'autres langues).(defn add-one [i] (inc i))
Les prédicats (c'est-à-dire les fonctions renvoyant vrai ou faux) se terminent par des
?
exemples:odd?
even?
nil?
empty?
Fin des procédures de changement d'état
!
. Tu te souviensset!
non? ouswap!
Choisissez de courtes longueurs de noms variables en fonction de leur portée. Cela signifie que si vous avez une très petite variable auxiliaire, vous pouvez souvent simplement utiliser un nom à une lettre.
(map (fn [[k v]] (inc v)) {:test 4 :blub 5})
choisissez des noms de variable plus longs selon les besoins, surtout s'ils sont utilisés pour de nombreuses lignes de code et que vous ne pouvez pas immédiatement deviner leur fonction. (mon avis).Je pense que beaucoup de programmeurs clojure ont plutôt tendance à utiliser des noms génériques et courts. Mais ce n'est bien sûr pas vraiment une observation objective. Le fait est que beaucoup de fonctions clojure sont en fait assez génériques.
drop
,take
,assoc
, etc. Ensuite , il y a un article qui décrit bien des façons de choisir un nom significatif: http://ecmendenhall.github.io/blog/blog/2013/09/ 02 / nettoyer-clojure-noms-significatifs /Fonctions lambda
Vous pouvez en fait nommer des fonctions lambda. C'est pratique pour le débogage et le profilage (mon expérience ici est avec ClojureScript).
(fn square-em [[k v]] {k (* v v)})
Utilisez les fonctions lambda en ligne
#()
comme pratiqueEspace blanc
Il ne doit pas y avoir de lignes parens. C'est à dire fermer les parenthèses tout de suite. N'oubliez pas que les parens sont là pour l'éditeur et le compilateur, l'indentation est pour vous.
Les listes de paramètres de fonction vont sur une nouvelle ligne
Cela a du sens si vous pensez aux chaînes doc. Ils se situent entre le nom de la fonction et les paramètres. La chaîne de doc suivante n'est probablement pas la plus sage;)
(Vous pouvez également entrer
,
comme vous le souhaitez, mais cela ne vous parait pas trop).Pour l'indentation, utilisez un éditeur suffisamment bon. Il y a des années, c'était emacs pour une édition nette, vim est également génial aujourd'hui. Les IDE clojure typiques devraient également fournir cette fonctionnalité. N'utilisez simplement pas un éditeur de texte aléatoire.
Dans vim en mode commande, vous pouvez utiliser la
=
commande pour mettre correctement en retrait.Si la commande est trop longue (imbriquée, etc.), vous pouvez insérer une nouvelle ligne après le premier argument. Maintenant, le code suivant est assez insensé mais il illustre comment vous pouvez grouper et mettre en retrait des expressions:
Une bonne indentation signifie que vous n'avez pas à compter les parenthèses. Les crochets sont destinés à l'ordinateur (pour interpréter le code source et le mettre en retrait). L'indentation est pour votre compréhension facile.
Fonctions d'ordre supérieur
for
etdoseq
formesVenant d'un arrière-plan Scheme, j'étais assez fier d'avoir compris
map
les fonctions lambda, etc. Donc, très souvent, j'écrivais quelque chose comme ça(map (fn [[k x]] (+ x (k data))) {:a 10 :b 20 :c 30})
C'est assez difficile à lire. Le
for
formulaire est bien plus agréable:`map a beaucoup d'utilisations et est vraiment sympa si vous utilisez des fonctions nommées. C'est à dire
Utiliser des macros de thread
Utilisez les macros de thread
->
et->>
ainsi que ledoto
cas échéant.Le fait est que les macros de threading font apparaître le code source plus linéaire que la composition de fonction. Le morceau de code suivant est assez illisible sans la macro de thread:
comparer avec
En utilisant la macro de threading, on peut généralement éviter d'introduire des variables temporaires qui ne sont utilisées qu'une seule fois.
Autres choses
la source
doc
ousource
dans un REPL). Fin de diatribe, pour une réponse par ailleurs excellenteapples
place dexs
, vous pensiez qu'il était spécifique aux pommes. Ensuite, je considérerais également que les noms d'arguments de fonction sont plus étendus que, disons, une variable de boucle for. donc si besoin, vous pouvez les avoir plus longtemps. Une dernière pensée: je vous laisse avec "Nom du code et non des valeurs" concatenative.org/wiki/view/Concatenative%20language/…