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. fore doseqmoduli
Provenendo da un background di Scheme ero piuttosto orgoglioso di aver capito mape 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 formodulo è 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 dotoquando 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