Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
teaching:cc4101:tareas:2025-1:tarea3 [2025/06/19 19:37] – [Objetos (1.5 pts)] dibanezteaching:cc4101:tareas:2025-1:tarea3 [2025/06/19 21:09] (current) – [Tarea 3 (Entrega: TBD)] dibanez
Line 1: Line 1:
-====== Tarea 3 (Entrega: TBD) ====== +====== Tarea 3 (Entrega: 6 de Julio de 2025) ====== 
  
-Esta tarea se distribuye con un archivo zip (<<PLACEHOLDER>>) que contiene 3 archivos: main.rkt, tests.rkt y env.rkt. Los archivos están incompletos, y en ellos tiene que implementar lo que se solicita en las preguntas siguientes. +Esta tarea se distribuye con un archivo zip ({{ :teaching:cc4101:tareas:2025-1:t3-init.zip |}}) que contiene 3 archivos: main.rkt, tests.rkt y env.rkt. Los archivos están incompletos, y en ellos tiene que implementar lo que se solicita en las preguntas siguientes. 
  
 Debe entregar via U-cursos **un archivo .zip** que contenga los archivos main.rkt y tests.rkt. Debe entregar via U-cursos **un archivo .zip** que contenga los archivos main.rkt y tests.rkt.
Line 7: Line 7:
 <note important>Consulte las normas de entrega de tareas en http://pleiad.cl/teaching/cc4101</note> <note important>Consulte las normas de entrega de tareas en http://pleiad.cl/teaching/cc4101</note>
  
-**Recuerde que el testing y calidad de código se evalúan de acuerdo a [[https://docs.google.com/document/d/1Ahtk97_teZwtpFnJ-H--rLndeiFuyeDHpoGWpC8wL5I/edit?usp=sharing|la rúbrica]].**+**Recuerde que el testing y calidad de código se evalúan de acuerdo a [[https://docs.google.com/document/d/1Ahtk97_teZwtpFnJ-H--rLndeiFuyeDHpoGWpC8wL5I/edit?usp=sharing|esta rúbrica]].**
  
 ====== Resumen ====== ====== Resumen ======
Line 176: Line 176:
 **Intérprete** **Intérprete**
   * [0.3 pts] Extienda el tipo ''Val'' con un constructor llamado ''objV'' que permita almacenar la información necesaria para representar a un objeto como valor. **Hint**: Recuerde que uno de los objetivos de tener clases, es permitir que sus intancias puedan compartir métodos.   * [0.3 pts] Extienda el tipo ''Val'' con un constructor llamado ''objV'' que permita almacenar la información necesaria para representar a un objeto como valor. **Hint**: Recuerde que uno de los objetivos de tener clases, es permitir que sus intancias puedan compartir métodos.
-  * [0.pts] Defina la función ''invoke-method'' que permita buscar un método por nombre dentro de la clase de un objeto e invocarlo utilizando los argumentos entregados. Usted debe decidir la firma de esta función. +  * [0.pts] Defina la función ''invoke-method'' que permita buscar un método por nombre dentro de la clase de un objeto e invocarlo utilizando los argumentos entregados. Usted debe decidir la firma de esta función. 
-  * [0.pts] Extienda el intérprete para permitir instanciar una clase utilizando la expresión ''new''.+  * [0.pts] Extienda el intérprete para permitir instanciar una clase utilizando la expresión ''new''.
  
 **Observación**: Cuando se evalúa una expresión ''new'', se debe buscar en la clase un constructor que corresponda al número de argumentos entregados. Si no hay ninguno que tenga la aridad requerida, se debe lanzar el error ''"constructor not found"''. Si se está instanciando una clase que no declara ningún constructor, solo se puede usar el constructor por defecto que no recibe argumentos, es decir, ''{new c}''. **Observación**: Cuando se evalúa una expresión ''new'', se debe buscar en la clase un constructor que corresponda al número de argumentos entregados. Si no hay ninguno que tenga la aridad requerida, se debe lanzar el error ''"constructor not found"''. Si se está instanciando una clase que no declara ningún constructor, solo se puede usar el constructor por defecto que no recibe argumentos, es decir, ''{new c}''.
Line 194: Line 194:
 <code scheme> <code scheme>
 ;; Esta clase no tienen ningún constructor con aridad 2 ;; Esta clase no tienen ningún constructor con aridad 2
-> (run-val '{begin {with {{C {class {x} +> (run-val '{with {{C {class {x} 
-                               {def init {init-x} {set x init-x}}}}} +                             {def init {init-x} {set x init-x}}}}} 
-                     10} +                  {new C 1 2}})
-                   {new C 1 2}})+
 "error: constructor not found" "error: constructor not found"
 </code> </code>
  
 <code scheme> <code scheme>
