Sei sulla pagina 1di 9

6 De Sustitucin de Ambientes

Aunque tenemos una definicin de trabajo de las funciones, se puede sentir un ligero malestar al
respecto. Cuando el intrprete ve un identificador, que podra haber tenido la sensacin de que
tiene que "mirar hacia arriba". No slo no levant nada, definimos su comportamiento es un
error! Si bien toda la razn, esto tambin es un poco sorprendente. Ms importante an,
escribimos intrpretes para entender y explicar idiomas, y esta implementacin puede parecerle
no hacer eso, porque no coincide con nuestra intuicin.

Hay otra dificultad con el uso de sustitucin, que es el nmero de veces que atravesamos el
programa fuente. Sera bueno tener que atravesar slo aquellas partes del programa que
realmente se evala, y luego, slo cuando sea necesario. Pero la sustitucin atraviesa ramas todono visitados de condicionales, por ejemplo-y obliga al programa a desplazar una vez por
sustitucin y una vez ms para la interpretacin.

Ejercicio
Tiene la sustitucin tiene implicaciones para la complejidad momento de la evaluacin?

Hay otro problema con la sustitucin, que es que se define en trminos de representaciones de la
fuente de programa. Obviamente, nuestro intrprete tiene necesidades y el acceso a la fuente,
para interpretarlo. Sin embargo, otras implementaciones-tales como compiladores, no tienen
necesidad de almacenarla para ese propsito.
Los compiladores pueden almacenar versiones de o informacin acerca de la fuente por otras
razones, tales como la presentacin de informes de errores de tiempo de ejecucin, y equipos
conjuntos de investigacin pueden que tenga que volver a compilar bajo demanda.
Sera bueno emplear un mecanismo que es ms portable a travs de estrategias de
implementacin.

6.1 Al presentar el Medio Ambiente

La intuicin que se ocupa de la primera preocupacin es que el intrprete de "mirar hacia arriba"
un identificador en una especie de directorio. La intuicin de que se dirige a la segunda
preocupacin es aplazar la sustitucin. Afortunadamente, estos convergen bien de una manera
que tambin se ocupa de la tercera. El directorio registra la intencin de sustituir, sin tener que
volver a escribir la fuente de programa; mediante el registro de la intencin, en lugar de sustituir
de inmediato, podemos aplazar la sustitucin; y la estructura de datos resultante, que se llama un
medio ambiente, evita la necesidad de reescritura fuente-a-fuente y los mapas de muy bien a las

representaciones de la mquina de bajo nivel. Cada asociacin nombre en el medio ambiente se


llama unin.

Observe cuidadosamente que lo que estamos cambiando es la estrategia de ejecucin para el


lenguaje de programacin, no el lenguaje mismo. Por lo tanto, ninguno de nuestros tipos de datos
para los programas que representan debe cambiar, ni siquiera deberan las respuestas que el
intrprete ofrece. Como resultado de ello, debemos pensar en el intrprete anterior como
"implementacin de referencia" que el que estamos a punto de escribir debe coincidir. De hecho,
deberamos crear un generador que crea un montn de pruebas, los ejecuta a travs de ambos
intrpretes, y se asegura de sus respuestas son las mismas. Idealmente, deberamos demostrar
que los dos intrpretes se comportan de la misma, que es un buen tema para el estudio avanzado.
Una sutileza est en definir con precisin lo que "los mismos" significa, especialmente con
respecto a fracaso.
Primero vamos a definir nuestra estructura de datos medio ambiente. Un entorno es una lista de
pares de nombres asociado con ... qu?

Hacer Ahora!
Una pregunta natural que aqu podra ser lo que los mapas del entorno nombres. Pero un mundo
mejor, ms fundamental, la pregunta es: Cmo determinar la respuesta a la pregunta "natural"?

Recuerde que nuestro entorno se ha creado aplazar sustituciones. Por lo tanto, la respuesta est
en la sustitucin. Hemos discutido anteriormente (Oh Espera, an hay ms!) Que queremos
sustitucin para asignar nombres a las respuestas, lo que corresponde a una estrategia de
aplicacin de funcin ansiosos. Por lo tanto, el medio ambiente debe asignar nombres a las
respuestas.

(Define tipo de encuadernacin


[Bind (nombre: smbolo) (val: nmero)])

