Problem Set 12
Last updated: Wed, 8 Apr 2015 13:35:30 -0400
DUE: Monday 4/13/2015, 9pm EST
Preliminaries
Use the full Racket language to complete this assignment. Enable it by adding #lang racket (case-sensitive) at the top of the file. In addition, the Choose Language... menu located at the bottom-left of the DrRacket window must be set to Determine language from source.
Put all your solution files in a directory named set12 in your repository.
Download extras.rkt to this directory (right-click and choose "Save As"; don’t copy and paste) and commit it as well.
Use begin-for-test and rackunit to define your examples and tests.
- Don’t forget to tell us how many hours you spent working on the assignment. This should be a global variable called TIME-ON-TASK in each file. For example:
(define TIME-ON-TASK 10.5) ; hours
- So each solution file must have at least the following at the top:
(require "extras.rkt") (require rackunit) (define TIME-ON-TASK <number-of-hours-you-spent>) - After you’ve submitted your solution, use a web browser to go to https://github.ccs.neu.edu/ and check that your repository contains the following files:
set12/draw.rkt
set12/eval.rkt
set12/extras.rkt
Git Commit Requirement: For this assignment, you must have at least three well-labeled git commits (including the final commit). A well-labeled git commit accurately and succinctly describes the changes since the previous commit. Something like "commit2", or "home work 3" is not an acceptable git commit label. Failure to meet this requirement will result in loss of points.
Programming is all about making tradeoffs. Now that you have had practice writing OO programs, write down (in any file), from your experiences, three advantages of OOP, and three advantages of the function-based programming you used during the first part of the course.
All posns in this problem set should be from lang/posn.
You may not use set! or otherwise mutate any objects.
1 Drawing Application Extension
1.1 Additional Preliminaries
(check-location "12" "draw.rkt")
1.2 Problem Description
UPDATE 2015-04-07: The “control region” is a square containing anything within 5 pixels of the corner point itself, just as it was for the rectangles in set11.
UPDATE 2015-04-08: The signature and purpose statement for the required create-triangle function is:
; create-triangle : posn posn -> Shape<%> ; Creates a triangle Shape<%> object from a center ; posn and one arbitrary corner. (define (create-triangle center corner) ...)
UPDATE 2015-05-07: We have released a triangle library (right-click and choose save-as) with the following helper functions.
; Posn functions — — — — — — — — — — — — — — – ; subtract-posn : posn posn -> posn ; GIVEN: Two points, considered "positive" and "negative", respectively. ; RETURNS: The difference between those points, componentwise. Considering the ; result as a vector, the vector points from the negative point to the ; positive one. ; add-posn : posn posn -> posn ; GIVEN: Two points ; RETURNS: The sum of those points, componentwise. ; distance : posn posn -> Real ; GIVEN: Two points, ; RETURNS: the scalar distance between them. ; Triangle functions — — — — — — — — — — — — – ; in-triangle? : posn posn posn posn -> Boolean ; GIVEN: One "candidate" point and three corner points, ; RETURNS: true iff the candidate is inside the triangle defined ; by the last three points. ; render-equilateral-triangle : posn posn String String Image -> Image ; GIVEN: A center Posn, an arbitrary corner Posn, an opacity String, a color ; String, and a background Image, ; RETURNS: An Image like the background but with an equilateral triangle placed ; onto it, such that its center is as given, one of its corners is at the ; given corner, and its opacity and color as given. (The "center" is the ; point that's equidistant from the three corners.) ; compute-corners : posn posn -> (list posn posn posn) ; Computes the corners of an equilateral triangle from a center and one corner. ; The given corner is also included in the output.
2 Interpreter, OO Style
2.1 Additional Preliminaries
(check-location "12" "eval.rkt")
2.2 Problem Description
(define Result<%> (interface () ; app : ListOf<Result<%>> ListOf<Def> -> Result<%> ; If Result is a lambda, applies it to given arguments, else errors. app)) (define Expr<%> (interface () ; eval : ListOf<Def> -> Result<%> ; Evaluates the expression to a Result<%>, ; in the context of the given definitions. eval ; subst : Result<%> Var -> Expr<%> ; Replaces references to the given var with the given Result<%>. ; Does not replace x with r if x occurs in the body of a lambda ; that shadows x. ; WHERE: the given Result<%> has no unbound variables. subst ; to-expr : -> Expr ; Returns a representation of this expression as a non-object Expr. to-expr ; to-expr/no-var : -> ExprNoVar ; Returns a representation of this expression as a non-object ExprNoVar. to-expr/no-var ; expr=? : Expr<%> -> Boolean ; Returns true if this expression is structurally equivalent to the given Expr<%> expr=?)) (define Program<%> (interface () ; eval : -> ListOf<Result<%>> ; Evaluates expressions in the program to Result<%>s ; WHERE: A function may be called before it is defined. ; WHERE: The results have the same order as their original expressions in the program. eval))
; mk-Program% : Program -> Program<%> (define (mk-Program% p) ...) ; mk-Expr% : Expr -> Expr<%> (define (mk-Expr% e) ...)
(define-struct def (name params body) #:transparent) (define-struct arith (op args) #:transparent) (define-struct bool (op args) #:transparent) (define-struct cmp (op args) #:transparent) (define-struct if-exp (test branch1 branch2) #:transparent) (define-struct call (fn args) #:transparent) (define-struct lam (params body) #:transparent) (define-struct lam/no-var (body) #:transparent)