-> (run-val '{})+> (run-val '{with {{A {class {x y} 
 +                             {def init {x y} {begin {set x x} 
 +                                                    {set y y}}}}}} 
 +                  {init A}}) 
 +; Retorna una instancia donde x e y no están inicializados.
 </code> </code>
 ==== Llamados a Métodos (0.8 pto) ==== ==== Llamados a Métodos (0.8 pto) ====
- 
-**Extensiones del AST y Parser** 
-  * [0.2 pts] Extienda el tipo de datos ''Expr'' y la función ''parse'' para soportar la expresión ''->'' del lenguaje. 
  
 **Extensiones de ''well-formed''** **Extensiones de ''well-formed''**
-  * [0.pts] Extienda ''well-formed'' para verificar el nodo ''->''. En este caso, solo es necesario llamar ''well-formed'' para cada subnodo del nodo ''new''.+  * [0.pts] Extienda ''well-formed'' para verificar el nodo ''->''. En este caso, solo es necesario llamar ''well-formed'' para cada subnodo del nodo ''new''.
  
 **Intérprete** **Intérprete**
-  * [0.pts] Extienda el intérprete para permitir evaluar la invocación de métodos de un objeto.+  * [0.pts] Extienda el intérprete para permitir evaluar la invocación de métodos de un objeto.
  
 **Observaciones**: **Observaciones**:
   * Recuerde en en la sección anterior (Objetos) implementó la función ''invoke-method''.   * Recuerde en en la sección anterior (Objetos) implementó la función ''invoke-method''.
-  * La invocación de un método inexistente o cuya aridad no coincide con el número de argumentos entregados debe lanzar el error ''"method <id> not found"''.+  * La invocación de un método inexistente debe lanzar el error ''"method <id> not found"''
 +  * Invocar un método con la cantidad equivocada de argumentos debe lanzar el error ''no overload of <num> arguments was found for method <id>''
  
 A continuación se muestran programas en los que se intenta invocar un método inexistente o donde no se encuentra una sobrecarga con la aridad correcta: A continuación se muestran programas en los que se intenta invocar un método inexistente o donde no se encuentra una sobrecarga con la aridad correcta:
Line 235: Line 236:
                    {o {new A}}}                    {o {new A}}}
               {-> o set-x 10 20}})               {-> o set-x 10 20}})
-"error: method set-x not found"+"error: no overload of 2 arguments was found for method set-x"
 </code> </code>
  
 ==== Acceso y Modificación a Campos (1.2 pts) ==== ==== Acceso y Modificación a Campos (1.2 pts) ====
- 
-**Extensiones del AST y Parser** 
-  * [0.2 pts] Extienda el tipo de datos ''Expr'' y la función ''parse'' para soportar la expresión ''get'' del lenguaje. 
-  * [0.2 pts] Extienda el tipo de datos ''Expr'' y la función ''parse'' para soportar la expresión ''set'' del lenguaje. 
  
 **Extensiones de ''well-formed''** **Extensiones de ''well-formed''**
Line 260: Line 257:
  
 **Intérprete** **Intérprete**
-  * [0.pts] Extienda el intérprete para permitir obtener el valor de un campo en una clase+  * [0.pts] Extienda el intérprete para permitir obtener el valor del campo de un objeto
-  * [0.pts] Extienda el intérprete para permitir modificar el valor de un campo en una clase.+  * [0.pts] Extienda el intérprete para permitir modificar el valor del campo de un objeto.
  
 Los errores dentro de ''interp'' para objetos deben manejarse de la siguiente forma: Los errores dentro de ''interp'' para objetos deben manejarse de la siguiente forma:
Line 283: Line 280:
 </code> </code>
  