(Define-tipo-alias Env (listof Binding))


(Define mt-env vaco)
(Define contras extender-env)
6.2 Interpretacin de Ambientes

Ahora podemos hacer frente a la intrprete. Uno de los casos es fcil, pero debemos revisar todos
los dems:

<*> :: =
(Define (interp [expr: ExprC] [env: Env] [fds: (FunDefC listof)]): Nmero
(Tipo caso ExprC expr
[NUMC (n) n]
<IDC-case>
<AppC caso>
<PlusC / multC caso>))
Las operaciones aritmticas son las ms fciles. Recordemos que antes, el intrprete se repiti sin
realizar nuevas sustituciones. Como resultado, no hay nuevas sustituciones diferidos para llevar a
cabo, ya sea, lo que significa que el medio ambiente no cambia:

<PlusC / multC caso> :: =


[PlusC (id) (+ (interp l env fds) (interp fds r env))]
[MultC (id) (* (interp l env fds) (interp fds r env))]
Ahora vamos a manejar identificadores. Claramente, encontrndose con un identificador ya no es
un error: se trataba de la misma motivacin para este cambio. En su lugar, debemos buscar su
valor en el directorio:

<IDC-case> :: =
[IDC (n) (bsqueda n env)]

Hacer Ahora!
Implementar las operaciones de bsqueda.

Finalmente, la solicitud. Observe que en el intrprete de sustitucin, el nico caso que caus
nuevas sustituciones que se produzcan era de aplicacin. Por lo tanto, este debe ser el caso que
construye enlaces. Primero vamos a extraer la definicin de funcin, al igual que antes:

<AppC caso> :: =
[AppC (bis) (local ([definir fd (fds f conseguir-FUNDEF)])
<AppC-interp>)]
Anteriormente, sustituimos, entonces interpretamos. Debido a que no tenemos ninguna etapa de
sustitucin, podemos proceder con la interpretacin, siempre y cuando grabamos el aplazamiento
de la sustitucin.

<AppC-interp> :: =
(Interp (FDC-cuerpo fd)
<AppC-interp-bind-en-env>
fds)
Es decir, el conjunto de definiciones de funciones se mantiene sin cambios; estamos interpretar el
cuerpo de la funcin, como antes; pero tenemos que hacerlo en un entorno que se une el
parmetro formal. Ahora vamos a definir ese proceso de unin:

<AppC-interp-bind-en-env-tomar-1> :: =
(Extender-env (bind (FDC-arg fd)
(Interp un fds env))
env)
el nombre est ligado es el parmetro formal (el mismo nombre que fue sustituido por, antes). Se
ve obligada a interpretar el resultado de la discusin (porque hemos decidido en una semntica de
aplicacin ansiosos). Y, por ltimo, esto se extiende al medio ambiente que ya tenemos. Tipo de
comprobacin de esto ayuda a asegurarse de que llegamos todos los pequeos pedazos derecha.

Una vez que tengamos una definicin para las operaciones de bsqueda, nos gustara tener un
intrprete completo. As que aqu est uno:

