Anonim işlev kısaltması


85

Kısa gösterimi # (..) kullanan anonim işlevler hakkında anlamadığım bir şey var.

Aşağıdaki işler:

REPL>  ((fn [s] s) "Eh")
"Eh"

Ancak bu değil:

REPL>  (#(%) "Eh")

Bu çalışıyor:

REPL> (#(str %) "Eh")
"Eh"

Anlamadığım şey (# (%) "Eh") neden çalışmıyor ve aynı zamanda ((fn [s] s) "Eh") içinde str kullanmam gerekmediğidir.

Her ikisi de anonim işlevlerdir ve her ikisi de burada bir parametre alır. Neden diğer gösterimler bir işleve ihtiyaç duymazken kısaltma notasyonu bir işleve ihtiyaç duyar?

Yanıtlar:


126
#(...)

kısaltmasıdır

(fn [arg1 arg2 ...] (...))

(burada argN sayısı vücutta ne kadar% N'ye sahip olduğunuza bağlıdır). Yani yazdığın zaman:

#(%)

şu dile çevrildi:

(fn [arg1] (arg1))

Bunun ilk anonim işlevinizden farklı olduğuna dikkat edin:

(fn [arg1] arg1)

Sürümünüz arg1'i bir değer olarak döndürür, kısaltmanın genişletilmesinden gelen sürüm onu ​​bir işlev olarak çağırmaya çalışır. Bir dize geçerli bir işlev olmadığı için hata alırsınız.

Steno, gövde etrafında bir dizi parantez sağladığından, yalnızca tek bir işlev çağrısı veya özel bir form yürütmek için kullanılabilir.


65

Diğer cevapların zaten çok güzel bir şekilde işaret ettiği #(%)gibi (fn [arg1] (arg1)), gönderdiğiniz şey aslında bir şeye genişler , ki bu hiç de aynı değildir (fn [arg1] arg1).

@John Flatness, sadece kullanabileceğinizi belirtti identity, ancak gönderim makrosunu identitykullanarak yazmanın bir yolunu arıyorsanız #(...), bunu şu şekilde yapabilirsiniz:

#(-> %)

#(...)Gönderme makrosu ile ->iş parçacığı makrosu birleştirildiğinde, (fn [arg1] (-> arg1))tekrar genişleyen (fn [arg1] arg1), sadece istediğiniz gibi bir şeye genişletilir . Ayrıca ->ve #(...)makro kombinasyonunu vektörleri döndüren basit işlevler yazmak için yararlı buluyorum , örneğin:

#(-> [%2 %1])

21

Eğer kullandığınız zaman #(...), bunun yerine yazıyoruz hayal (fn [args] (...)), dahil sağ sterlin sonra başladı parantez.

Yani, çalışmayan örneğiniz şuna dönüşür:

((fn [s] (s)) "Eh")

ki bu açıkçası işe yaramıyor çünkü "Eh" dizesini çağırmaya çalışıyorsunuz . Örneğiniz strişe yarıyor çünkü artık işleviniz (str s)yerine (s). (identity s)str'ye zorlamayacağı için ilk örneğinize daha yakın bir analog olacaktır.

Düşünürseniz mantıklıdır, çünkü bu tamamen minimal örnek dışında, her anonim işlev bir şeyi çağıracaktır , bu yüzden gerçekten bir arama yapmak için başka bir iç içe parantez kümesine ihtiyaç duymak biraz aptalca olacaktır.

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.