-===== Parte 2: Codificando funciones anónimas de primera clase con Objetos (_ pts) =====+===== Parte 2: Codificando funciones anónimas de primera clase con Objetos (1 pt) =====
 Ahora incorporaremos funciones anónimas de primera clase (típicamente conocidas como "lambdas") a nuestro lenguaje. A diferencia de lo visto durante el curso, en esta ocasión no daremos una interpretación directa de las funciones. Usted debe idear una manera de usar la implementación de clases y objetos hecha en la parte anterior para codificar las lambdas. Esto significa que **no puede modificar** el AST y el intérprete para soportar funciones y aplicaciones de funciones. Las modificaciones que debe hacer son en el **parser**. En otras palabras, las funciones y aplicaciones serán sólo azúcar sintáctica. Ahora incorporaremos funciones anónimas de primera clase (típicamente conocidas como "lambdas") a nuestro lenguaje. A diferencia de lo visto durante el curso, en esta ocasión no daremos una interpretación directa de las funciones. Usted debe idear una manera de usar la implementación de clases y objetos hecha en la parte anterior para codificar las lambdas. Esto significa que **no puede modificar** el AST y el intérprete para soportar funciones y aplicaciones de funciones. Las modificaciones que debe hacer son en el **parser**. En otras palabras, las funciones y aplicaciones serán sólo azúcar sintáctica.
  
Line 304: Line 301:
 8 8
 </code> </code>
 +
 +===== Parte 3 (extra): Campos de Clase (1 pt de Bonus) =====
 +En la parte 1 implementamos clases con campos y métodos de instancia, además de estos la mayoría de lenguajes que permiten POO soportan campos y métodos de clase, como también campos y métodos estáticos.
 +
 +En esta parte extenderemos el lenguaje con campos de clase, para ello modificaremos la sintáxis de esta forma:
 +<code scheme>
 +<expr> ::= ... (expresiones del lenguaje base) ...
 +        | {class {<field>*} <method>*} 
 +
 +<field> ::= <sym>
 +          | {cls <sym> <expr>?}
 +</code>
 +
 +El ''?'' indica que un campo de clase puede o no incluir una expresión. Esta expresión es usada como valor inicial para el campo de clase.
 +
 +Tenga en consideración:
 +
 +  * Un campo de clase solo puede ser modificado por objetos de esa clase.
 +  * Un campo de clase puede ser leído usando ''get'' directamente sobre el valor de la clase, o desde cualquiera de sus instancias.
 +  * No pueden haber campos de clase o instancia con el mismo nombre. Esto debe comprobarse de forma estática. En caso de encontrarse, debe lanzar el error "duplicate fields"
 +  * Si un campo de clase no incluye un valor inicial, entonces se encuentra no inicializado. Intentar acceder a un campo de clase no inicializado debe lanzar el error "class field <id> not initialized".
 +
 +Programas de ejemplo:
 +<code scheme>
 +> (run-val '{with {{A {class {x {cls y 0}}
 +                             {def init {x}
 +                               {begin {set x x}
 +                                      {set y {+ 1 {get self y}}}}}}}
 +                   {o1 {init A 5}}
 +                   {o2 {init A 10}}
 +                   {o3 {init A 0}}}
 +                  {get A y}})
 +3
 +</code>
 +
 +<code scheme>
 +; Programa con un mismo nombre como campo de clase e instancia.
 +> (run-val '{with {{Foo {class {x {cls x}}}}}
 +                  0})
 +"error: duplicate fields"
 +</code>
 +
 +<code scheme>
 +; Programa que intenta leer un campo de clase no inicializado
 +> (run-val '{with {{Bar {class {cls a} {def get-a {} {get self a}}}}
 +                   {o {init Bar}}}
 +                  {-> o get-a}})
 +"error: class field a not initialized"
 +</code>
 +
 +<code scheme>
 +> (run-val '{with {{Test {class {cls b} {def set-b {new-b} {set b new-b}}}}
 +                   {o1 {init Test}}
 +                   {o2 {init Test}}
 +                  {begin {-> o1 set-b #t}
 +                         {get o2 b}}})
 +#t
 +</code>
 +
 +  * Realize las modificaciones necesarias para extender el lenguaje con campos de clase.
 +