Clojure protokolleri basit bir açıklaması
Çözmek için gereken ne clojure protokoller ve anlamaya çalışıyorum. Herkes clojure protokol nedir ve neden net bir açıklama var mı?
CEVAP
Clojure Protokolleri amacı, etkin bir şekilde İfade Sorunu çözmek için.
İfade Sorunu ne? Uzama temel sorunu ifade eder: programlarımız işlemleri kullanarak. veri türlerini işlemek Bizim programları geliştikçe, yeni veri türleri ve yeni işlemler ile genişletmeye ihtiyacımız var. Ve özellikle de, varolan veri türleriyle çalışmak olan yeni bir işlem eklemek mümkün olmak istiyorum, ve mevcut operasyonları ile çalışan yeni veri türleri eklemek istiyoruz.Vebunun doğru olmasını istiyoruzuzantısıyani değiştirmek istemiyoruzmevcutprogram, mevcut soyutlamalar saygı istiyoruz, bizim uzantıları modülleri ayrı, ayrı ad ayrı ayrı derlenmiş olmak istiyoruz, ayrı olarak dağıtılan, ayrı ayrı tip kontrol etti. Onları tür-güvenli olmasını istiyoruz. [Not: tüm dillerde anlamı bu değil. Ama, örneğin, onları güvende türü-gol bile Clojure gibi bir dilde mantıklı. Sadece edemeyiz statik olarak çünkükontrol edintip-güvenlik kodu rastgele sağa kır istiyoruz anlamına gelmiyor mu?]
İfade Sorunu, aslında nasıl bir dil böyle kullanildigini sağlıyor musunuz?
Bu çıkıyor tipik saf uygulamalarının usul ve/veya işlevsel programlama, çok kolay Ekle yeni işlemler (prosedürler, fonksiyonlar), ama çok zor eklemek yeni veri türleri, beri temelde işlemleri ile veri türlerini kullanarak bir çeşit dava ayrımcılık (switch
, case
, desen eşleştirme) ve ihtiyacınız Ekle yeni vaka için onları, yani değiştirmek varolan kodu:
func print(node):
case node of:
AddOperator => print(node.left) ' ' print(node.right)
NotOperator => '!' print(node)
func eval(node):
case node of:
AddOperator => eval(node.left) eval(node.right)
NotOperator => !eval(node)
Şimdi, Eğer eklemek istediğiniz bir yeni operasyon, diyelim ki, bir tür denetleme, bu çok kolay bir şey, ama eğer eklemek istediğiniz yeni bir düğüm türü, değiştir tüm mevcut desen eşleştirme ifadelerde tüm işlemler.
Ve tipik saf OO, tam tersi sorun: kolay eklemek yeni veri türleri olan çalışma ile mevcut faaliyetler (ya da devralma ya da onları geçersiz kılma), ama yapmak zordur add new işlemleri, beri anlamına gelir değiştirerek mevcut sınıfları/nesneleri.
class AddOperator(left: Node, right: Node) < Node:
meth print:
left.print ' ' right.print
meth eval
left.eval right.eval
class NotOperator(expr: Node) < Node:
meth print:
'!' expr.print
meth eval
!expr.eval
Burada, ekleyerek yeni bir düğüm türü kolaydır, çünkü ya da miras, geçersiz veya uygulamak için gerekli tüm işlemleri, ama ekleyerek yeni bir operasyon zor, çünkü ihtiyacın eklemek ya da tüm yaprak sınıf ya da bir temel sınıf, böylece değiştirme kodu mevcut.
Birçok dilde İfade Sorunu çözmek için çeşitli yapıları var: Haskell örtük değişkenleri vardır, Raket Birimleri var, Git Arayüzleri, CLOS ve Clojure var Multimethods vardır Scala typeclasses vardır. Orada da "çözümler"girişimibunu çözmek için, ama öyle ya da böyle başarısız: Arabirimleri ve yayım Yöntemleri C# ve Java, Ruby, Python, ECMA içinde Monkeypatching.
Aslında zaten Clojure unutmayınvardırİfade Sorunu çözmek için bir mekanizma: Multimethods. O OO AP ile sorun onlar işlemleri ve türleri bir arada paket. Multimethods ayrı. Bu FP var asıl sorun operasyon paket ve vaka ayrımı ile birlikte. Yine Multimethods ayrı.
Hadi ikimiz de aynı şeyi yapmak beri Multimethods ile Protokol karşılaştırın. Protokoller zaten biz Neden . ya da, daha açık bir ifadeyle: ^em>varMultimethods?
Protokoller Multimethods üzerinden teklif Gruplama ana şey: birden fazla fonksiyonu birlikte grup ve de ki "bu 3 fonksiyonlarıbirlikteFoo
Protokol formu". Olamaz Multimethods ile yaparlar, her zaman kendi üzerinde durmak. Örneğin, Stack
bir Protokol oluşan bildirebilirsinizher ikisi depush
pop
bir fonksiyonbirlikte.
Neden sadece grup Multimethods yeteneği birlikte yapmıyorsunuz? Tamamen pragmatik bir nedeni var, ve kelime "" giriş cümlemi: performans. verimli kullanma sebebim bu.
Clojure dili ev sahipliği yaptı. I. e. özellikle üstünde çalıştırılmak üzere tasarlanmıştırbaşka birdil platform. Ve hemen hemen (JVM, CLİ, ECMA, Objective-C) çalıştırmak için Clojure istediğiniz herhangi bir platform, yüksek performans dağıtmak için destek uzman olduğu ortaya çıkıyorsadeceilk bağımsız değişkenin türü. Clojure OTOH sevk Multimethodskeyfi özellikleritüm argümanlar.
Yani, Protokoller göndermek için kısıtlamaksadeceilktartışma vesadecetürünü (ya da nil
özel bir durum olarak).
Bu Protokoller fikri başlı başına bir sınırlama değil, temel platform performans iyileştirmeleri ulaşmak için pragmatik bir seçimdir. Özellikle, Protokoller çok hızlı yapar/CLİ Arayüzleri, JVM için önemsiz bir eşleme anlamına gelir. Yeterince hızlı, aslında, şu anda Java veya C ile yazılmış olan Clojure kısımları yeniden yapabilme# kendi kendini Clojure.
Clojure aslında zaten sürüm 1.0 beri Protokolleri olmuştur: Seq
Protokol, örneğin. Ama 1.2, Clojure Protokolleri yazamazdın kadar, ana dilde bunları yazmak zorunda kaldım.
basit bir açıklaması PHP OOP vs Usul?...
Clojure blok Yorumlar...
Windows basit bir Python betiği dönüşt...
antlr: basit bir örnek var mı?...
3NF arasındaki fark ve basit bir dille...