Both sides previous revisionPrevious revisionNext revision | Previous revision |
teaching:cc4101:tareas:xyz:2024-1:tarea3 [2024/07/11 01:25] – [Clases (X pts)] gricci | teaching:cc4101:tareas:xyz:2024-1:tarea3 [2024/07/11 02:24] (current) – [Codificando funciones anónimas de primera clase con Objetos (1 pto)] fdiaz |
---|
====== Tarea 3 (Entrega: X de julio de 2024) ====== | ====== Tarea 3 (Entrega: X de julio de 2024) ====== |
| |
Esta tarea se distribuye con un archivo zip ({{ :teaching:cc4101:tareas:2023-1:base-t3.zip | base}}) 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:2024-1:tarea3:tarea3-base.zip | base}}) 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. |
- **Clases y objetos**: En esta sección se pide extender el lenguaje base con clases y objetos. En particular las clases deben ser entidades de primera clase, es decir, son valores del lenguaje. | - **Clases y objetos**: En esta sección se pide extender el lenguaje base con clases y objetos. En particular las clases deben ser entidades de primera clase, es decir, son valores del lenguaje. |
| |
- **Codificando Lambdas con Objetos**: El objetivo de esta sección es extender el lenguaje para soportar lambdas y aplicaciones como azúcar sintáctica, usando objetos. | - **Codificando funciones anónimas de primera clase con Objetos**: El objetivo de esta sección es extender el lenguaje para soportar funciones anónimas de primera clase (típicamente conocidas como “lambdas”) y aplicaciones como azúcar sintáctica, usando objetos. |
| |
<note warning> | <note warning> |
==== Manos a la Obra! ==== | ==== Manos a la Obra! ==== |
| |
==== Clases (X pts) ==== | ==== Clases (1.5 pts) ==== |
| |
**Extensiones del AST y Parser** | **Extensiones del AST y Parser** |
* [x pts] Defina el tipo de datos ''Method'' para representar una definición de método en el AST. | * [0.1 pts] Defina el tipo de datos ''Method'' para representar una definición de método en el AST. |
* [x pts] Implemente la función ''parse-method'' que recibe una definición de método en sintaxis concreta y retorna el nodo de AST correspondiente. | * [0.1 pts] Implemente la función ''parse-method'' que recibe una definición de método en sintaxis concreta y retorna el nodo de AST correspondiente. |
* [x pts] Extienda el tipo de datos ''Expr'' y la función ''parse'' para soportar la expresión ''class'' del lenguaje. | * [0.2 pts] Extienda el tipo de datos ''Expr'' y la función ''parse'' para soportar la expresión ''class'' del lenguaje. |
| |
**Extensiones de ''well-formed''** | **Extensiones de ''well-formed''** |
</code> | </code> |
| |
* [x pts] Extienda ''well-formed'' para realizar las verificaciones mencionadas. | * [0.7 pts] Extienda ''well-formed'' para realizar las verificaciones mencionadas. |
| |
**Observación**: Puede añadir un parámetro extra a ''well-formed'' para indicar si esta dentro de una clase | **Observación**: Puede añadir un parámetro extra a ''well-formed'' para indicar si esta dentro de una clase |
| |
**Intérprete** | **Intérprete** |
* [x pts] Extienda el tipo ''Val'' con un constructor llamado ''classV'' que permita almacenar la información necesaria para representar a una clase como valor. | * [0.3 pts] Extienda el tipo ''Val'' con un constructor llamado ''classV'' que permita almacenar la información necesaria para representar a una clase como valor. |
* [x pts] Extienda el intérprete para soportar la creación de clases. | * [0.1 pts] Extienda el intérprete para soportar la creación de clases. |
| |
**Observación**: Recuerde que los métodos definidos en una clase deben utilizar el ambiente al momento de la creación de la clase y no el ambiente de cuando son invocados. | **Observación**: Recuerde que los métodos definidos en una clase deben utilizar el ambiente al momento de la creación de la clase y no el ambiente de cuando son invocados. |
| |
==== Objetos (X pts) ==== | ==== Objetos (1.5 pts) ==== |
| |
**Extensiones del AST y Parser** | **Extensiones del AST y Parser** |
* [x pts] Extienda el tipo de datos ''Expr'' y la función ''parse'' para soportar la expresión ''new'' del lenguaje. | * [0.2 pts] Extienda el tipo de datos ''Expr'' y la función ''parse'' para soportar la expresión ''new'' del lenguaje. |
| |
**Extensiones de ''well-formed''** | **Extensiones de ''well-formed''** |
* [x pts] Extienda ''well-formed'' para verificar el nodo ''new''. En este caso, solo es necesario llamar ''well-formed'' para cada subnodo del nodo ''new'' TODO | * [0.2 pts] Extienda ''well-formed'' para verificar el nodo ''new''. En este caso, sólo es necesario llamar ''well-formed'' para cada subnodo del nodo ''new''. |
| |
**Intérprete** | **Intérprete** |
* [x 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. |
* [x pts] Defina la función ''invoke-method'' que permita buscar un método dentro de un objeto e invocarlo utilizando los argumentos entregados. | * [0.4 pts] Defina la función ''invoke-method'' que permita buscar un método dentro de la clase un objeto e invocarlo utilizando los argumentos entregados. |
* [x pts] Extienda el intérprete para permitir instanciar una clase utilizando la expresión ''new''. | * [0.4 pts] Extienda el intérprete para permitir instanciar una clase utilizando la expresión ''new''. |
| |
Durante el instanciado de clases, deben cumplirse los siguientes requisitos: | **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}''. |
* La creación de un objeto con un número inválido de argumentos debe lanzar el error ''"constructor not found"''. | |
| |
Además, para la creación de un objeto, los constructores son simplemente métodos llamados ''init''. Es posible definir varios métodos ''init'', sin embargo, definir varios constructores con la misma aridad es un error (//en tiempo de creación de la clase//). Cuando se ejecuta un ''new'', se selecciona el constructor que corresponda al número de argumentos pasados (error si no hay ninguno que calza). Si no hay ningún constructor declarado, solo se puede usar ''{new c}'' sin argumentos (constructor por defecto). | |
| |
A continuación se muestran algunos ejemplos de los errores que pueden lanzarse al instanciar un objeto: | A continuación se muestran algunos ejemplos de instanciación de clases: |
| |
<code scheme> | <code scheme> |
</code> | </code> |
| |
==== Llamados a métodos (X pts) ==== | <code scheme> |
| ;; Esta clase no tienen ningún constructor con aridad 2 |
| > (run-val '{begin {with {{C {class {x} |
| {def init {init-x} {set x init-x}}}}} |
| 10} |
| {new C 1 2}}) |
| "error: constructor not found" |
| </code> |
| |
| ==== Llamados a Métodos (0.8 pto) ==== |
| |
**Extensiones del AST y Parser** | **Extensiones del AST y Parser** |
* [x pts] Extienda el tipo de datos ''Expr'' y la función ''parse'' para soportar la expresión ''->'' del lenguaje. | * [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''** |
* [x pts] Extienda ''well-formed'' para verificar el nodo ''->''. En este caso, solo es necesario llamar ''well-formed'' para cada subnodo del nodo ''new'' TODO | * [0.2 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** |
* [x pts] Extienda el intérprete para permitir invocar métodos de una clase. | * [0.4 pts] Extienda el intérprete para permitir evaluar la invocación de métodos de un objeto. |
| |
Durante el instanciado de clases, deben cumplirse los siguientes requisitos: | **Observaciones**: |
* La invocación de un método inexistente debe lanzar el error ''"method <id> not found"''. | * 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"''. |
| |
A continuación se muestran algunos ejemplos de los errores que pueden lanzarse al invocar un método: | 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: |
| |
<code scheme> | <code scheme> |
</code> | </code> |
| |
==== Acceso a campos (X pts) ==== | <code scheme> |
| ;; Esta clase no tiene el método set-x definido para la aridad 2 |
| > (run-val '{with {{A {class {x} |
| {def set-x {val-x} {set x val-x}}}} |
| {o {new A}}} |
| {-> o set-x 10 20}}) |
| "error: method set-x not found" |
| </code> |
| |
| ==== Acceso y Modificación a Campos (1.2 pts) ==== |
| |
**Extensiones del AST y Parser** | **Extensiones del AST y Parser** |
* [x 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 ''get'' del lenguaje. |
* [x pts] Extienda el tipo de datos ''Expr'' y la función ''parse'' para soportar la expresión ''set'' 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''** |
</code> | </code> |
| |
* [x pts] Extienda ''well-formed'' para verificar el nodo ''get''. | * [0.1 pts] Extienda ''well-formed'' para verificar el nodo ''get''. |
* [x pts] Extienda ''well-formed'' para verificar el nodo ''set''. | * [0.2 pts] Extienda ''well-formed'' para verificar el nodo ''set''. |
| |
**Intérprete** | **Intérprete** |
* [x pts] Extienda el intérprete para permitir obtener el valor de un campo en una clase. | * [0.3 pts] Extienda el intérprete para permitir obtener el valor de un campo en una clase. |
* [x pts] Extienda el intérprete para permitir modificar el valor de un campo en una clase. | * [0.2 pts] Extienda el intérprete para permitir modificar el valor de un campo en una clase. |
| |
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: |
</code> | </code> |
| |
| ===== Codificando funciones anónimas de primera clase con Objetos (1 pto) ===== |
| 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. |
| |
**Extienda el lenguaje para soportar estas expresiones, donde tanto clases y objetos son valores.** Usted debe decidir los atributos que tendrán sus respectivos nodos en el AST. Si se encuentra con casos no especificados anteriormente debe tomar supuestos e indicarlo en su entrega. Modifique el parser y el intérprete para soportar el lenguaje extendido. | Hint: Piense en lo que comúnmente hemos visto como sintaxis de "aplicación de función" como azúcar sintáctico para la invocación de un método en un objeto, este método puede contener el código de la "función" definida. ¿De qué clase sería ese objeto? ¿Cómo se podría llamar ese método? |
| |
===== Codificando Lambdas (1 pto) ===== | |
Ahora incorporaremosmos lambdas (funciones anónimas de primera clase) 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. | |
<code scheme> | <code scheme> |
<expr> ::= ... | <expr> ::= ... |