Ejercicio de evaluación de expresiones en Scheme con ambientes¶
Considere el ambiente inicial env0:
(x, y, z, f)
(9, 10, 11, closure (a, b) if >(a, b) then a else b empty-env)
Se tiene el siguiente programa en Scheme:
let
u = (f x y) ; Aplica f a x=9 e y=10 → resultado 10 (mayor entre 9 y 10)
v = (f y z) ; Aplica f a y=10 y z=11 → resultado 11 (mayor entre 10 y 11)
p = 6 ; Define p como 6
in
letrec
f(x, y) = if >(x, 0) ; Función recursiva f definida con letrec
then +(y, (g -(x, 2) +(y, 1))) ; Si x>0, suma y con el resultado de g(x-2, y+1)
else +(u, v) ; Si x≤0, retorna u+v = 10+11 = 21
g(m, n) = if >(m, 0) ; Función recursiva g definida con letrec
then +(n, (f sub1(m) +(n, 2))) ; Si m>0, suma n con el resultado de f(m-1, n+2)
else *(u, v) ; Si m≤0, retorna u*v = 10*11 = 110
in
+((f 20 p), (proc (x, y) +(x, y) u v)) ; Suma: (f 20 6) + (procedimiento anónimo aplicado a u y v)
Resultado final: 323
Cadena de ambientes (entornos)¶
graph TD
A["empty-env"] --> B["env0
x y z f
9 10 11 (closure ... empty-env)"]
B --> C["env1
u v p
10 11 6"]
A --> F1["envprocf1
a b
9 10"]
A --> F2["envprocf1
a b
10 11"]
C --> D["envR2
(f g)
((x y) (m n))
(if.. if...)"]
D --> FF1["envrf1 x y 20 6"]
D --> G1["envrg1 n m 18 7"]
D --> FF2["envrf2 x y 17 9"]
D --> G2["envrg2 n m 15 10"]
D --> FF3["envrf3 x y 14 12"]
D --> G3["envrg3 n m 12 13"]
D --> FF4["envrf4 x y 11 15"]
D --> G4["envrg4 n m 9 16"]
D --> FF5["envrf5 x y 8 18"]
D --> G5["envrg5 n m 6 19"]
D --> FF6["envrf6 x y 5 21"]
D --> G6["envrg6 n m 3 22"]
D --> FF7["envrf7 x y 2 23"]
D --> G7["envrg7 n m 0 24"]
D --> H["envprocfinal
x y
10 11"]
Explicación paso a paso¶
-
En
env0evaluamos(f x y)y(f y z). Al evaluar(f 9 10)y(f 10 11)se generan dos ambientes temporales (envprocf1yenvprocf2) que extiendenempty-envcon los parámetrosayb. La funciónforiginal es una clausura que retorna el mayor de dos números. -
Sobre el ambiente
envR2(creado porletrec) evaluamos+((f 20 p), (proc (x,y) +(x,y) u v)). La evaluación procede de izquierda a derecha:
a. (f 20 6) en envrf1: +(y, #2) = +(6, 296) = 302
b. (g 18 7) en envrg1: +(n, #3) = +(7, 289) = 296
c. (f 17 9) en envrf2: +(y, #4) = +(9, 280) = 289
d. (g 15 10) en envrg2: +(n, #5) = +(10, 270) = 280
e. (f 14 12) en envrf3: +(y, #6) = +(12, 258) = 270
f. (g 12 13) en envrg3: +(n, #7) = +(13, 245) = 258
g. (f 11 15) en envrf4: +(y, #8) = +(15, 230) = 245
h. (g 9 16) en envrg4: +(n, #9) = +(16, 214) = 230
i. (f 8 18) en envrf5: +(y, #10) = +(18, 196) = 214
j. (g 6 19) en envrg5: +(n, #11) = +(19, 177) = 196
k. (f 5 21) en envrf6: +(y, #12) = +(21, 156) = 177
l. (g 3 22) en envrg6: +(n, #13) = +(22, 134) = **156** ← Error corregido: era 155, debe ser 156
m. (f 2 23) en envrf7: +(y, #14) = +(23, 110) = 133
n. (g 0 24) en envrg7: Aquí m=0, por lo que se evalúa la rama else que retorna *(u, v) = 10*11 = 110
3. Evaluamos en envR2 la expresión (proc (x,y) +(x,y) u v). Esto genera:
((closure (x,y) +(x,y) envR2) 10 11)
envprocfinal que extiende envR2 con x=10 e y=11. Al evaluar +(x, y) en este ambiente obtenemos 10+11 = 21.
- Finalmente, resolvemos:
+((f 20 p), (proc (x,y) +(x,y) u v)) +(302, 21) 323
Conceptos teóricos relevantes¶
- Ambiente (environment): Estructura que asocia identificadores (variables) con sus valores. Cada extensión crea un nuevo ambiente que hereda las asociaciones del padre.
- Clausura (closure): Estructura que encapsula una función junto con su ambiente de definición, permitiendo el acceso a variables no locales.
letrec: Constructo que permite definiciones mutuamente recursivas. A diferencia delet, las funciones definidas enletrecpueden referenciarse entre sí.- Evaluación de aplicaciones de procedimientos: Sigue la regla de crear un nuevo ambiente extendiendo el ambiente de la clausura con los parámetros formales vinculados a los argumentos actuales.
- Recursión mutua: Patrón donde dos o más funciones se llaman entre sí, como
fygen este ejemplo.
Tabla de resumen de conceptos¶
| Concepto | Descripción | Ejemplo en el ejercicio |
|---|---|---|
| Ambiente inicial | Entorno base con definiciones iniciales | env0 con x=9, y=10, z=11, f=closure |
| Clausura | Función + ambiente de definición | closure (a,b) if >(a,b) then a else b empty-env |
let |
Constructo para definiciones locales no recursivas | let u = (f x y) v = (f y z) p = 6 in ... |
letrec |
Constructo para definiciones recursivas mutuas | letrec f(x,y)=... g(m,n)=... |
| Recursión mutua | Funciones que se llaman entre sí | f llama a g, y g llama a f |
| Aplicación de procedimiento | Evaluación de una función con argumentos | (f 20 p), (proc (x,y) +(x,y) u v) |
| Extensión de ambiente | Creación de nuevo ambiente a partir de uno existente | envrf1 extiende envR2 con x=20, y=6 |
| Evaluación condicional | Uso de if para control de flujo |
if >(x,0) then ... else ... |
| Procedimiento anónimo | Función sin nombre definida en línea | (proc (x,y) +(x,y) u v) |
Comentarios adicionales¶
- La evaluación de
(f 20 6)demuestra cómo la recursión mutua genera una secuencia de llamadas alternadas entrefyg, decrementando los valores de los parámetros hasta alcanzar el caso base. - El uso de
letreces esencial aquí, ya queletno permitiría la referencia mutua entrefyg. - La clausura original
f(la que retorna el máximo) es "sombreada" (shadowed) por la nueva definición defen elletrec, lo cual es permitido en Scheme. - La evaluación del procedimiento anónimo
(proc (x,y) +(x,y) u v)muestra cómo los argumentosuyv(con valores 10 y 11) se vinculan a los parámetrosxeyrespectivamente. - El resultado final 323 se obtiene de la suma de 302 (resultado de la recursión mutua) y 21 (resultado del procedimiento anónimo).