We don't intend for these assignments to take too long. If you have spent five hours on any part of this assignment please stop and check in with the TAs.
In this assignment, you will be working with sets. The documentation is on pyret.org/docs/latest.
For the next couple of assignments you will be asked to create programs that either inspect or implement features of a simple functional programming language called Paret.
For the purposes of this assignment, this language is defined by the following grammar:
<expr> ::= | <num> | <bool> | (+ <expr> <expr>) | (num= <expr> <expr>) | (if <expr> <expr> <expr>) | <id> # identifier | (lam <id> <expr>) # anonymous function | (<expr> <expr>) # function application | (let (<id> <expr>) <expr>) | @ # a "hole"
To make working with Paret programs easier we have provided a function
parse, which takes an expression in the language's concrete syntax and returns its abstract syntax representation in the form below:
data Expr: | e-num(value :: Number) | e-bool(value :: Boolean) | e-op(op :: Operator, left :: Expr, right :: Expr) | e-if(cond :: Expr, consq :: Expr, altern :: Expr) | e-id(name :: String) | e-lam(param :: String, body :: Expr) | e-app(func :: Expr, arg :: Expr) | e-let(id :: String, value :: Expr, body :: Expr) | e-hole end data Operator: | op-plus | op-num-eq end
For instance evaluating the expression:
parse("((lam x (+ 1 @)) 2)")
Produces an annotated representation as a Pyret datatype:
e-app(e-lam("x", e-op(op-plus, e-num(1), e-hole)), e-num(2))
In this assignment you will write code to check what is in scope at a given part of your program.
This part of the program, known as a hole, is indicated by
You will implement a function that takes an expression with a hole in it and returns the set of identifiers that are in scope at the hole:
fun calc-locals(expr :: C.Expr, bound :: Set<String>) -> Set<String>: ... end
It must return precisely the set of identifiers that are in scope at the
hole. In particular, replacing a hole with any one of the identifiers
calc-locals must never cause an unbound identifier
exception. Conversely, every identifier not in the set returned by
calc-locals must be unbound at that position (though it may not result
in a runtime exception, because it may never be evaluated).
For example, the following program:
parse-n-calc(```(let (x 3) (let (y true) (lam f (f @))))```)
[set: "x", "y", "f"]. (
parse-n-calc is a helper function we provide which first parses an expression, then calls
calc-localsis to statically check what is in scope at a given part of your program; you do not need to evaluate the program and it should always halt.
To get started, you can open the code stencil and the test stencil in
We will grade your code by running our test suite against it, and grade your tests by running them against correct and incorrect solutions that we have written to see whether your tests can tell the difference. Feel free to write implementation-specific test cases in your code submission: we won't run these, but they can be helpful to you.
Do not write test cases that include no holes or more than one hole.
For this and future assignments: Do not change the type signatures of functions in the stencils. You don't need to test
parse (because we're providing it for you). You don't need to write test cases that violate the type signature of a function.
If you write helper functions in your code file (which we encourage you to do), please only test them in your code file. We will grade your test file against our own solutions, which won't have defined the same helper functions that you did.
First, please fill out this google form to tell us how long you spent on this assignment. Again, this data is only being used for course design purposes and will not affect your grade in any way.
To submit your implementation and test cases, first save them locally by clicking "More / Download this file" in the code.pyret.org editor. Your submission should consist of a zip file containing both "calc-vars-tests.arr" and "calc-vars-code.arr". Next, visit the captain-teach assignments page:
and click the "calc-vars" link for the current assignment. This page will ask you to click the "Next Step" and direct you to upload a file. You will have a chance to view your submission before publishing, but you may only publish one submission to this assignment.