Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
teaching:cc4101:tareas:2023-1:tarea2:parte3 [2023/05/11 15:24] – created tvallejosteaching:cc4101:tareas:2023-1:tarea2:parte3 [2023/05/11 16:50] (current) – [Parte 3. Estrategias de evaluación (2 ptos.)] tvallejos
Line 7: Line 7:
 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
Line 41: Line 41:
          | <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>}
  
Line 60: Line 60:
 **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>
-  * 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). +
   * 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 también que los modificadores solo se pueden aplicar al dominio al codominio. Por lo que una funcion no puede tener tipo ''{lazy {Num -Num}}'', pero si tipo ''%%{{lazy {Num -> Num}} -> Num}%%'' o ''{Num -> {lazy {Num -> Num}}}''+  * 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>
 ---- ----
  
Line 88: Line 87:
   * 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 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 con funciones memoizadas!
  
 </note> </note>