Okunabilir Clojure Kodu nasıl yazılır?


13

Clojure'da yeniyim. Yazdığım kodu anlayabiliyorum ama daha sonra anlamak çok zor oluyor.
Parantezleri eşleştirmek zorlaşır.

Çeşitli durumlarda adlandırma kuralları ve girinti konusunda izlenecek genel kurallar nelerdir?

Örneğin anlamak için örnek bir yapılanma örneği yazdım ama ikinci kez tamamen okunamaz görünüyor.

(defn f [{x :x y :y z :z [a b c] :coll}] (print x " " y  " " z " " a " " b " " c)) 

Yapılandırmanın kaldırılması durumunda, bunu doğrudan parametre düzeyinde yapmak veya izin formunu başlatmak ve sonra devam etmek daha mı iyi?


3
Stack Overflow'da okunabilirlik hakkında iyi bir cevap var. Kontrol edebilirsiniz. stackoverflow.com/a/1894891/1969106
yfklon

2
Okunabilir Lisp kodu yazmak genel olarak zordur. Bir sebepten ötürü "Kaybolan Parantezde Kaybedildi" backronimini icat ettiler.
Mason Wheeler

Yanıtlar:


23

Adlandırma kuralları

  • işlevler için küçük harfte kal
  • -tireleme için kullanın (diğer dillerde alt çizgi veya deve örneği).

    (defn add-one [i] (inc i))

  • ? Örneklerle sonunu (yani, doğru veya yanlış döndüren işlevleri) tahmin eder:odd? even? nil? empty?

  • Devlet değiştirme prosedürleri sona eriyor !. Hatırladın set!değil mi? veyaswap!

  • Erişimlerine bağlı olarak kısa değişken adı uzunlukları seçin. Bu, gerçekten küçük bir yardımcı değişkeniniz varsa, genellikle tek harfli bir ad kullanabilirsiniz. (map (fn [[k v]] (inc v)) {:test 4 :blub 5})özellikle çok sayıda kod satırı için kullanılıyorsa ve amaçlarını hemen tahmin edemiyorsanız, gerektiğinde daha uzun değişken adları seçin. (benim fikrim).

    Birçok clojure programcısının jenerik ve kısa isimler kullanmaya eğilimli olduğunu hissediyorum. Ancak bu elbette nesnel bir gözlem değildir. Mesele şu ki, bir çok clojure fonksiyonu aslında oldukça geneldir.

Lambda fonksiyonları

  • Aslında lambda işlevlerini adlandırabilirsiniz. Bu hata ayıklama ve profil oluşturma için uygundur (buradaki deneyimim ClojureScript ile).

    (fn square-em [[k v]] {k (* v v)})

  • Satır içi lambda işlevlerini #()uygun olarak kullanın

Beyaz boşluk

  • Yalnızca ebeveynler satırları olmamalıdır. Parantezleri hemen kapatın. Unutmayın parens editör ve derleyici için orada, girinti sizin için.

  • İşlev parametre listeleri yeni bir satıra gider

   (defn eksileri
     [Ab]
     (ab listesi))

