Tại sao chúng ta không thể viết các hàm tốc ký lồng nhau trong Clojure?


11

Tôi đã cố gắng đánh giá biểu thức Clojure với các hàm tốc ký lồng nhau ngày hôm nay và nó sẽ không cho phép tôi.

Biểu thức là:

(#(+ % (#(+ % (* % %)) %)) 5) ; sorry for the eye bleed

Đầu ra là:

IllegalStateException Nested #()s are not allowed  clojure.lang.LispReader$FnReader.invoke (LispReader.java:630)
...and a bunch of other garbage

2
tôi thấy rằng không thể viết mã như vậy là một điều tốt cho clojure.
Simon Bergot

3
Bởi vì nó làm cho đôi mắt của bạn chảy máu.
Michael Shaw

Bạn không cần (# (+% 1 (# (+% 2 (*% 3% 4))% 5)) 5)?
innova

Câu trả lời:


5

Bạn sẽ biết rằng% thuộc về chức năng bên trong. Hạn chế là bạn sẽ mất quyền truy cập vào% trong hàm ngoài.

Sử dụng fn [x]cú pháp thay thế.


1
Vì thế? Hầu hết thời gian tôi không cần truy cập vào %fn bên ngoài, và vào những lần bạn đã làm, bạn có thể quay lại (fn), phải không?
Zaz

10

Nó hoàn toàn tùy ý; có một vài dòng trong trình phân tích cú pháp vô hiệu hóa nó. Nếu bạn chỉnh sửa dòng đó, bạn có thể có các hàm ẩn danh lồng nhau và chúng hoạt động chính xác như bạn mong đợi.

cụ thể, các dòng 634-635 trong https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java

public static class FnReader extends AFn{
    public Object invoke(Object reader, Object lparen) {
        PushbackReader r = (PushbackReader) reader;
        if(ARG_ENV.deref() != null) // <-- line 634
            throw new IllegalStateException("Nested #()s are not allowed");
        // ...

Bạn có thể xác định dòng trong trình phân tích cú pháp và chứng minh rằng mã được viết lại để không có chức năng lồng nhau anon và mã với dòng được loại bỏ khỏi trình phân tích cú pháp và một chức năng lồng anon hoạt động như nhau?

2
@MichaelT: có bạn đi. và bạn chỉ có thể kiểm tra nó; thật dễ dàng để làm vì bạn có thể tắt chúng khi chạy. trình phân tích cú pháp clojure thực sự khá dễ bị hack
amara

4
Vâng, không hoàn toàn độc đoán; trừ khi Rick Hickey chỉ có một ngày độc đoán, chắc chắn phải có một lý do để anh ta đặt nó vào đó, và bạn dường như không biết lý do đó là gì. Tât nhiên.
Robert Harvey

Wow, thật là một tìm kiếm! Đẹp - +1.

Thay đổi này có gây ra bất kỳ phân tích mơ hồ nào về các phương thức lồng nhau không? Tôi tò mò về việc fn [x]viết lại mã của OP sẽ có chức năng giống hệt với phiên bản clojure đã sửa đổi. Hơn nữa, sẽ có bất kỳ vấn đề với tính di động của mã clojure?

3

Bạn có thể có các hàm ẩn danh lồng nhau của sắp xếp (fn [params] (body)). Chỉ cú pháp # không hỗ trợ lồng nhau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.