2014-05-14 18 views
5

Alıntı, alıntı-ekleme, değerlendirme ve aklıma gelebilecek başka herhangi bir şeyle uğraşmaya çalışıyorum ama şimdiye kadar hiç şans yok. Neden işe yaramadığını anlıyorum - bu bir harita olarak görülüyor ve a, b ve c durumlarını değerlendirmeye çalışıyor. Daha sonra kullanmak için bir yıkım haritasının saklanması

(def destructor {a :a b :b c :c}) 
; CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(:1:15) 

(let [destructor my-map] 
    'etc) 

Ben birkaç kez kullanarak düşünüyorum oldukça dahil yapı bozma haritası var, yüzden bir yere uzağa sokmak için iyi bir fikir gibi görünüyordu. Belki bunun için daha iyi yollar vardır?

cevap

3

İyi fikir, ama bunu tam olarak yapamazsınız, çünkü depolamak istediğiniz şey gerçekten bir değer değildir, bu yüzden onu bir varda saklayamazsınız.

Bunun yerine, onun genişleme bu içeren bir makro tanımlayabiliriz: @ amalloy yanıt gibi

(defmacro with-abc [abc & body] 
    `(let [~'{:keys [a b c]} ~abc] 
    [email protected])) 

(with-abc foo 
    (...use a, b, and c...)) 
+3

komik görünüşlü '~ ' 'Let-cümlede öyle ki, a, b ve cd sözdizimi-alıntı ile ad alanı-nitelikli olsun. Bunun gerekli olduğunu düşünüyorum, ama şu anda gerçek bir bilgisayarda değilim, yani eğer birisi düzenlemekte özgür olmadığını düşünüyorsa. – amalloy

+0

Çok hoş. Ben '' anahtarları '' (bir örnek olarak görmek güzel), kullanamıyorum, "oldukça ilgili bir yıkıcı harita" (yani, birçok düzeyde) var, ama benim harita içinde takas harika çalışıyor. Biraz makro kullanıyorum, ama - pek çok kez başarılı olmasına rağmen - sanırım hala kafamı her şeyden geçmek ve yepyeni, tamamen dönüştürülmüş bir şey elde etmek üzereyim. Teşekkürler! –

+1

@amalloy: Kayıt için haklısınız - '~ '' gereklidir. Ben test ettim ve olduğu gibi çalışır, ancak 'java.lang.RuntimeException neden olur: ~ nitelikli isim: kullanıcı/a' izin veremez. –

2

şey benim de ilk içgüdüsü oldu ve muhtemelen gitmek için bir yoldur. Yani düz bir ol dikkate değer olabilir dedi' Üst düzey işlevi:

(defn destruct 
    [{a :a b :b c :c} f] 
    (f a b c)) 

(destruct my-map 
      (fn [a b c] 
      (println a) 
      (println b) 
      (println c))) 

Biraz nosier ve sen her zaman bağlamaları isim zorladı, ancak ne kadar bağlı potansiyel hijyen sorunlarını önlemek ve Metaprogramlama ile konfor düzeyiniz, bir araya getirilmesi biraz daha kolay.

+0

Evet, haritayı adlandırmadan kaçınmak istiyorum çünkü haritam yalnızca onlarca şey içermiyor, aynı zamanda birkaç farklı yuvalama seviyesinde. Mümkün olan yerlerde fonksiyonel rotayı bulmaya çalışmak güzel. Teşekkürler. –

+0

Gotcha. Makro gibi giden yol o zaman. – Beyamor

0

Sen alıntı/unquoting seviyeleri ile yok edici düzeninin

(def my-destructor '{a :a b :b c :c}) 

Bunu yapabilirsin alıntı gerekir, ama biraz yardımcı işlevi ile görmek kolaydır.

(defn- with-destructor* [binding & body] 
    `(let ~binding [email protected])) 

Bu eval gösterilen

(defmacro with-destructor [[destructor form] & body] 
    (eval `(with-destructor* [~destructor '~form] '[email protected]))) 

olarak (makro genişleme sırasında) "derlemek" zaman gerçekleşir

(macroexpand-1 '(with-destructor [my-destructor {:a 1 :c 3}] (+ a c))) 
;=> (clojure.core/let [{a :a, b :b, c :c} {:a 1, :c 3}] (+ a c)) 

Sonucu

(with-destructor [my-destructor {:a 1 :c 3}] (+ a c)) 
;=> 4 
+0

'with-destructor' 'tanımının' eval' kullanmak için hiçbir nedeni yoktur. Onun bedeni sadece '' (destroctor * [destructor form] body) ile uygulanmalıdır.Ve elbette ki 'yıkayıcıdan' vararg'ları bırakırsanız, 'uygula' seçeneğini kullanabilirsiniz (bence, sizce). – amalloy

+0

@amalloy Belki bir şeyleri özlüyorum, ama önerilerinizin yalnızca ('yıkıcı [{a: ab: bc: c} {: a 1: c 3}]' de olduğu gibi basit bir yıkıcı ifadeyle çalışacağına inanıyorum (+ ac)), ancak sorudaki gibi bir varlığında saklanmaz. –

+0

Anladım. Belirli bir makro için düzeltilmemiş olan "yıkıcı" nın kullanıcı tarafından sağlanmasına izin vermeye çalışıyorsunuz. Kafam karışıktı çünkü makro argümanını var ile aynı şekilde adlandırdınız ve makroyu varlara atıfta buluyordum. – amalloy

İlgili konular