Eğer doktor dizelerini düşünürseniz bu mantıklıdır. Fonksiyon adı ile parametreler arasındadır. Aşağıdaki doc dizesi muhtemelen en akıllısı değildir;)

   (defn eksileri
     "Bir şeyleri eşleştirmek"
     [Ab]
     (ab listesi))
  • Eşleştirilen veriler, eşleştirmeyi koruduğunuz sürece yeni bir satırla ayrılabilir
  (defn f 
    [{x: x 
      y: y 
      z: z  
      [abc]: coll}] 
    (x "" y "" z "" a "" b "" c'yi yazdırın)) 

(İstediğiniz ,gibi girebilirsiniz , ancak bu mantıksız geliyor).

  • Girinti için yeterince iyi bir editör kullanın. Yıllar önce bu lisp düzenleme için emacs, vim bugün de harika. Tipik clojure IDE'ler de bu işlevselliği sağlamalıdır. Sadece rastgele bir metin editörü kullanmayın.

    Vim'de komut kipinde =düzgün girintilemek için komutu kullanabilirsiniz .

  • Komut çok uzun olursa (iç içe geçmiş vb.), İlk bağımsız değişkenden sonra yeni satır ekleyebilirsiniz. Şimdi aşağıdaki kod oldukça anlamsızdır, ancak ifadeleri nasıl gruplayabileceğiniz ve girintileyebileceğinizi gösterir:

(+ (if-let [yaş (: kişisel yaş grubu)]
     (eğer (> 18 yaş)
       yaş
       0))
   (sayım (aralık (- 3 b))
                 (azalt + 
                         (aralık 10, 10)))))

İyi girinti, parantez saymanız gerekmediği anlamına gelir. Köşeli ayraçlar bilgisayar içindir (kaynak kodunu yorumlamak ve girintilemek için). Girinti kolay anlaşılması içindir.

Yüksek mertebeden fonksiyonlar forve doseqformlar

Bir Şema arka planından gelince, anladım mapve lambda işlevlerini vb.Ile gurur duydum.

(map (fn [[k x]] (+ x (k data))) {:a 10 :b 20 :c 30})

Bunu okumak oldukça zor. forForm yolu daha güzel:

(for [[k x] {:a 10 :b 20 :c30}]
  (+ x (k data)))

`haritanın bir çok kullanımı vardır ve adlandırılmış işlevler kullanıyorsanız gerçekten güzel. yani

(map inc [12 30 10]

(map count [[10 20 23] [1 2 3 4 5] (range 5)])

İş Parçacığı makrolarını kullanma

Diş makroları kullanın ->ve ->>aynı zamanda dotone zaman uygulanabilir.

Burada önemli olan nokta, iş parçacığı makrolarının kaynak kodunu işlev kompozisyonundan daha doğrusal göstermesidir. Aşağıdaki kod parçası, iş parçacığı makrosu olmadan oldukça okunamıyor:

   (f (g (h 3) 10) [10 3 2 3])

ile karşılaştırmak

   (-> 
     (h 3)
     (g 10)
     (f [10 3 2 3]))

İş parçacığı makrosu kullanarak, genellikle yalnızca bir kez kullanılan geçici değişkenler girmekten kaçınılabilir.

Diğer şeyler

  • Dokümanları kullan
  • işlevleri kısa tut
  • diğer clojure kodunu oku

Yapılandırmayla bu işlev girinti ile güzel görünüyor!
Amogh Talpallikar

Kısa fonksiyonlar için +1. Çok sayıda küçük işlev çok daha fazla kendi kendini belgeliyor
Daniel Gratzer

1
Ben kuvvetle bile "kısa erimli" fonksiyonlarda, kısa değişken isimleri kullanmak iyi bir fikir olduğunu katılmıyorum. İyi değişken adları okunabilirlik için kritik öneme sahiptir ve tuş vuruşları dışında hiçbir maliyeti yoktur. Bu, Clojure topluluğu hakkında beni en çok rahatsız eden şeylerden biri. Açıklayıcı değişken isimlerine neredeyse düşmanca direnç gösteren birçok insan var. Clojure çekirdeği, işlev bağımsız değişkenleri için 1 harfli değişken adlarıyla doludur ve bu, dili öğrenmeyi çok daha zorlaştırır (örneğin, çalışan docveya sourcebir REPL'de). Aksi halde mükemmel bir cevap için rant sonu
Nathan Wallace

@NathanWallace Bir şekilde sana katılıyorum, ama bazı açılardan anlamıyorum. Uzun isimler bazen işlevleri aşırı özel hale getirme eğilimindedir. Yani bazı genel filtre işlemlerinin aslında genel olduğunu, applesbunun yerine argüman yerine xselmalara özgü olduğunu düşündüğünüzü görebilirsiniz. Sonra, ayrıca işlev bağımsız değişken adları let-say bir for döngüsü değişkeni daha ulaşan olarak kabul ediyorum. yani gerekirse, daha uzun olabilir. Son bir düşünce olarak: Sizi "İsim kodu değerleri değil" olarak bırakacağım concatenative.org/wiki/view/Concatenative%20language/…
wirrbel

Özel ve genel arayüzler gibi bir şeye paragraf ekleyebilirim. Özellikle kütüphanelerle ilgili. Kod kalitesinin yeterince konuşulmayan bir yönü ve bu cevabı yazdığından beri tonlarca şey öğrendim.
wirrbel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.