Hangi alanda LISP'in makrosu Ruby'nin DSL oluşturma yeteneğinden daha iyidir?


21

Ruby'nin parlamasını sağlayan şeylerden biri, Etki Alanına Özel Dilleri daha iyi oluşturma yeteneğidir.

Bu kütüphaneleri LISP’de makro ile çoğaltmak mümkün olsa da Ruby'nin uygulamasının daha zarif olduğunu düşünüyorum. Yine de, bir tane düşünemesem de, LISP'in makrosunun Ruby'ninkinden daha iyi olabileceğini düşünüyorum.

Öyleyse, LISP'nin makrosu hangi alanda Ruby'nin DSL oluşturma yeteneğinden daha iyidir?

güncelleştirme

Bunu sordum çünkü modern programlama dilleri LISP tekilliğine yaklaşıyor gibi.

  • C makro genişleme ön işlemcisine sahip , ancak çok ilkel ve hataya açık
  • C # özniteliklere sahiptir, ancak bu salt okunur olsa da yansıma ile ortaya çıkar
  • Python, fonksiyonun davranışını değiştirebilecek dekoratör ekledi (ve v 3.0 için sınıf), ancak oldukça sınırlı.
  • Bakım uygulanırsa, ancak Ruby yöntemiyle zarif DSL yapan Ruby TMTOWTDI.

LISP'nin makrosunun sadece özel durumlar için geçerli olup olmadığını ve diğer programlama dili özelliklerinin, bugün yazılım geliştirmedeki zorluklarla başa çıkmak için soyutlamayı yükseltecek kadar güçlü olup olmadığını merak ediyordum.


4
Bu konuda niçin yakın oylar aldığından emin değilim. Sanırım istediğimiz soru bu mu? İlginç, düşündürücü düşünce ve kapsam oldukça iyi tanımlanmıştır.
Tim Post

Ruby'de böyle bir şey uygulamaya çalışın: meta-alternative.net/pfront.pdf
SK-

@Tim Post: Bir sorun, hem Common Lisp hem de Ruby'yi iyi tanımadığınız sürece, bu sorunun gerçekten kolay bir soru olmadığıdır. Bir diğeri, titizlikle rahatsız edebilen diğer dillere oldukça cahil referanslar: C / C ++ diye bir dil yok ve C ++ 'nın önemli bir kısmı şablon sistemi ve Common Lisp'in makro sisteminin sadece özel durumlar için geçerli olduğu önerisi. Temel olarak, bu iyi bir soru, ama kötü yazılmış ve cevaplamak zor.
David Thornley

@David Thornley, yazıyı özellikle C \ C ++ 'da güncelledim ve C'yi vurguladım. Başkalarının CL'nin makrosunun özel durum için olmadığını bana göstereceğini ümit edeceğimi umarak soruyu gönderdim .
OnesimusUnbound

@OnesimusUnbound: Lisp makro sisteminin yapabileceği herhangi bir hesaplama için teorik olarak en azından yetenekli olduklarından, gerçekten C ++ 'ın dil örnekleri listenize şablonlarını eklerdim. Lisp'in makroları göz önüne alındığında, bazı iyi Ortak Lisp kodlarını (orada bol miktarda F / OS Lisp kodu var) alın ve "defmacro" ifadesini arayın (büyük / küçük harf duyarlı bir arama yapmak isteyebilirsiniz). Muhtemelen bir çoğunu bulacaksınız. Makroların yazma ve doğru yazma işlevlerinden daha zor olduğunu düşünün ve genel olarak yararlı olmaları gerektiğinin farkına varacaksınız.
David Thornley

Yanıtlar:


23

Lisp'i okuyun ve kendiniz karar verin.

Özetim Ruby'nin uygun sözdizimi sağlamada daha iyi olduğudur. Ancak Lisp, yeni soyutlamalar yaratma kabiliyetine ve ardından soyutlamaya katmanı kazanma şansını verir. Fakat bu noktayı anlamak için pratikte Lisp'i görmelisin. Bu nedenle kitap tavsiye eder.


1
"Let Let Lambda" çok benzer bir zemini kapsıyor. Ayrıca okuma önerilir.
John R. Strohm

But Lisp wins, hands down, at the ability to create new abstractions, and then to layer abstraction on abstraction.Şimdi nedenini biliyorum. . .
OnesimusUnbound

