Convenzioni di denominazione
- resta in minuscolo per le funzioni
-
usa -
per la sillabazione (quale sarebbe underscore o caso cammello in altre lingue).
(defn add-one
[i]
(inc i))
-
I predicati (ovvero le funzioni che restituiscono true o false) terminano con ?
Esempi: odd?
even?
nil?
empty?
-
Le procedure di modifica dello stato terminano in !
. Ti ricordi set!
giusto? o swap!
-
Scegli lunghezze dei nomi delle variabili brevi in base alla loro portata. Ciò significa che se si dispone di una variabile ausiliaria molto piccola è spesso possibile utilizzare solo un nome di una sola lettera. (map (fn [[k v]] (inc v)) {:test 4 :blub 5})
sceglie nomi di variabile più lunghi secondo necessità, specialmente se sono usati per molte linee di codice e non è possibile indovinarne immediatamente lo scopo. (la mia opinione).
Ritengo che molti programmatori di clojure tendano piuttosto a usare nomi generici e abbreviati. Ma ovviamente non è un'osservazione oggettiva. Il punto è che molte funzioni del clojure sono in realtà piuttosto generiche.
- Usa nomi significativi. Le procedure stanno facendo qualcosa, quindi puoi descriverli al meglio usando i verbi. Le funzioni built-in di Clojure dovrebbero metterti sulla giusta traccia:
drop
, take
, assoc
, ecc. Poi c'è un bell'articolo che descrive i modi per scegliere un nome significativo: link
Funzioni Lambda
-
In realtà puoi nominare le funzioni lambda. Questo è conveniente per il debugging e la profilazione (la mia esperienza qui è con ClojureScript).
(fn square-em [[k v]] {k (* v v)})
-
Usa le funzioni lambda in linea #()
come conveniente
Whitespace
-
Non ci dovrebbero essere linee parens-only. Cioè chiudi subito le parentesi. Ricorda che ci sono i parens per l'editor e il compilatore, il rientro è per te.
-
Gli elenchi dei parametri delle funzioni vanno su una nuova riga
(defn cons
[a b]
(list a b))
Questo ha senso se pensi alle stringhe doc. Sono tra il nome della funzione e i parametri. La seguente stringa doc probabilmente non è la più saggia;)
(defn cons
"Pairing up things"
[a b]
(list a b))
- I dati accoppiati possono essere separati da una nuova riga se si mantiene l'associazione
(defn f
[{x :x
y :y
z :z
[a b c] :coll}]
(print x " " y " " z " " a " " b " " c))
(Puoi anche inserire ,
come preferisci, ma questo non sembra lelo).
-
Per indentazione usa un editor sufficientemente buono. Anni fa questo è stato emac per un editor nitido, anche oggi è fantastico. Anche gli IDE dei clojure tipici dovrebbero fornire questa funzionalità. Basta non usare un editor di testo casuale.
In vim in modalità comando puoi usare il comando =
per indentare correttamente.
-
Se il comando diventa troppo lungo (annidato, ecc.) è possibile inserire una nuova riga dopo il primo argomento. Ora il seguente codice è piuttosto insensato ma illustra come puoi raggruppare e indentare espressioni:
(+ (if-let [age (:personal-age coll)]
(if (> age 18)
age
0))
(count (range (- 3 b)
(reduce +
(range b 10)))))
Una buona indentazione significa che non devi contare le parentesi. Le parentesi sono per il computer (per interpretare il codice sorgente e per indentarlo). La rientranza è per tua comprensione.
Funzioni di ordine superiore rispetto a for
e doseq
moduli
Provenendo da uno sfondo di Scheme ero piuttosto orgoglioso di aver capito map
e funzioni lambda, ecc. Quindi abbastanza spesso, scriverei qualcosa di simile
(map (fn [[k x]] (+ x (k data))) {:a 10 :b 20 :c 30})
Questo è piuttosto difficile da leggere. La forma for
è molto più bella:
(for [[k x] {:a 10 :b 20 :c30}]
(+ x (k data)))
La
'mappa ha molti usi ed è davvero bella se usi le funzioni con nome. Cioè.
(map inc [12 30 10]
(map count [[10 20 23] [1 2 3 4 5] (range 5)])
Utilizza macro di threading
Utilizza le macro di threading ->
e ->>
e doto
quando applicabile.
Il punto è che le macro di threading rendono il codice sorgente più lineare della composizione della funzione. La seguente parte di codice è piuttosto illeggibile senza la macro di threading:
(f (g (h 3) 10) [10 3 2 3])
confronta con
(->
(h 3)
(g 10)
(f [10 3 2 3]))
Usando la macro di threading, si può in genere evitare di introdurre variabili temporanee che vengono utilizzate solo una volta.
Altre cose
- Utilizza le docstring
- mantieni le funzioni in breve
- leggi altro codice clojure