2009-03-26 1 views
15

Tôi đang xem hướng dẫn tuyệt vời của Clojure here. Trong một trong những ví dụ nó có mã Clojure dọc theo dòng sau đây:tại sao "(def nguyên âm? (Set" aeiou "))" làm việc?

(def vowel? (set "aeiou")) 

này làm cho nguyên âm trở lại đúng với nguyên âm và phụ âm sai cho:

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

Tại sao điều này? Tôi giả sử nó có một cái gì đó để làm với dấu hỏi đằng sau tên biến. không thể tìm thấy bất cứ điều gì ngay lập tức trong hướng dẫn ...


Sửa Tôi chỉ nhận ra vowel? không trả lại đúng hay sai mà là yếu tố bản thân hay không. Xem câu trả lời của riêng tôi.

Trả lời

16

Điều này hoàn toàn tương tự như cách bản đồ (đối tượng tự nhiên nhất trong Clojure) hoạt động. Khi bản đồ được gọi là một chức năng, nó hoạt động như một ánh xạ:

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

Vì vậy, nó có ý nghĩa rằng một bộ Clojure có thể được gọi là một chức năng, và sẽ làm việc như một thử nghiệm thành viên. Bằng cách này, nếu bạn sử dụng các từ khóa (những điều mà bắt đầu với một dấu hai chấm) như các phím của một ánh xạ, họ cũng làm việc có chức năng như tương tự, vì vậy bạn có thể làm

user=> (:bar ob) 
:baz 

và ngay cả những điều tương tự với bộ từ khóa:

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

Nhưng, lần nữa, mẹo sau này chỉ hoạt động với từ khóa, không phải bất kỳ thứ gì khác mà bạn có thể sử dụng làm khóa trong bản đồ hoặc thành viên trong nhóm.

7

Aha! Tôi đã tự tìm ra nó. Nó không thực sự trả lại true hoặc false, thay vì nó trả về lần xuất hiện đầu tiên trong tập hợp hoặc không nếu nó không xảy ra.

Và vì bạn có thể sử dụng điều này làm điều kiện (không được xử lý là sai và không đúng), điều này hoạt động như một hack nhỏ để kiểm tra xem chuỗi có chứa một chữ cái hay không.

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

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

Nghe có vẻ phù hợp với tôi. Dấu chấm hỏi cho biết nó có thể được sử dụng như một bài kiểm tra. Bạn sẽ thường thấy dấu chấm than trên các hàm có tác dụng phụ. Họ không phải là một phần của ngôn ngữ, họ là những truyền thống lisp (vì vậy bạn biết các chức năng an toàn từ những "nguy hiểm"). – MBCook

+2

Để làm rõ,? và! chỉ là các ký tự như a và b, và bạn có thể sử dụng chúng để đặt tên cho các ký hiệu (như là \, /, *, -, + ...). Có truyền thống để đặt tên một số ký hiệu trong Lisp, nhưng có sự khác biệt nhỏ giữa các phương ngữ. – Svante

+0

ah, cảm ơn @svante! tôi nghĩ có điều gì đó kỳ diệu về "?" :) – Epaga