1 Introduction
This manual describes the ChocoPy language, which is a statically typed dialect of Python 3.6. ChocoPy
is intended to be used in a classroom setting. It has been designed to be small enough for students to
implement a full ChocoPy compiler over one semester.
ChocoPy has been designed to be a subset of Python. Almost every valid ChocoPy program is also a
valid Python 3.6 program. An execution of a ChocoPy program that does not result in error usually has
the same observable semantics as the execution of that program in Python 3.6. Appendix A lists the small
number of exceptions to this rule.
A ChocoPy program is contained in a single source file. At the top level, a ChocoPy program consists
of a sequence of variable definitions, function definitions, and class definitions followed by a sequence of
statements. A class consists of a sequence of attribute definitions and method definitions. A class creates a
user-defined type. Function definitions can be nested inside other methods and functions. All class names and
functions defined at the top level are globally visible. Classes, functions, and methods cannot be redefined.
Program statements can contain expressions, assignments, and control-flow statements such as conditionals
and loops. Evaluation of an expression results in a value that can be an integer, a boolean, a string, an
object of user-defined class, a list, or the special value None. ChocoPy does not support dictionaries, first-
class functions, and reflective introspection. All expressions are statically typed. Variables (global and local)
and class attributes are statically typed, and have only one type throughout their lifetime. Both variables
and attributes are explicitly typed using annotations. In function and method definitions, type annotations
are used to explicitly specify return type and types of formal parameters.
For readers familiar with the Python language, Figure 1 contains a sample ChocoPy program illustrating
top-level functions, statements, global variables, local variables, and type annotations. The type annotations
are valid syntaxes in Python 3.6, though the Python interpreter simply ignores these annotations and leaves
them as hints for other tools. In contrast, ChocoPy enforces static type checking at compile time. In
Figure 1, the function is
zero is defined at the top level. Its formal parameters items and idx are explicitly
typed as a list of integers and an integer, respectively. The return type of the function is zero is bool.
The function defines a local variable, val, whose type is int. At the top level, the program defines a global
variable mylist, whose type is a list of integers. Function is zero is invoked in a top level statement and
its result is output using the predefined print function. Similarly, Figure 2 contains a ChocoPy program
that defines two classes: animal and cow. The class cow inherits from animal, which in turn inherits from
the predefined root class object. The Boolean attribute makes noise is defined in animal and is therefore
inherited by class cow. The class cow overrides the method sound. The constructor for class cow is invoked
at line 19.
Section 2 provides a detailed but informal overview of the various language constructs in ChocoPy.
Sections 3–6 provide formal descriptions of the lexical structure, grammatical syntax, typing rules, and
operation semantics of ChocoPy.
2 A tour of ChocoPy
Notation In the rest of this section, we use:
• {expr} to denote an expression in the program.
• {id} to denote an identifier such as the name of a variable or function.
• {stmts} to denote a list of program statements, separated by newlines.
• {declarations} to denote a list of (possibly interleaved) declarations of functions, variables, attributes,
and/or classes, where applicable.
• {type} to denote a static type annotation.
• {literal} to denote a constant literal such as an integer literal, a string literal, or the keywords True,
False or None.
3