(Define (bsqueda [para: smbolo] [env: Env]): Nmero


(Cond
[(Env vaco?) (Error de "bsqueda" nombre no encontrado ")]
[Ms (cond
[(Smbolo = para (bind-nombre (primero env)))

(Bind-val (primera env))]


[Ms (operaciones de bsqueda para (env resto))])]))
Observe que buscar un identificador libre todava produce un error, pero se ha movido desde el
intrprete, que es por s mismo incapaz de determinar si o no un identificador es libre para buscar,
que determina esta basado en el contenido del medio ambiente.

Ahora tenemos una intrprete completa. Usted debe, por supuesto, probarlo asegrese de que
funciona como era de esperar. Por ejemplo, estas pruebas pasan:

(Prueba (interp (plusC (NUMC 10) (appC 'const5 (NUMC 10)))


mt-env
(Lista ('const5' _ FDC (NUMC 5))))
15)

(Prueba (interp (plusC (NUMC 10) (APPC "doble (plusC (NUMC 1) (NUMC 2))))
mt-env
(Lista (FDC 'doble' x (plusC (IDC 'x) (IDC' x)))))
16)

(Prueba (interp (plusC (NUMC 10) (cudruple appC '(plusC (NUMC 1) (NUMC 2))))
mt-env
(Lista ('cudruple' FDC x ('doble (APPC "doble (x IDC appC))))
(FDC 'doble' x (x) (IDC plusC (IDC x)))))
22)
As que hemos terminado, no?

Hacer Ahora!
Detectar el error.

6.3 Aplazar correctamente

He aqu otra prueba:


(Interp (appC 'f1 (NUMC 3))
mt-env
(Lista (x FDC 'F1' (f2 appC '(NUMC 4)))
(Y FDC 'F2' (plusC (IDC 'x) (IDC y)))))
En nuestro intrprete, ste evala a 7. En caso de que?

Traducido a la raqueta, esta prueba corresponde a las dos definiciones y expresiones siguientes:

(Define (f1 x) (f2 4))


(Define (f2 y) (x + y))

(F1 3)
Lo que debe producir esto? (F1 3) sustitutos x con 3 en el cuerpo de f1, que luego se invoca (f2 4).
Pero sobre todo, en f2, el identificador x no est obligada! Efectivamente, Raqueta producir un
error.

De hecho, tambin lo har nuestro intrprete basado sustitucin!

Por qu el resultado del proceso de sustitucin en un error? Es porque, cuando reemplazamos la


representacin de x con la representacin de las 3 de la representacin de f1, lo hacemos en f1
solamente.
Este "la representacin de" es conseguir un poco molesto, verdad? Por lo tanto, voy a dejar de
decir eso, pero asegrese de entender por qu tena que decirlo. Es un poco importante de la
pedantera.
(Obviamente: x es el parmetro de la F1, incluso si otra funcin tena un parmetro llamado x, eso
es un x diferente.) Por lo tanto, cuando lleguemos a evaluar el cuerpo de f2, la x no ha sido
sustituido, lo que resulta en el error.

Qu sali mal cuando nos cambiamos a entornos? Mira con atencin: esto es sutil. Podemos
centrarnos en aplicaciones, porque slo afectan al medio ambiente. Cuando sustituimos el formal

para el valor del real, lo hicimos mediante la ampliacin del entorno actual. En trminos de
nuestro ejemplo, le preguntamos al intrprete para sustituir sustitucin no slo de f2 en el cuerpo
de f2, sino tambin a los actuales (aquellos de la persona que llama, f1), y de hecho todos los
anteriores tambin. Es decir, el medio ambiente slo crece; nunca se contrae.

Porque de acuerdo en que los entornos son slo una estrategia de implementacin alternativa
para la sustitucin y, en particular, que el significado de la lengua no debe cambiar, tenemos que
modificar el intrprete. En concreto, no debemos pedirle que llevar todos los ltimos solicitudes
de sustitucin diferidos, pero en vez que sea empezar de nuevo para cada nueva funcin, al igual
que el intrprete basado sustitucin hace. Este es un cambio fcil:

<AppC-interp-bind-en-env> :: =
(Extender-env (bind (FDC-arg fd)
(Interp un fds env))
mt-env)
Ahora hemos reproducido verdaderamente el comportamiento del intrprete de sustitucin.
En caso de que usted se est preguntando cmo escribir un caso de prueba que las capturas de
errores, levant la prueba / EXN.

6.4 Alcance

El entorno de intrprete rota anteriormente implementa lo que se conoce como el alcance


dinmico. Esto significa que el entorno se acumula fijaciones como el programa ejecuta. Como
resultado, si un identificador est obligado incluso depende de la historia de la ejecucin del
programa. Debemos considerar esto inequvocamente como un defecto de diseo de lenguajes de
programacin. Afecta negativamente a todas las herramientas que leen y programas de proceso:
compiladores, IDEs, y seres humanos.

En cambio, sustitucin y ambientes, hecho que nos correctamente-dan mbito lxico o alcance
esttico. "Lxico" en este contexto significa "determinado a partir del programa de origen",
mientras que "esttica" en informtica significa "sin ejecutar el programa", por lo que estos estn
apelando a la misma intuicin. Cuando examinamos un identificador, queremos saber dos cosas:
(1) Est obligado? (2) Si es as, dnde? Por "donde" queremos decir: si hay varios enlaces para el
mismo nombre, que se rige este identificador? Dicho de otra manera, que la sustitucin de uno le
dar un valor a este identificador? En general, estas preguntas no pueden ser respondidas de

forma esttica en un idioma de forma dinmica con mbito: por lo que su IDE, por ejemplo, no
puede superponer flechas para mostrarles esta informacin (como lo hace DrRacket).
Una manera diferente de pensar en ello es que en un idioma de forma dinmica con mbito, la
respuesta a estas preguntas es la misma para todos los identificadores, y simplemente se refiere al
entorno dinmico. En otras palabras, no proporciona ninguna informacin til.
Por lo tanto, a pesar de que las normas de alcance se hacen ms complejos como el espacio de
nombres se hace ms ricos (por ejemplo, objetos, hilos, etc.), siempre debemos esforzarnos por
preservar el espritu de determinacin del alcance esttico.

6.4.1 Qu tan grave es?


Usted puede mirar en nuestro ejemplo correr y preguntarnos si estamos creando una tempestad
en un vaso de agua. A cambio, usted debe considerar dos situaciones:
Para entender la estructura de unin de su programa, es posible que tenga que buscar en todo el
programa. No importa lo mucho que has descompuesto su programa en pequeos fragmentos,
comprensibles, no importa si usted tiene un identificador de conexin en cualquier lugar.

La comprensin de la estructura de unin no es slo una funcin del tamao del programa, sino
tambin de la complejidad de su flujo de control. Imagina un programa interactivo con numerosos
servicios repetidos; usted tendra que realizar un seguimiento a travs de cada uno de ellos,
tambin, para saber qu unin gobierna un identificador.

Necesita un poco ms de un empujn? Vamos a sustituir la expresin de nuestro programa de


ejemplo con ste:
(Si (luna visible?)
(F1 10)
(F2 10))
Supongamos-moon visible? es una funcin que, presumiblemente, se evala como falsa en las
noches de luna nueva y verdadera en otros momentos. Entonces, este programa se evaluar como
una respuesta, excepto en las noches de luna nueva, cuando se fallar con un error de
identificacin no unido.
Ejercicio
Lo que pasa en las noches nubladas?

6.4.2 El alcance de nivel superior

Materia se vuelven ms complejas cuando contemplamos las definiciones de nivel superior en


muchos idiomas. Por ejemplo, algunas versiones de esquema (que es un dechado de mbito
lxico) le permiten escribir esto:
(Definir y 1)
(Define (f x) (x + y))
que parece sugerir con bastante claridad que el y en el cuerpo de f vendr, excepto:
(Definir y 1)
(Define (f x) (x + y))
(Definir y 2)
es legal y (f 10) produce 12. Espere, se podra pensar, siempre tienen la ltima! Pero:
(Definir y 1)
(Define f (let ((z y)) (lambda (x) (x y z))))
(Definir y 2)
Aqu, z se une a la primera valor de y mientras que el interior y se une a la segunda valor.
La mayora de los lenguajes de scripting "" presentan problemas similares. Como resultado, en la
web se encuentra una enorme confusin sobre si un determinado lenguaje es statically- o
dinmicamente con mbito, cuando en realidad los lectores estn comparando el
comportamiento dentro de funciones (a menudo estticos) en contra de la de nivel superior (por
lo general dinmico). Cuidado!
En realidad, hay una explicacin vlida de este comportamiento en trminos de alcance lxico,
pero puede llegar a ser complicado, y tal vez una opcin ms sensata es prevenir tales
redefinicin. Raqueta hace precisamente esto, lo que ofrece la comodidad de un nivel superior sin
su dolor.
6.5 La exposicin del Medio Ambiente

Si estbamos construyendo la ejecucin para que otros puedan utilizar, sera sabio y una cortesa
para el intrprete exportado a tomar slo una expresin y una lista de definiciones de funciones, e
invocar nuestra interp definido con el medio vaca. Esto tanto ahorra usuarios un detalle de
implementacin, y evita el uso de un intrprete con un entorno incorrecta. En algunos contextos,
sin embargo, puede ser til para exponer el parmetro de entorno. Por ejemplo, el medio
ambiente puede representar un conjunto de enlaces predefinidos: por ejemplo, si el idioma desea
proporcionar pi obligado automticamente a 3,2 (en Indiana).

Potrebbero piacerti anche