Skip to content

Instantly share code, notes, and snippets.

@kmicinski
Created March 20, 2025 19:32
Show Gist options
  • Save kmicinski/71cb14e72f46c3341b6dcd69bb0e8403 to your computer and use it in GitHub Desktop.
Save kmicinski/71cb14e72f46c3341b6dcd69bb0e8403 to your computer and use it in GitHub Desktop.
Exercise 3 help
#lang racket
;; Consider the folllowing λ-calculus expression, write
;; a reduction sequence where each β reduction in the
;; sequence uses CBV evaluation order
((λ (x) x)
((λ (y) y) (λ (z) z)))
((λ (x) x)
((λ (z) (z z)) (λ (y) (y y))))
;; In Call-by-Value, we have a notion of *values*, which
;; are computed results. To call a function, we have to
;; reduce its arguments to values.
;;
;; In Call-by-Name, we are tracking the program's abstract
;; syntax tree (or at least, some representation of it) at
;; runtime. When we get to an application, instead of reducing
;; the argument to a value (like a number, or a closure,
;; or an object), we instead bind the variable to the runtime
;; representation of the expression corresponding to the argument
;;
;; CBN β: ((λ (x) e-b) e-a) → e-b[x↦e-a]
;; CBV β: ((λ (x) e-b) v) → e-b[x↦v-a]
;; in Call-by-Value, we are always assigning variables to
;; *values*, represented as data structures at runtime.
#lang racket
;; Exercise 3: A CE (Control and Environment) interpreter for Scheme
;; NOTE: You *MAY* collaborate with other students on this exercise,
;; but *not* the later project. Feel free to work with up to two other
;; students (groups of three) and submit the same code as them. Use
;; that code to begin your solution for p3.
;; Name: ________________________________
;; Collaborator 1: ________________________________
;; Collaborator 2: ________________________________
(provide interp-ce)
; Interp-ce must correctly interpret any valid scheme-ir program and yield the same value
; as DrRacket, except for closures which must be represented as `(closure ,lambda ,environment).
; (+ 1 2) can return 3 and (cons 1 (cons 2 '())) can yield '(1 2). For programs that result in a
; runtime error, you should return `(error ,message)---giving some reasonable string error message.
; Handling errors and some trickier cases will give bonus points.
(define (interp-ce exp)
(define (interp env exp)
(pretty-print exp)
(pretty-print env)
(match exp
[(or (? number?) (? boolean?)) exp]
[`(let ([,x ,rhs]) ,body)
(interp env `((lambda (,x) ,body) ,rhs))]
[`(lambda (,x) ,body)
`(closure (lambda (,x) ,body) ,env)]
[(? symbol? x)
;; look it up
(hash-ref env x)]
[`(if ,ge ,te ,fe)
(if (interp env ge)
;; guard was true, evaluate the true branch
(interp env te)
(interp env fe))]
;; not required, but you may want to add this
#;[`(apply-prim ,op ,x)
'todo]
[`(,op ,e0 ,e1)
(define (op->rkt op)
(match op ['+ +] ['- -] ['* *]))
(let ([v0 (interp env e0)]
[v1 (interp env e1)]
[op+ (op->rkt op)])
(op+ v0 v1))]
[`(,ef ,ea)
;;
(define clo-for-ef (interp env ef))
(match clo-for-ef
[`(closure (lambda (,x) ,e-b) ,env+)
(let ([v (interp env ea)])
(interp (hash-set env+ x v) e-b))])]))
;; TODO: update?
(define starting-env (hash))
(interp starting-env exp))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment