Answers
Answers
1
(let ()
(define f (λ (x)
(let ()
(define v1 (- x 10))
(define v2 (+ x 10))
(define v3 (/ v1 v2))
v3)))
1.2
(lambda (f x y)
(let ()
(define v1 (- x 5))
(define v2 (* v1 v1)) ; Squaring the result of (x - 5)
(define v3 (- y 10))
(define v4 (* v3 v3)) ; Squaring the result of (y - 10)
v6))
1.3
(let ()
(define v1 10) ; Original x
(define v2 20) ; Original y
(define v4 (* v3 v2)) ; New y (x * y), using updated x (v3) and original y (v2)
v5)
1.4
(let ()
(define v1 10)
(define v2 20)
(define v3 (/ v2 v1))
(define v4 (* v1 v3))
(define v5 (- v1 v4))
(define v6 (- v5 v2))
(define v7 (* v5 v4 v6))
(define v8 (+ v5 v4))
(define v9 (square v8))
(define v10 (* v5 v7 v9))
v12)
1.5
(let ()
(define v1 10)
(define v2 20)
(define v4 (* v1 v2))
(define v5 (- v4 v1))
(define v6 (f v5))
v6)
1.6
#lang racket
;; Example Usage:
(define expr '(* (+ x y) (sqrt (- y z))))
(define vars '(v1 v2 v3 v4 v5 v6 v7 v8 v9 v10))
1.7
(define (ssa-form-ver2 expr varnames)
(match expr
[(list 'begin es ...) (ssa-begin es varnames)]
[(list 'set! varname e1) (ssa-set varname e1 varnames)]
[_ (ssa-form-ver1 expr varnames)])) ;; Reuse Q6 function
example
(begin
(define x 10)
(set! x (+ x 5))
(* x 2))
1.8
(define (ssa-form-opt expr varnames used-vars)
(match expr
[(list 'begin es ...) (ssa-begin-opt es varnames used-vars)]
[(list 'set! varname e1) (ssa-set-opt varname e1 varnames used-vars)]
[_ (ssa-form-ver1 expr varnames)])) ;; Reuse Q6 function
These solutions reuse variables when possible and ensure that only the required
number of variables are used, making them memory efficient.
----Question 2-------------
2
(define (factorial/ret n return)
(if (= n 0)
(return 1)
(factorial/ret (- n 1) (λ (res) (return (* n res))))))
2.1
(define (+/ret a b return)
(return (+ a b)))
2.2
(define (factorial/ret n return)
(if (= n 0)
(return 1)
(factorial/ret (- n 1) (λ (res) (return (* n res))))))
2.3
(define (fibo/ret n return)
(if (<= n 1)
(return 1)
(fibo/ret (- n 1)
(λ (f1) (fibo/ret (- n 2)
(λ (f2) (return (+ f1 f2))))))))
2.4
(define (fibo/ret n a b return)
(if (= n 0)
(return a)
(fibo/ret (- n 1) b (+ a b) return)))
2.5
(define (even?/ret n return)
(if (= n 0)
(return #t)
(odd?/ret (- n 1) return)))
2.6
Notice and Wonder
1. SSA Form vs. Q1 Implementation
Noticed:
SSA form introduces unique variables at every step, eliminating mutations.
The transformed version ensures each computation is explicitly stored in a new
variable.
SSA form makes dependencies clear, whereas the original version allows reusing
variable names.
Wondered:
How does SSA impact performance in an optimizing compiler?
Would SSA always be beneficial for functional languages like Racket, or does it
introduce unnecessary complexity in some cases?
Wondered:
Is the accumulator form always the best way to optimize recursive functions for
tail-recursion?
How does CPS transformation impact memory usage in deep recursion cases compared to
accumulator-based recursion?
------Question 3--------
3.1
(reset (sqrt (+ (square (shift f 42)) (square (- y2 y1)))))
Ans: 42
3.2
ans: 48
3.3
ans: (4, 8, 12, 16)
3.4
ans: (4, 8, 12, 16)
3.5
(define (factorial n)
(reset
(let ([f 1])
(let loop ()
(shift k
(if (<= n 1)
f
(begin
(set! f (* f n))
(set! n (- n 1))
(k (loop)))))))))