Lisp'in üstüne herhangi bir sözdizimi sağlamak önemli değildir. Aslında, okuyucu makrolar sayesinde Ruby'den çok daha kolay.
SK-mantık

1
@ SK-mantık: Doğru. Ancak Lispers, okuyucu makrolardan uzak durur çünkü o rotadan indiğinizde artık Lisp gibi hissetmez. Aslında, Clojure gibi bazı Lisp çeşitleri, dil tasarımcısı için okuyucu makroları ayırır.
btilly

14

Ruby'nin DSL geliştirme olanakları, dilin yapısını değiştirmez. Ruby'nin metaprogramlama tesisleri doğal olarak Ruby sözdizimine ve anlambilimine bağlıdır ve yazdığınız her şeyin Ruby'nin nesne modeline dahil edilmesi gerekir.

Makroların soyut programın üzerinde çalıştığı Lisp (ve makro özellikleri farklı olan Scheme ) ile karşılaştırınız. Bir Lisp programı Çünkü olduğunu bir Lisp değer, bir makro fonksiyon haritalama diğerine esasen keyfi sözdizimi.

Etkili, bir Ruby DSL hala Ruby gibi hissediyor , ancak bir Lisp DSL Lisp gibi hissetmek zorunda değil.


6
+1: LOOP bir DSL örneği olarak çok Lispy hissetmiyor.
Frank Shearar

2

Ruby'nin DSL'leri hiç DSL değil ve bunları kullanmaktan kesinlikle nefret ediyorum çünkü dokümantasyonları gerçekten nasıl yürüdüğü konusunda yatıyor. Örneğin ActiveRecord'u ele alalım. Modeller arasındaki ilişkileri "bildirmenizi" sağlar:

class Foo < ActiveRecord::Base
    has_one :bar
    has_one :baz
end

Ancak, bu "DSL" nin bildirimi (Ruby'nin classsözdiziminin kendisinin bildirimi gibi ), Ruby "DSL" lerin gerçekte nasıl çalıştığını anlayan herkes tarafından açığa çıkabilen korkunç bir yalan:

class Foo < ActiveRecord::Base
    [:bar,:baz,:qux,:quux].each do |table|
        has_one table if i_feel_like_it?(table)
    end
    puts "Just for shits and giggles, and to show"
    puts "just how fucked up Ruby really is, we're gonna ask you"
    puts "which SQL table you want the Foo model to have an"
    puts "association with.\n"
    puts "Type the name of a table here: "
    has_one gets.chomp.to_sym
end

(Sadece bir Lisp formunun bedeninde buna yakın bir şey yapmayı deneyin defclass!)

Kod tabanınızda yukarıdaki gibi bir kodun olduğu anda, projedeki her geliştiricinin, Ruby DSL'lerin , kodun bakımını yapmadan önce gerçekte nasıl çalıştığını (sadece yarattıkları yanılsamaları değil) tam olarak anlamaları gerekir . Mevcut belgeler tamamen yararsız olacaktır, çünkü bunlar yalnızca bildirimsel yanılsamayı koruyan deyimsel kullanımı belgelemektedir .

RSpec, yukarıdakinden bile daha kötü, çünkü hata ayıklamak için kapsamlı ters mühendislik gerektiren tuhaf kenar durumları var. (Bütün günlerimi neden test vakalarımdan birinin atlandığını bulmaya çalışarak geçirdim. RSpec'in test olaylarından sonra bağlamda olan tüm sınav vakalarını, bağlamda göründükleri sıraya bakılmaksızın bağlamsız yürütdüğü ortaya çıktı. , çünkü contextyöntem blokunuzu normalde girdiğinden farklı bir veri yapısına yerleştirir.)

Lisp DSL'ler, küçük derleyiciler olan makrolar tarafından uygulanır. Bu şekilde oluşturabileceğiniz DSL'ler, Lisp'in mevcut sözdizimini kötüye kullanmaz. Tamamen kusursuz olacak şekilde yazılabilecek gerçek mini dillerdir, çünkü kendi gramerlerine sahip olabilirler. Örneğin, Lisp'in LOOPmakroları Ruby'nin eachyönteminden çok daha güçlü .

(Çoktan bir cevap kabul ettiğinizi biliyorum, ancak bunu okuyan herkes On Lisp'in tamamını okumak isteyecek .)

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.