Type Inference
This project implements an interpreter for the COOL (Classroom Object-Oriented Language) programming language, enhanced with type inference capabilities through the introduction of the AUTO_TYPE
keyword.
Introduction
Type inference is the ability to infer, either partially or fully, the type of an expression at compile time. The objective of this project is the implementation of a COOL interpreter that has type inference by adding the AUTO_TYPE
type.
A COOL program need not specify all types of annotations if they are inferable given the context. Annotations are occasionally needed for disambiguation, eg type inference with polymorphic recursion is undecidable. Below are some examples showing some cases in which it is possible to infer the type of expressions and in which cases a semantic error will be thrown.
Features
Type Inference: Automatically deduces the types of expressions using
AUTO_TYPE
.COOL Language Support: Fully supports the syntax and semantics of the COOL programming language.
Interpreter Implementation: Executes COOL programs with type inference capabilities.
Examples
The simplest case is when the type is omitted in a variable declaration. In this case, the type is inferred from the initialization expression:
The same happens with the attributes of a class, when they can be inferred by the type of the initialization expression:
A more complex case is when the return type of a function is left unspecified, but can be inferred from its body:
In the above case, it's easy to infer the return type of succ
because the expression returns exactly the same type as an argument. In these cases, it is even possible not to specify the type of the argument, since the +
the operator is only defined for Int
:
However, it is sometimes not possible to infer the type of an argument from its use within a function body. In the following case, although we know that the type of the argument p
must be Point
to accept the invocation, it is not guaranteed that the type inference mechanism will have to infer it (because in the future there may be other classes with a translate
method). Depending on the implementation, in these cases, it is allowed to throw a semantic error indicating that it was not possible to infer the type of the argument p
.
Finally, recursive functions carry special complexity:
The example above allows the type of the argument n
and the return to be inferred simultaneously, since the return of the recursive function is used in a +
operation that is only defined for Int
. However, in the following example:
Since the return type is not used explicitly in a mathematical operation, it is not trivial to deduce that its return type is Int
, since Object
would also work as a return type. In these cases, you want the inference mechanism to deduce the most concrete type for the return and the most abstract type for the arguments that is possible.
Finally, two mutually recursive functions:
In this case, it is theoretically possible to infer that f
and g
must both return type Int
, but given the complexity of handling type inference in more than one function at a time, it is not guaranteed that it will be possible to infer types in this case.
Resources:
Skills

Python
Flask
HTML5/CSS

Jinja2
Habilities
Programming
API Development
Compiler Theory