2017-06-21 25 views
6

statesMakrolar neden makrolar olarak tanımlanır? Örneğin LUMINUS web sitesi için

Compojure rota tanımları

(GET "/" [] "Show something") 
... 

Ama compojure yolları değil fonksiyonlardır istek haritalar kabul ve tepki haritalar döndüren işlevler ... sadece olduklarını

(defmacro GET "Generate a `GET` route." 
    [path args & body] 
    (compile-route :get path args body)) 

Bir işlev döndüren ancak yıkıma izin vermeyen make-route işlevini kullanabilirsiniz. Öyleyse, bir işlev olarak, componentjure'ın tahrip için (yani vektör) özel sözdizimini kullanamazsınız, ancak bu, herhangi bir yıkımı durdurur mu? Makro onlara bir performans artışı veriyor mu?

(make-route :get "/some_path" some_handler) 

Yıkıcı sözdizimi bir makro sarıcı kullanarak işlevine geçirilemedi?

cevap

7

Makrolar kullanılmasının bir nedeni, kullanıcının her şeyi teklif etmek zorunda kalmadan işlev ve sembol adları yazabilmesidir. Bu örneği from the Clojure Cookbook atın:

; Routing 
(defroutes main-routes 
    (GET "/" [] (index)) 
    (GET "/en/" [] (index)) 
    (GET "/fr/" [] (index-fr)) 
    (GET "/:greeting/" [greeting] (view greeting))) 

index* sembollerin tümünün yanı sıra view ve greetingGET bir işlev olsaydı alıntı gerekecekti: işlevi çalıştırılmadan önce fonksiyon argümanları değerlendirilir yana

; Routing 
(defroutes main-routes 
    (GET "/" [] '(index)) 
    (GET "/en/" [] '(index)) 
    (GET "/fr/" [] '(index-fr)) 
    (GET "/:greeting/" '[greeting] '(view greeting))) 

Form okunduğunda, (index)ve diğerleri tarafından değerlendirilecektir. Ayrıca, her bir HTTP isteğinde greeting değişkeni değişecektir, bu nedenle açık bir şekilde önceden bilinmemektedir. Makro ayrıca, normal bir işlevle (normalde) mümkün olmayan tüm yıkıcı büyü ile de ilgilenir.

(GET "/:greeting/" [greeting] (view greeting)) 

normal "Clojure kod" değil:

genellikle kafa karıştırıcı (ve iyi başlayanlar açıkladı değildir) şey gibi bir satır olmasıdır. Bunun yerine, GET makrosunun "yasal" Clojure kodunun nasıl üretileceğine dair talimatlar olarak kullanacağı ve kullanacağı bir tür (elverişli bir şekilde Alana Özgü Dili veya DSL) kısa yoldur. DSL, Clojure çok daha kısa, daha basit, & Clojure derleyici tarafından üretilen Java Bytecode veya makine montaj dili kodundan daha uygun olduğu gibi, bir insan için son oluşturulan koddan daha uygun olan daha kısa, daha basit, & JVM tarafından üretilmiştir.

Kısacası, her makro, DSL'i basit bir Clojure haline getiren bir "ön derleyici" dir; bu, daha sonra Clojure derleyicisi tarafından Java bayt kodu oluşturmak için alınan yongadır.

GET sembol bir işlev ne de makro gibi, ama işaretleyici sadece bir tip ne oldu böylece defroutes makro içine makro büyü tüm koymak için yeniden düzenlenmiştir olabilir, söyledikten Uygulamada :get anahtar kelime. Bir kullanıcı olarak, bu tür uygulama detayları normalde çok fazla önemli değildir.

Güncelleme

Bir işlev çalışmak veya çok garip olmaz sadece makro kullanmak en iyisidir. Karar verici faktör, genellikle çıplak (belirtilmemiş) semboller kullanmak istiyorsa, ancak bunları önceden değerlendirmezse belirleyici faktördür. Çekirdek Clojure kendisi defn, for, and, or, when ve diğerleri dahil olmak üzere diğer dillerde "yerleşik ins", birçok yapılar için makro kullanır.

Ayrıca makro bazı şeyler bir işlev yapamaz unutmayın can, böyle filter gibi yüksek bir dereceden işleve bir parametre olarak.

Özetle, bir fonksiyon, bir Davranışı tanımlar. Makro, bir dil uzantısını tanımlar.

+0

Eğer GET bir fonksiyon olsaydı, '' (tebrik selamlama) 'hiçbir anlam ifade etmezdi. “GET” /: selamlama ”(fn [req] (istek [[tebrik] req] (selamlama))))), hantal ama imkansız olmayan bir şey yazmanız gerekir. – amalloy

+0

İşlev yaklaşımının çoğu özellik için 'eval' kullanması gerekecek, bu nedenle makro çözümü büyük ölçüde tercih ediliyor. –

+0

@AlanThompson - tamamen merak. Makroların büyük bir hayranı değilim çünkü çoğu zaman gerçekten neler olduğunu engellediklerini düşünüyorum. Projeler onları yoğun olarak kullandığında daima ilgilenir (tasarım kararları vb.). Sadece bidi'yi buldum - veri yapısı yaklaşımı bana ruhani düzeyde konuşur. – beoliver

İlgili konular