Pergunta

Eu gostaria de ter uma versão lambda, chamado lambda-r, de dentro do qual você pode return.Um exemplo:

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

Isso daria o valor 6.Embora você possa esperar que o valor seja 7, ele é 6 porque 1 é retornado da expressão lambda antes de 2 ser alcançado.

Aqui está um exemplo do tipo de transformação que procuro.Digamos que alguém usasse lambda-r do seguinte modo:

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

Eu quero que seja transformado assim:

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

Isso também poderia ser expresso com uma expressão let em vez de uma definição interna, mas estou usando a definição para maior clareza.

Observe que o código acima realmente funciona conforme o esperado. O problema é que estou tendo problemas para expressar lambda-r como um macro.A razão é que eu quero k e v ser higiênico, mas não quero return para ser higiênico.

Minha macro no momento é esta:

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

O que não funciona porque return é tratado de forma higiênica e, como resultado, não é diretamente visível ao usar lambda-r.Então (lambda-r () (return 1)) dá um erro que diz que return não é um identificador válido.


Editar:Graças à resposta de Nathan Sanders, estou mais perto de entender o que tenho que fazer aqui.No entanto, não entendo completamente os procedimentos a seguir e, como resultado, ainda não consegui fazer isso funcionar.Eu realmente apreciaria se você pudesse me explicar/direcionar para recursos que explicam o seguinte:

  • o syntax procedimento
  • o datum->syntax/syntax->datum procedimentos

Editar:Deixa pra lá - agora entendi :)

Foi útil?

Solução

O que você quer é syntax-case em vez de syntax-rules.

A definição R6RS dá alguns exemplos, nomeadamente uma seção sobre conversões de objetos de sintaxe e dados, que é o que você deseja.Você deve ser capaz de adaptar o loop c/ break exemplo para o seu return.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top