2009-03-26 12 views
15

Przyjrzyj się znakomitemu samouczkowi Clojure here. W jednym z przykładów, jakie ma kodu Clojure wzdłuż następujących linii:dlaczego "(def samogłoska? (Ustaw" aeiou "))" działa?

(def vowel? (set "aeiou")) 

To sprawia samogłoska return true dla samogłosek i spółgłosek false:

(vowel? (first "abc")) ; => true 
(vowel? (first "cba")) ; => false 

Dlaczego tak jest? Zakładam, że ma to coś wspólnego ze znakiem zapytania za nazwą zmiennej. Nie znaleźliśmy niczego od razu w tutorialu ...


Edit Właśnie uświadomiłem sobie vowel? nie zwraca prawdę lub fałsz, lecz element sama lub zerowa. Zobacz moją własną odpowiedź.

Odpowiedz

16

Jest to całkowicie analogiczne do sposobu działania map (najbardziej naturalnych obiektów w Clojure). Gdy mapa jest nazywany jako funkcja, działa jako mapowania:

user=> (def ob {:foo "bar", :bar :baz, :qwerty 42}) 
#'user/ob 
user=> (ob :foo) 
"bar" 

Więc to ma sens, że zestaw Clojure można nazwać jako funkcję i będzie działać jako test członkostwa. Nawiasem mówiąc, jeśli używasz słów kluczowych (tych rzeczy, które zaczynają się dwukropkiem) jako klawisze mapowania, oni również pracować jako podobne funkcje, dzięki czemu można zrobić

user=> (:bar ob) 
:baz 

a nawet samo z zestawami słowa kluczowe:

user=> (def vowel-keywords (set [:a :e :i :o :u])) 
#'user/vowel-keywords 
user=> (:a vowel-keywords) 
:a 
user=> (:b vowel-keywords) 
nil 

Ale znowu, ta ostatnia sztuczka działa tylko za pomocą słów kluczowych, a nie cokolwiek innego, co można użyć jako klucze w odwzorowaniu lub członków w zestawie.

7

Aha! Skończyło się, że sam to odkryłem. W rzeczywistości nie zwraca ona true ani false, lecz zwraca pierwsze wystąpienie w zbiorze lub zero, jeśli nie występuje.

A ponieważ możesz użyć tego jako warunku (zero jest traktowane jako fałszywe, a nie-zero jako prawdziwe), działa to jak miły mały hack do sprawdzania, czy ciąg zawiera literę.

(vowel? (first "abc")) ; => "a" 
(vowel? (first "cba")) ; => nil 

(if (vowel? (first "abc")) 
     (println "yay") 
     (println "oops")) ; => "yay" 
+0

Brzmi dobrze dla mnie. Znak zapytania wskazuje, że można go użyć jako testu. Często widzisz wykrzyknik na funkcjach, które mają efekty uboczne. Nie są częścią języka, są tradycją seplenienia (więc znasz bezpieczne funkcje z "niebezpiecznych"). – MBCook

+2

Aby było jasne,? i ! są po prostu znakami takimi jak aib, i można ich używać do nazywania symboli (tak jak są to \, /, *, -, + ...). Istnieją tradycje nazywania pewnych symboli w Lisp, ale istnieją niewielkie różnice między dialektami. – Svante

+0

ah, dzięki @svante! Myślałem, że jest coś magicznego w "?" :) – Epaga