SORU
22 Aralık 2010, ÇARŞAMBA


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
22 Aralık 2010, ÇARŞAMBA


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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • ecf150king

    ecf150king

    20 Ocak 2006
  • Hallucination Land

    Hallucinatio

    14 Ocak 2011
  • Jeremy Stark

    Jeremy Stark

    23 Mayıs 2010