Convenzioni di denominazione
- rimanere in minuscolo per le funzioni
utilizzare -
per la sillabazione (quale sarebbe il trattino basso o il caso del cammello in altre lingue).
(defn add-one
[i]
(inc i))
I predicati (ovvero le funzioni che restituiscono vero o falso) terminano con ?
esempi:odd?
even?
nil?
empty?
Le procedure per il cambio di stato finiscono in !
. Ti ricordi set!
giusto? oswap!
Scegli lunghezze di nomi variabili brevi a seconda della loro portata. Ciò significa che se si dispone di una variabile ausiliaria davvero piccola, spesso è possibile utilizzare semplicemente un nome di una lettera. (map (fn [[k v]] (inc v)) {:test 4 :blub 5})
scegli nomi di variabili più lunghi in base alle esigenze, soprattutto se utilizzati per molte righe di codice e non puoi indovinarne immediatamente lo scopo. (la mia opinione).
Sento che molti programmatori di clojure tendono piuttosto a usare nomi generici e brevi. Ma questa non è ovviamente un'osservazione obiettiva. Il punto è che molte funzioni di clojure sono in realtà piuttosto generiche.
Funzioni lambda
Puoi effettivamente nominare le funzioni lambda. Questo è utile per il debug e la profilazione (la mia esperienza qui è con ClojureScript).
(fn square-em [[k v]] {k (* v v)})
Utilizzare le funzioni lambda in linea nel modo #()
più comodo
Lo spazio bianco
Non dovrebbero esserci righe solo per parentesi. Vale a dire chiudere subito le parentesi. Ricorda che le parentesi ci sono per editor e compilatore, il rientro è per te.
Gli elenchi dei parametri delle funzioni vanno su una nuova riga
(defn cons
[AB]
(elenco ab))
Questo ha senso se pensi alle stringhe di documenti. Sono tra il nome della funzione e i parametri. La seguente stringa doc non è probabilmente la più saggia;)
(defn cons
"Abbinamento delle cose"
[AB]
(elenco ab))
- I dati accoppiati possono essere separati da una nuova riga purché si mantenga l'associazione
(defn f
[{x: x
y: y
z: z
[abc]: coll}]
(stampa x "" y "" z "" a "" b "" c))
(Puoi anche entrare ,
come preferisci, ma sembra poco lusinghiero).
Per il rientro utilizzare un editor sufficientemente buono. Anni fa questo era emacs per l'editing lisp, anche oggi vim è fantastico. Anche gli IDE di clojure tipici dovrebbero fornire questa funzionalità. Basta non usare un editor di testo casuale.
In vim in modalità comando è possibile utilizzare il =
comando per rientrare correttamente.
Se il comando diventa troppo lungo (nidificato, ecc.) È possibile inserire una nuova riga dopo il primo argomento. Ora il seguente codice è piuttosto insensato ma illustra come è possibile raggruppare e indentare le espressioni:
(+ (if-let [age (: personal-age coll)]
(se (> 18 anni)
età
0))
(conta (intervallo (- 3 b)
(riduci +
(intervallo b 10)))))
Un buon rientro significa che non è necessario contare le parentesi. Le parentesi sono per il computer (per interpretare il codice sorgente e per rientrarlo). Il rientro è per la tua facile comprensione.
Funzioni di ordine superiore vs. for
e doseq
moduli
Provenendo da un background di Scheme ero piuttosto orgoglioso di aver capito map
e funzioni lambda, ecc. Molto spesso, scrivevo qualcosa del genere
(map (fn [[k x]] (+ x (k data))) {:a 10 :b 20 :c 30})
Questo è abbastanza difficile da leggere. Il for
modulo è molto più bello:
(for [[k x] {:a 10 :b 20 :c30}]
(+ x (k data)))
`map ha molti usi ed è davvero bello se stai usando funzioni con nome. ie
(map inc [12 30 10]
(map count [[10 20 23] [1 2 3 4 5] (range 5)])
Usa le macro di threading
Utilizzare le macro di threading ->
e ->>
anche doto
quando applicabile.
Il punto è che le macro di threading rendono il codice sorgente più lineare della composizione della funzione. Il seguente pezzo di codice è piuttosto illeggibile senza la macro threading:
(f (g (h 3) 10) [10 3 2 3])
confrontare con
(->
(h 3)
(g 10)
(f [10 3 2 3]))
Utilizzando la macro threading, si può in genere evitare di introdurre variabili temporanee che vengono utilizzate una sola volta.
Altre cose
- Usa dotstrings
- mantenere le funzioni brevi
- leggi altro codice clojure