Perché non possiamo scrivere funzioni stenografiche nidificate in Clojure?


11

Ho provato a valutare un'espressione Clojure con funzioni stenografiche nidificate oggi, e non me lo ha permesso.

L'espressione era:

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

L'output è stato:

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

2
trovo che non poter scrivere questo codice sia una buona cosa per il clojure.
Simon Bergot,

3
Perché ti fa sanguinare gli occhi.
Michael Shaw,

Non ti serve (# (+% 1 (# (+% 2 (*% 3% 4))% 5)) 5)?
Innova,

Risposte:


5

Sapresti che% appartiene alla funzione interna. Lo svantaggio è che si perderebbe l'accesso a% nella funzione esterna.

Utilizzare fn [x]invece la sintassi.


1
Così? Il più delle volte non ho bisogno di accedere a quello %dell'FN esterno, e nelle volte in cui lo hai fatto, potresti tornare indietro (fn), giusto?
Zaz,

10

È completamente arbitrario; ci sono un paio di righe nel parser che lo disabilitano esplicitamente. Se modifichi quella linea, puoi avere funzioni anonime nidificate e si comportano esattamente come ti aspetteresti.

in particolare, le righe 634-635 in 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");
        // ...

È possibile identificare la riga nel parser e dimostrare che il codice riscritto per non avere una funzione annidata anon e che il codice con la riga rimossa dal parser e una funzione annidata anon funziona allo stesso modo?

2
@MichaelT: eccoti. e puoi semplicemente provarlo; è facile da fare poiché puoi spegnerli in fase di esecuzione. il parser clojure è davvero abbastanza facilmente hackerabile
amara

4
Bene, non completamente arbitrario; a meno che Rick Hickey non abbia avuto una giornata arbitraria, ci deve essere stato un motivo per cui l'ha messo lì, e sembra che tu non sappia quale sia quella ragione. Duh.
Robert Harvey,

Wow, che scoperta! Bello - +1.

Questa modifica causerebbe analisi ambigue dei metodi nidificati? Sono curioso di fn [x]riscrivere il codice del PO con funzionalità identiche a una versione modificata del clojure. Inoltre, ci sarebbe qualche problema con la portabilità del codice clojure?

3

Puoi avere funzioni anonime nidificate del tipo (fn [params] (body)). Solo la sintassi # non supporta l'annidamento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.