2014-10-30 22 views
8

Rich Hickey's Strange Loop transducers presentation cho chúng tôi biết rằng có hai triển khai map trong Clojure 1.6, một cho các chuỗi trong clojure.core và một cho các kênh trong core.async.Core.async có thể thực hiện các chức năng của nó theo trình tự không?

enter image description here

Bây giờ chúng ta biết rằng trong 1,7 chúng tôi có đầu dò, mà một hàm foldr (reduce) được trả về từ chức năng bậc cao như mapfilter khi đưa ra một chức năng nhưng không phải là một bộ sưu tập.

Điều tôi đang cố gắng nói rõ và thất bại, là lý do tại sao các hàm core.async không thể trả về một chuỗi hoặc là Seq giống. Tôi có cảm giác rằng 'giao diện' (giao thức) là khác nhau nhưng tôi không thể thấy như thế nào.

Chắc chắn nếu bạn đang lấy vật phẩm đầu tiên ra khỏi kênh thì bạn có thể thể hiện điều đó khi lấy vật phẩm đầu tiên ra khỏi một chuỗi?

Câu hỏi của tôi là: Có thể core.async đã triển khai các chức năng của nó theo trình tự không?

Trả lời

7

Vâng, theo một nghĩa nào đó, chúng có thể có. Nếu bạn bỏ qua đi khối (cho thời điểm này chúng ta hãy làm như vậy), sau đó có thực sự không có gì sai trái với một cái gì đó như sau:

(defn chan-seq [ch] 
    (when-some [v (<!! c)] 
    (cons v (lazy-seq (chan-seq ch))))) 

Nhưng cần chú ý ở đây <!! gọi. Điều này được gọi là "chặn": bên trong chức năng này là một số lời hứa và khóa sẽ khiến cho chuỗi đang thực hiện tạm dừng cho đến khi có giá trị trên kênh. Vì vậy, điều này sẽ làm việc tốt nếu bạn không nhớ có một thread Java ngồi đó làm gì.

Ý tưởng đằng sau các khối đi là thực hiện các quy trình lôgic rẻ hơn nhiều; để thực hiện điều này, khối di chuyển viết lại phần thân của khối thành một chuỗi các cuộc gọi lại được gắn vào kênh, để cuộc gọi nội bộ đến <! bên trong khối di chuyển được chuyển thành một cái gì đó như thế này (take! c k) trong đó k là một cuộc gọi lại đến phần còn lại của khối đi.

Bây giờ nếu chúng tôi có tiếp tục thực sự, hoặc nếu JVM hỗ trợ các chủ đề nhẹ, thì có, chúng tôi có thể kết hợp các khối đi và chặn. Nhưng điều này hiện nay liên quan đến việc viết lại bytecode sâu (như dự án Pulsar/Quasar) hoặc một số tính năng JVM không chuẩn. Cả hai tùy chọn này đều bị loại trừ trong việc tạo ra core.async để thuận lợi cho việc thực hiện đơn giản hơn nhiều (và hy vọng đơn giản hơn nhiều) chuyển đổi khối cục bộ.

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