Skip to content
This repository has been archived by the owner on Aug 10, 2024. It is now read-only.

Commit

Permalink
Adding new class
Browse files Browse the repository at this point in the history
  • Loading branch information
renatocf committed May 27, 2014
1 parent f5a89c0 commit 35a0cc7
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 2 deletions.
2 changes: 0 additions & 2 deletions 15.01-Host_language
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,3 @@ Então:
)))

(define (lookup [name : symbol] [e : Env]) (e name))

Esquematicamente
24 changes: 24 additions & 0 deletions 20.01-cps
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Continuation Passing Style
============================

Umexemplo simples de CPS possível seriafazer a soma passo a passo:
(+ a b)

(λ (k) ((cps a) (λ (av) ((cps b) (λ (bv) (k (+ av bv)))))))
^^^^^^^ ^^^^ ^^^^^^^ ^^^^ ^^^^^^^^^
(1) (2) (3) (4) (5)

1) Primeiro, calculamos o argumento 'a' da soma. O resultado será um
lambda que aceita uma continuação;
2) O valor calculado em 'a' será passado para a continuação - e salvo
no labmda com a associação de do da computação com av;
3) A continuação comeva calculando o argumento 'b' da soma. O resultado
será um lambda que aceita uma continuação;
4) O valor calculado em 'b' será passado para a continuação - e salvo
na lambda com a associação do resultado da computação com bv;
5) Usando 'av' e 'bv', realizamos a última computação (somar av com
bv, o primeiro salvo no environment desse lambda). O resultado deve
ser aplicado na continuação global da expressão: k.

Se quiséssemos apenas EXECUTAR, então poderíamos executar esta
continuação passando 'k' como a função identidade.
87 changes: 87 additions & 0 deletions 20.02-cps_in_the_core
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
CPS MONTADO NO CORE
=====================

Como poderíamos fazer para alterar a nossa última linguagem, de modo a
criar CPS? Simples: a partir da árvore, vamos interpretá-la construindo
estruturas em CPS. Precisaremos passar, a cada uma das interpretações,
qual é a CONTINUAÇÃO.

(define-type Value
[closV (f : ((Value -> Value) : Value))]
)

(define (interp/k [expr : ExprC] [env : Env] [k : (Value -> Value)]) Value
(type-case ExprC expr
[numC (n) (k (numV n))]
[idC (n) (k (lookup n env))]

; Precisamos:
; 1. Calcular o valor de f (intepretar a expressão f). Passamos
; o environment corrente + uma continuação.
; 2. Armazenar o resultado de f, guardando esse valor num λ
; 3. Calcular o valor de a (interpretar a expressão a). Passamos
; o environment corrente + uma continuação.
; 4. Guardamos o valor interpretado de a em f
; 5. Por último, aplicamos a closure, passando:
; 5.1. av como argumento principal
; 5.2. k como continuação, para computar o restante
[appC (f a) (interp/k f env (lambda (fv)
(interp/k a env
(lambda (av) (closV-f fv) av k)
)))
]

; Não precisamos passar uma continuação com num+. Como ele não faz
; mais nada - ele é um caso básico - não precisamos passar o k para
; lá. Numa função qualquer, que poderia ter mais chamadas de
; funções, precisaríamos PASSAR esta continuação porque a função
; vai para o outro lugar.
[plusC (l r) (interp/k l env (lambda (lv)
(interp/k r env (lambda (rv)
(k (num+ lv rv))
))
))
]

; Análogo ao caso acima
[multC (l r) (interp/k l env (lambda (lv)
(interp/k r env (lambda (rv)
(k (num* lv rv))
))
))
]

; Análogo aos casos acima
[ifC (c y n) (interp/k c env (lambda (cv)
(if (zero? (numV-n cv))
(interp/k n env (lambda (nv) (k nv)))
(interp/k y env (lambda (yv) (k yv)))
)))
]

; No lambda, o processo segue os mesmos princípios:
; 1. Nosso valor de retorno será um closV, que recebe como
; argumento uma função de Valor em Valor
; 2. A função criada terá dois argumentos: um valor de argumento
; (o argumento tradicional) e uma nova continuação (dyn-k).
; NÃO usamos k, pois ele é uma continuação na construção de
; expressões. Caso nossa interpretação final tivesse como
; valor de retorno apenas um lambda, por exemplo, teríamos
; um lamda que está no estilo CPS.
; 3. O corpo do lambda será a conversão para o estilo CPS
; (interpretação) do argumento 'b'. Ele deverá ter como
; environment o environment EXTENDIDO com a associação de
; 'a' a 'arg-val'. Essa interpretação, porém, deverá ocorrer
; sobre a continuação dyn-k.
[lamC (a b) (k (closV (lambda (arg-val dyn-k)
(interp/k b
(extend-env (bind a arg-val) env) dyn-k))
))]
))

O interpretador muda pouco:
(define (interp [e : ExprC]) : ExprC
(interp/k e mt-env identity))

Sendo a função identidade a base da recursão, que não faz nada:
(define (identity [i : ExprC] i))

0 comments on commit 35a0cc7

Please sign in to comment.