ทำไมเราไม่สามารถเขียนฟังก์ชั่นการจดชวเลขซ้อนใน Clojure ได้?


11

ฉันพยายามประเมินการแสดงออกของ Clojure ด้วยฟังก์ชั่นชวเลขที่ซ้อนกันในวันนี้และมันจะไม่ยอมให้ฉัน

การแสดงออกคือ:

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

ผลลัพธ์คือ:

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

2
ฉันพบว่าไม่สามารถเขียนรหัสดังกล่าวเป็นสิ่งที่ดีสำหรับการปิดบัง
Simon Bergot

3
เพราะมันทำให้ดวงตาของคุณมีเลือดออก
Michael Shaw

คุณไม่ต้องการ (# (+% 1 (# (+% 2 (*% 3% 4))% 5)) 5)?
innova

คำตอบ:


5

คุณจะรู้ว่า% เป็นฟังก์ชันภายใน ข้อเสียคือคุณจะไม่สามารถเข้าถึง% ในฟังก์ชันภายนอกได้

ใช้fn [x]ไวยากรณ์แทน


1
ดังนั้น? ส่วนใหญ่เวลาที่ฉันไม่ต้องการเข้าถึง%fn ด้านนอกและในเวลาที่คุณทำคุณสามารถถอยกลับไป(fn)ใช่ไหม?
Zaz

10

มันไม่มีข้อ จำกัด มีสองบรรทัดใน parser ที่ปิดใช้งานอย่างชัดเจน หากคุณแก้ไขบรรทัดนั้นคุณสามารถมีฟังก์ชั่นที่ไม่ระบุตัวตนซ้อนกันและจะทำหน้าที่เหมือนที่คุณคาดหวัง

โดยเฉพาะบรรทัด 634-635 ใน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");
        // ...

คุณสามารถระบุบรรทัดใน parser และแสดงให้เห็นว่ารหัสเขียนใหม่เพื่อไม่ได้มีฟังก์ชั่นที่ซ้อนกัน anon และรหัสที่มีบรรทัดที่ถูกลบออกจาก parser และฟังก์ชั่นที่ซ้อนกัน anon ทำงานเหมือนกันหรือไม่

2
@MichaelT: ไปแล้ว และคุณสามารถทดสอบได้ มันง่ายที่จะทำเพราะคุณสามารถเปลี่ยนมันได้ที่รันไทม์ โปรแกรมแยกวิเคราะห์ Clojure นั้นสามารถแฮ็กได้ง่ายจริงๆ
amara

4
ดีไม่สมบูรณ์โดยพล; เว้นแต่ Rick Hickey เพิ่งจะมีวันโดยพลการต้องมีเหตุผลที่เขาวางไว้ในนั้นและคุณดูเหมือนจะไม่ทราบว่าเหตุผลนั้นคืออะไร ดุจ
Robert Harvey

ว้าวช่างเป็นอะไร! ดี - +1

การเปลี่ยนแปลงนี้จะทำให้เกิดการวิเคราะห์คำที่ซ้อนกันของวิธีการซ้อนกันหรือไม่ ฉันอยากรู้ว่าการfn [x]เขียนรหัส OP ใหม่จะมีฟังก์ชั่นที่เหมือนกันกับเวอร์ชั่น clojure ที่แก้ไขแล้ว นอกจากนี้จะมีปัญหาใด ๆ กับการพกพาของรหัส clojure หรือไม่

3

คุณสามารถมีฟังก์ชั่นที่ไม่ระบุชื่อที่ซ้อนกันของการจัดเรียง (fn [params] (body)) มีเพียง # ไวยากรณ์ที่ไม่สนับสนุนการซ้อน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.