2016-04-08 15 views
5

Các chức năng vector, bản đồ và tập hợp đa dạng, trong khi danh sách và chuỗi không hoạt động. Tại sao tất cả các bộ sưu tập này không thể hoạt động để làm cho nó phù hợp?Tại sao nhà thiết kế lại tạo các hàm vectơ, bản đồ và đặt trong clojure?

Hơn nữa, tại sao chúng ta không tạo tất cả các dữ liệu soạn này làm một hàm ánh xạ vị trí với dữ liệu nội bộ của nó?

Nếu chúng ta tạo tất cả các dữ liệu soạn dưới dạng hàm này thì sẽ chỉ có dữ liệu hàm và nguyên tử trong clojure. Điều này sẽ giảm thiểu các yếu tố cơ bản trong ngôn ngữ đó đúng không?

Tôi tin rằng tối thiểu, tốt nhất chỉ có 2, tập hợp các yếu tố cơ bản sẽ làm cho ngôn ngữ đơn giản hơn, biểu cảm hơn và linh hoạt hơn. Điều này có đúng không?

+0

Có sự khác biệt nào giữa danh sách và chuỗi không? –

+0

Chào mừng bạn đến với stackoverflow, Thật khó trả lời các câu hỏi về trạng thái tâm trí của người khác theo cách mà bạn có thể đánh dấu là "đúng" hoặc "không chính xác" để khó trả lời câu hỏi này một cách khách quan. –

+0

@BobJarvis là một giao diện được thực hiện bởi tất cả các loại bộ sưu tập, bao gồm danh sách. –

Trả lời

9

Vectơ, bản đồ và bộ là tất cả cấu trúc dữ liệu liên kết. Bản đồ là rõ ràng nhất; họ chỉ cần kết hợp các khóa tùy ý với các giá trị tùy ý. Một véc tơ có thể được coi là một bản đồ có tập hợp khóa phải là tập hợp của tất cả các số nguyên không âm tính nhỏ hơn kích thước của vectơ. Cuối cùng, các bộ có thể được coi là bản đồ ánh xạ khóa cho chính chúng.

Điều quan trọng là phải hiểu rằng bản chất tuần tự của một véc tơ và bản chất liên kết của một véc tơ là hai thứ trực giao. Đó là một cấu trúc dữ liệu được thiết kế để hỗ trợ cả hai trừu tượng (ở một mức độ nào đó, ví dụ, bạn không thể chèn hiệu quả vào đầu một vectơ).

Danh sách đơn giản hơn vectơ; chúng là cấu trúc dữ liệu tuần tự hữu hạn, không có gì hơn. Danh sách không thể trả về phần tử một cách hiệu quả tại một chỉ mục cụ thể, do đó nó không thể hiện chức năng đó như một phần của giao diện cốt lõi của nó. Tất nhiên, bạn có thể có được một yếu tố của một danh sách bằng chỉ số sử dụng nth, nhưng trong trường hợp đó, bạn dứt khoát xử lý nó như là một chuỗi, không như một cấu trúc liên kết.

Vì vậy, để trả lời câu hỏi của bạn, việc triển khai IFn cho vectơ, bản đồ và tập hợp có mối quan hệ cực kỳ gần nhau giữa ý tưởng về cấu trúc dữ liệu kết hợp và ý tưởng về hàm thuần túy. Danh sách và các trình tự khác không phải là liên kết vốn có, do đó, để nhất quán, chúng không thực hiện IFn.

+0

Tôi đã kiểm tra thuộc tính của bộ trong Clojure có vẻ như đó không phải là cấu trúc liên kết. Chạy: (cập nhật # {1 2} 1 inc) bạn sẽ nhận được ngoại lệ: PersistentHashSet không thể chuyển thành clojure.lang.Associative – Shark

+0

@Shark By "associative", tôi không có nghĩa là "triển khai [' Associative'] (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Associative.java) giao diện "; thay vào đó, tôi chỉ đơn giản có nghĩa là chúng hỗ trợ hiệu quả các truy vấn từ các khóa đến các giá trị. Trong Clojure, các thiết lập chỉ xảy ra để được xử lý như [trường hợp đặc biệt] (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L746-L749), nhưng điều đó không thay đổi thực tế là họ vốn đã hỗ trợ tra cứu hiệu quả và danh sách không. –

+0

cảm ơn đã cho tôi xem mã nguồn. Bây giờ tôi có thể nói rằng đó là một lỗ hổng trên định nghĩa kiểu của Set trong clojure? Nó giả sử để thực hiện Associative để làm cho nó bao gồm? – Shark

2

câu trả lời Elogent là tuyệt vời. Có một lý do nữa là sẽ không có ý nghĩa đối với các danh sách có chức năng:

Danh sách đen đã có một vai trò rất quan trọng khác nhau, vì vậy chúng cũng không được coi là hàm theo cách vector.

Hãy bắt đầu với một vectơ chứa hai hàm, partial+ và một số, 5. Chúng tôi có thể coi vectơ là một hàm, như bạn đã biết, để trả về giá trị được lập chỉ mục bởi đối số của nó:

user=> ([partial + 5] 2) 
5 

Cho đến giờ, rất tốt. Giả sử chúng ta muốn sử dụng một danh sách (partial + 5) ở vị trí của vector, như bạn đề nghị, để trở về giá trị 5. chúng tôi sẽ nhận được một thông báo lỗi? Không! Nhưng chúng tôi sẽ không nhận được 5 kết quả là:

user=> ((partial + 5) 2) 
7 

Điều gì đã xảy ra? (partial + 5) trở một chức năng - chức năng có thêm 5 đến đối số duy nhất của nó - và sau đó chức năng này được áp dụng cho đối số 2.

Khi danh sách được đánh giá, phần tử đầu tiên của nó được đánh giá và phải trả về một hàm. Nếu phần tử đầu tiên là một biểu tượng, nó được đánh giá, và sau đó hàm đó là giá trị của nó được áp dụng cho các đối số, đó là các phần tử khác của danh sách. Nếu đối số đầu tiên của một danh sách là chính nó là một danh sách, thì nó được đánh giá theo cùng cách mà nó sẽ được đánh giá nếu nó ở cấp cao nhất. Toàn bộ biểu thức trong danh sách bên trong đó sẽ trả về một hàm, sau đó nó sẽ được áp dụng cho các phần tử khác của danh sách bên ngoài.

Vì danh sách bên trong là yếu tố đầu tiên của danh sách đang được đánh giá đã có vai trò này nên nó cũng không thể phát loại vai trò mà các vectơ là yếu tố đầu tiên phát.

+0

Tôi nghĩ rằng u cần phải thay đổi con quỷ của bạn để ('(một phần + 5) 2) – Shark

+0

Tôi không có ý định để được trích dẫn, và nếu nó được, mã tôi đã cho sẽ không làm những gì tôi nói. Nhưng bạn có một điểm tốt: Tương tự với '([: a: b] 1)', hoặc '('[: a: b] 1)', là '(' (: a: b) 1)', tạo ra lỗi. Sau đó, tôi nghĩ rằng câu trả lời của Elogent là có liên quan - đặc biệt là về hiệu quả. Truy cập một mục nhập vectơ là nhanh; nó liên quan đến việc lập chỉ mục hoặc một phương thức nhanh khác. Việc truy cập bản đồ và tập hợp rất nhanh vì chúng sử dụng băm. Các truy cập này bao gồm một phép tính đơn giản - giống như một hàm đơn giản. Danh sách truy cập chậm bởi vì nó có thể liên quan đến việc lấy một con trỏ cái khác, hết lần này đến lần khác. – Mars

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