| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| teaching:cc4101:tareas:2023-1:tarea2:parte3 [2023/05/11 16:21] – etanter | teaching:cc4101:tareas:2023-1:tarea2:parte3 [2023/05/11 16:50] (current) – [Parte 3. Estrategias de evaluación (2 ptos.)] tvallejos |
|---|
| La extensión de SL consiste en agregar //modificadores// a los tipos declarados por las funciones funciones, los que especifican el tipo de estrategia a utilizar para los argumentos. A continuación les proveemos una ilustración de este mecanismo y qué es lo que debieran obtener al finalizar esta sección. | La extensión de SL consiste en agregar //modificadores// a los tipos declarados por las funciones funciones, los que especifican el tipo de estrategia a utilizar para los argumentos. A continuación les proveemos una ilustración de este mecanismo y qué es lo que debieran obtener al finalizar esta sección. |
| <code scheme> | <code scheme> |
| ;; La función se declara de tipo (Num -> Num). Sin modificadores significa evaluación temprana. | ;; Una función de tipo Num -> Num significa que se aplicará con evaluación temprana. |
| > (run-p-sl '{with {f {fun {Num -> Num} {x} {+ x x}}} | > (run-p-sl '{with {f {fun {x : Num} -> Num : {+ x x}}} |
| {f {printn 10}}}) | {f {printn 10}}}) |
| (result 20 '("10")) ;; Se imprime una vez, al evaluar el argumento en la aplicación | (result 20 '("10")) ;; Se imprime una vez, al evaluar el argumento en la aplicación |
| |
| ;; La función se declara (lazy Num -> Num), es decir, se declara el argumento como lazy/call-by-need. | ;; Una función de tipo (lazy Num -> Num), usará evaluación lazy/call-by-need para su argumento. |
| > (run-p-sl '{with {f {fun {{lazy Num} -> Num} {x} {+ x x}}} | > (run-p-sl '{with {f {fun {x : {lazy Num}} -> Num : {+ x x}}} |
| {f {printn 10}}}) | {f {printn 10}}}) |
| (result 20 '("10")) ;; Se imprime una vez cuando se usa el argumento dentro del cuerpo | (result 20 '("10")) ;; Se imprime una vez cuando se usa el argumento dentro del cuerpo |
| |
| ;; La función se declara (name Num -> Num), es decir, se declara el argumento como name/call-by-name. | ;; Una función de tipo (name Num -> Num), usará evaluación name/call-by-name para su argumento. |
| > (run-p-sl '{with {f {fun {{name Num} -> Num} {x} {+ x x}}} | > (run-p-sl '{with {f {fun {x : {name Num}} -> Num : {+ x x}}} |
| {f {printn 10}}}) | {f {printn 10}}}) |
| (result 20 '("10" "10")) ;; Se imprime dos veces, una por cada uso que se hace del argumento, dentro del cuerpo | (result 20 '("10" "10")) ;; Se imprime dos veces, una por cada uso que se hace del argumento, dentro del cuerpo |
| |
| ;; Otro ejemplo de lazy. Note que efectivamente al evaluarla se comporta correctamente. | ;; Otro ejemplo de lazy. Note que efectivamente al evaluarla se comporta correctamente. |
| > (run-p-sl '{with {f {fun {{lazy Num} -> Num} {x} 1}} | > (run-p-sl '{with {f {fun {x : {lazy Num} -> Num : 1}}} |
| {f {printn 10}}}) | {f {printn 10}}}) |
| (result 1 '()) ;; No se imprime porque el argumento nunca se usa dentro del cuerpo | (result 1 '()) ;; No se imprime porque el argumento nunca se usa dentro del cuerpo |
| | <id> | | <id> |
| | {<SL> <SL>} | | {<SL> <SL>} |
| | {fun {<sym> : <mtype>} : <mtype> <SL>} ;; note el uso de mtype (tipos con modificadores) | | {fun {<sym> : <mtype>} → <mtype> : <SL>} ;; note el uso de mtype (tipos con modificadores) |
| | {printn <SL>} | | {printn <SL>} |
| |
| **Hint**: si bien en la sintaxis solo existen dos modificadores, internamente es más conveniente tener 3 (incluyendo uno para eager), así todo tipo tiene un modificador. | **Hint**: si bien en la sintaxis solo existen dos modificadores, internamente es más conveniente tener 3 (incluyendo uno para eager), así todo tipo tiene un modificador. |
| |
| **Observaciones**: | <note tip> |
| * Se puede pensar ''lazy X'' y ''name X'' como el tipo de las promesas que producen ''X''. | * Se puede pensar ''lazy X'' y ''name X'' como el tipo de las promesas que producen ''X''. |
| * Note la definición mutuamente recursiva entre ''<type>'' y ''<mtype>''. Esta definición nos permite crear (entre otros tipos) funciones de tipo ''(lazy Num) -> (name Num)'', es decir, una función que toma como argumento una expresión que produce un Num (sin evaluarla, y la evalua de manera lazy si es necesario), y retorna una expresión que produce un Num (sin evaluarla, y deberá ser evaluada tantas veces como sea utilizada). | * Note la definición mutuamente recursiva entre ''<type>'' y ''<mtype>''. Esta definición nos permite crear (entre otros tipos) funciones de tipo ''(lazy Num) -> (name Num)'', es decir, una función que toma como argumento una expresión que produce un Num (sin evaluarla, y la evalua de manera lazy si es necesario), y retorna una expresión que produce un Num (sin evaluarla, y deberá ser evaluada tantas veces como sea utilizada). |
| | </note> |
| ---- | ---- |
| |
| * Una forma de retrasar la evaluación de una expresión ''%%e%%'', es ponerla en el cuerpo de una lambda ''%%(lambda (_) e)%%''. Luego para evaluarla basta aplicar la función. | * Una forma de retrasar la evaluación de una expresión ''%%e%%'', es ponerla en el cuerpo de una lambda ''%%(lambda (_) e)%%''. Luego para evaluarla basta aplicar la función. |
| * Si se requiere una evaluación temprana y el argumento fue declarado lazy o by-name, entonces es necesario ajustarlo para que efectivamente se evalúe en ese punto. | * Si se requiere una evaluación temprana y el argumento fue declarado lazy o by-name, entonces es necesario ajustarlo para que efectivamente se evalúe en ese punto. |
| * Si tanto la función como el argumento calzan en la estrategia, entonces no es necesario hacer cambios. | * Si tanto la función como el argumento calzan en la estrategia, entonces no hay nada que hacer. |
| * Recuerde que la diferencia entre lazy y by-name es que la primera evalúa una sola vez la expresión y luego "recuerda" el valor para próximos usos. Acuérdese de lo realizado en la Parte 1 con funciones memoizadas! | * Recuerde que la diferencia entre lazy (a.k.a. by-need) y by-name es que la primera evalúa una sola vez la expresión y luego "recuerda" el valor para próximos usos. Acuérdese de lo realizado en la Parte 2 con funciones memoizadas! |
| |
| </note> | </note> |
| |
| |