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

완전히 임의적입니다. 파서에는 명시 적으로 비활성화하는 몇 줄이 있습니다. 해당 줄을 편집하면 중첩 된 익명 함수를 가질 수 있으며 예상대로 정확하게 작동합니다.

특히 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java의 634-635 행

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");
        // ...

파서에서 줄을 식별하고 코드에 anon 중첩 함수가 없도록 다시 작성했으며 파서에서 줄을 제거한 코드와 anon 중첩 함수가 동일하게 작동한다는 것을 보여 줄 수 있습니까?

2
@MichaelT : 당신은 간다. 테스트 만하면됩니다. 런타임에 스위치를 끌 수 있기 때문에 수행하기 쉽습니다. clojure 파서는 정말 쉽게 해킹 가능하다
amara

4
글쎄, 완전히 임의적 이지는 않습니다 . Rick Hickey가 임의의 날을 보내지 않았다면 그가 거기에 넣은 이유가 있었을 것입니다. 그리고 그 이유가 무엇인지 모르는 것 같습니다. 어.
Robert Harvey

와우 니스-+1

이 변경으로 인해 중첩 된 메소드가 모호하게 구문 분석됩니까? fn [x]OP 코드를 다시 작성하여 수정 된 clojure 버전과 동일한 기능을 갖게 될지 궁금 합니다. 또한 클로저 코드의 이식성에 문제가 있습니까?

3

(fn [params] (body)) 정렬의 중첩 된 익명 함수를 가질 수 있습니다. # 구문 만 중첩을 지원하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.