2012-01-19 35 views
23

Vì vậy, tôi nghĩ rằng nó sẽ là một ý tưởng tốt đẹp để đặt tên một chức năng tính toán số mũ ^, nhưng có vẻ như dấu mũ thực sự làm điều gì đó đặc biệt, như Clojure REPL tạo ra lỗi khi đánh giá '^. Googling chủ yếu đã cho tôi this, vì vậy tôi đã tự hỏi những gì sử dụng thực tế cho các dấu mũ trong Clojure là.Dấu mũ Clojure làm biểu tượng?

(Ngoài ra, nó sẽ có thể sau khi tất cả đến tên một chức năng ^?)

Trả lời

32

^ là "nhân vật meta" nó nói với the reader để thêm biểu tượng bắt đầu với ^ như siêu dữ liệu để biểu tượng tiếp theo (với điều kiện nó là một cái gì đó mà thực hiện IMetas)

user=> (def x ^:IamMeta [1 2 3]) 
#'user/x 
user=> x 
[1 2 3] 
user=> (meta x) 
{:tag :IamMeta} 
user=> 

Bạn có thể học được rất nhiều về cách hoạt động clojure dưới mui xe bằng cách nhìn vào meta của sự vật, cho các chức năng Ví dụ:

user=> (meta foo)       
{:ns #<Namespace user>, 
:name foo, :file "NO_SOURCE_PATH", 
:line 5, :arglists ([s])} 

này là rất thường được sử dụng cho type hints

(defn foo [^String s] (.charAt s 1)) 

nó thường là một ý tưởng tốt để bật cảnh báo phản ánh (set! *warn-on-reflection* true) và sau đó thêm gợi ý kiểu cho đến những lời cảnh báo biến mất. mà không có Clojure này sẽ tìm kiếm loại toán hạng hàm tại thời gian chạy, điều này giúp bạn tránh được rắc rối phiền phức với các kiểu mặc dù với một chi phí nhỏ.

PS: tiếp theo nhân vật người đọc ưa thích của tôi là "công văn" nhân vật #, nó rất đáng tìm hiểu về nó bên cạnh :)

PPS: đây là khác nhau trong clojure 1.2.x vs clojure 1.3.x trong Clojure 1.2.1 siêu dữ liệu không soạn khi bạn sử dụng meta-nhân vật:

user=> (def foo ^:foo ^:bar [1 2 3]) 
#'user/foo 
user=> (meta foo) 
{:tag :foo} 

và trong 1.3 nó "làm điều đúng đắn" và cũng từ khóa những lựa chọn thay vì "thẻ":

user=> (def foo ^:foo ^:bar [1 2 3]) 
#'user/foo 
user=> (meta foo) 
{:foo true, :bar true} 
+0

Nó không chính xác "thêm biểu tượng". Một biểu tượng được cắt ngắn cho một loại int. Nhưng điều này cũng làm việc với các chuỗi, ví dụ. '^" B ["'. Từ khóa được dịch sang các tùy chọn, ví dụ: '^: foo' được chuyển thành' {: foo true} '. Và cuối cùng, bạn có thể chỉ định bản đồ, ví dụ: '^ {: tag String: foo true: bar: baz}'. – kotarak

+0

kotarak điểm tốt, chúng ta cũng nên đề cập đến siêu dữ liệu tạo khác nhau trong các phiên bản khác nhau của clojure và tôi tin rằng 1,3 bắt đầu copmposing chuỗi siêu dữ liệu '^: foo ^: bar [1 3 4]' –

0

Dường như với tôi câu trả lời cho câu hỏi của bạn là không may. Trong Clojure, bạn không thể đặt tên cho hàm ^.

Tôi đã thử các sau đây trong REPL:

user=> (println \^) 
^ 
nil 

này dường như ngụ ý rằng bạn có thể thoát khỏi carat (^) với một dấu gạch chéo. Tuy nhiên, nếu tôi cố gắng để khai báo một hàm sử dụng \^ như một tên sau đó tôi nhận được một thông báo lỗi:

user=> (defn \^ [n e] (cond (= e 0) 1 :else (* n (\^ n (- e 1))))) 
IllegalArgumentException First argument to defn must be a symbol 
clojure.core/defn (core.clj:277) 

Cùng mã làm việc với một tên văn bản thông thường:

user=> (defn exp [n e] (cond (= e 0) 1 :else (* n (exp n (- e 1))))) 
#'user/exp 
user=> (exp 3 3) 
27 

tôi sẽ rất vui mừng nếu một người có Clojure-fu tốt hơn tôi có thể chứng minh tôi sai! :)

Các vấn đề liên quan