Domanda

Mi piacerebbe averne una versione lambda, chiamato lambda-r, dall'interno del quale puoi return.Un esempio:

(+ ((lambda-r ()
    (return 1)
    2)) 5)

Questo darebbe il valore 6.Anche se potresti aspettarti che il valore sia 7, è 6 perché 1 viene restituito dall'espressione lambda prima che venga raggiunto 2.

Ecco un esempio del tipo di trasformazione che sto cercando.Diciamo che uno dovesse essere usato lambda-r come segue:

(lambda-r (a b)
    (return a)
    (+ a b))

Voglio che sia trasformato in questo modo:

(call/cc (lambda (k)
       (define return (lambda (v)
                        (k (lambda (a b)
                             v))))
       (lambda (a b)
         (return a)
         (+ a b))))

Ciò potrebbe anche essere espresso con un'espressione let invece che con una definizione interna, ma sto usando la definizione per motivi di chiarezza.

Tieni presente che il codice sopra funziona effettivamente come previsto. Il problema è che ho difficoltà ad esprimermi lambda-r come un macro.Il motivo è che voglio k E v per essere igienico, ma non voglio return essere igienico.

La mia macro al momento è questa:

(define-syntax lambda-r
  (syntax-rules (return)
    [(_ (var ...) body ...)
     (call/cc (lambda (k)
           (define return (lambda (v)
                            (k (lambda (var ...)
                                 v))))
           (lambda (var ...)
             body ...)))
     ]))

Il che non funziona perché return viene trattato igienicamente e di conseguenza non è direttamente visibile durante l'uso lambda-r.COSÌ (lambda-r () (return 1)) dà un errore che dice questo return non è un identificatore valido.


Modificare:Grazie alla risposta di Nathan Sanders, sono più vicino a capire cosa devo fare qui.Tuttavia, non comprendo appieno le seguenti procedure e, di conseguenza, non sono ancora riuscito a farlo funzionare.Apprezzerei davvero se potessi spiegarmi/indirizzarmi a risorse che spiegano quanto segue:

  • IL syntax procedura
  • IL datum->syntax/syntax->datum procedure

Modificare:Non importa, ora ho capito :)

È stato utile?

Soluzione

Quello che vuoi è syntax-case invece di syntax-rules.

La definizione R6RS fornisce alcuni esempi, in particolare una sezione sulle conversioni sintassi-oggetto e dato, che è quello che vuoi.Dovresti essere in grado di adattare il loop con/ break esempio al tuo return.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top