0% found this document useful (0 votes)
7 views6 pages

Answers

The document contains various implementations of functions in Racket, including higher-order functions, continuation-passing style (CPS) transformations, and static single assignment (SSA) forms. It discusses recursive functions like factorial and Fibonacci, as well as operations on lists, and compares different approaches for efficiency and clarity. Additionally, it includes observations and questions regarding the impact of SSA and CPS on performance and memory usage.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views6 pages

Answers

The document contains various implementations of functions in Racket, including higher-order functions, continuation-passing style (CPS) transformations, and static single assignment (SSA) forms. It discusses recursive functions like factorial and Fibonacci, as well as operations on lists, and compares different approaches for efficiency and clarity. Additionally, it includes observations and questions regarding the impact of SSA and CPS on performance and memory usage.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

1.

1
(let ()
(define f (λ (x)
(let ()
(define v1 (- x 10))
(define v2 (+ x 10))
(define v3 (/ v1 v2))
v3)))

(define new-f (λ (x)


(let ()
(define v4 (f x)) ; Apply f once
(define v5 (f v4)) ; Apply f again
v5)))

(map new-f (list 1 2 3 4 5)))

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)

(define v5 (+ v2 v4)) ; Summing squared results


(define v6 (sqrt v5)) ; Taking square root

v6))

1.3
(let ()
(define v1 10) ; Original x
(define v2 20) ; Original y

(define v3 (+ v1 v2)) ; New x (x + y)

(define v4 (* v3 v2)) ; New y (x * y), using updated x (v3) and original y (v2)

(define v5 (/ v3 v4)) ; Final computation (/ x y)

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))

(define v11 (- v10 v7))

(define v12 (+ v5 v11))

v12)

1.5
(let ()
(define v1 10)
(define v2 20)

(define (f v3) (+ v3 (/ 5 v2)))

(define v4 (* v1 v2))

(define v5 (- v4 v1))
(define v6 (f v5))

v6)

1.6
#lang racket

(define (ssa-form-ver1 expr varnames)


(let loop ((e expr) (vars varnames) (bindings '()))
(cond
;; If the expression is a number or variable, return it as is
((or (number? e) (symbol? e)) (values e vars bindings))

;; If it's a unary operation (sqrt, square)


((and (list? e) (= (length e) 2))
(let-values ([(subexpr new-vars new-bindings) (loop (cadr e) (cdr vars)
bindings)])
(let* ((new-var (car vars))
(new-binding (list new-var (list (car e) subexpr))))
(values new-var new-vars (append new-bindings (list new-binding))))))

;; If it's a binary operation (+, -, *, /)


((and (list? e) (= (length e) 3))
(let-values ([(left-expr vars1 bindings1) (loop (cadr e) (cdr vars)
bindings)])
(let-values ([(right-expr vars2 bindings2) (loop (caddr e) (cdr vars1)
bindings1)])
(let* ((new-var (car vars))
(new-binding (list new-var (list (car e) left-expr right-expr))))
(values new-var vars2 (append bindings2 (list new-binding)))))))

;; Otherwise, return as-is (should not happen in valid input)


(else (values e vars bindings)))))

;; Wrapper function to return a proper let form


(define (ssa-wrapper expr varnames)
(let-values ([(result _ bindings) (ssa-form-ver1 expr varnames)])
`(let ,bindings ,result)))

;; Example Usage:
(define expr '(* (+ x y) (sqrt (- y z))))
(define vars '(v1 v2 v3 v4 v5 v6 v7 v8 v9 v10))

(displayln (ssa-wrapper expr vars))

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

(define (ssa-begin es varnames)


(let loop ([exprs es] [vars varnames] [acc '()])
(match exprs
['() (reverse acc)]
[(list e) (append (reverse acc) (list (ssa-form-ver2 e vars)))]
[(cons e rest)
(let* ([res (ssa-form-ver2 e vars)]
[new-vars (cdr vars)])
(loop rest new-vars (cons res acc)))]))))

(define (ssa-set varname e1 varnames)


(let* ([new-var (car varnames)]
[new-expr (ssa-form-ver2 e1 (cdr varnames))])
`(define ,new-var ,new-expr))) ;; Replace set!

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

(define (ssa-begin-opt es varnames used-vars)


(let loop ([exprs es] [vars varnames] [used used-vars] [acc '()])
(match exprs
['() (reverse acc)]
[(list e) (append (reverse acc) (list (ssa-form-opt e vars used)))]
[(cons e rest)
(let* ([res (ssa-form-opt e vars used)]
[new-vars (if (member (car vars) used) vars (cdr vars))])
(loop rest new-vars (cons (car vars) used) (cons res acc)))]))))

(define (ssa-set-opt varname e1 varnames used-vars)


(let* ([new-var (if (member varname used-vars) (car varnames) varname)]
[new-expr (ssa-form-opt e1 (cdr varnames) used-vars)])
`(define ,new-var ,new-expr)))

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))))))

(define (sum-list/ret lst return)


(if (empty? lst)
(return 0)
(sum-list/ret (rest lst) (λ (res) (return (+ (first lst) res))))))

(define (reverse-list/ret lst return)


(define (rev-helper lst acc return)
(if (empty? lst)
(return acc)
(rev-helper (rest lst) (cons (first lst) acc) return)))
(rev-helper lst '() return))

(define (map-list/ret f lst return)


(if (empty? lst)
(return '())
(map-list/ret f (rest lst) (λ (res) (return (cons (f (first lst)) res))))))

2.1
(define (+/ret a b return)
(return (+ a b)))

(define (*/ret a b return)


(return (* a b)))

(define (sqrt/ret x return)


(return (sqrt x)))

(define (hyp/ret x y return)


(*/ret x x (λ (x2)
(*/ret y y (λ (y2)
(+/ret x2 y2 (λ (sum)
(sqrt/ret sum return))))))))

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)))

(define (odd?/ret n return)


(if (= n 0)
(return #f)
(even?/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?

2. /ret Forms in Q3 vs. Q4


Noticed:
Q3 (fibo/ret) uses explicit continuation calls twice to handle the two recursive
calls, making it more complex than Q4.
Q4 (fibo/ret in accumulator form) is more tail-recursive and only needs a single
continuation call, making it more efficient.
Q3 has an inherent recursive structure that leads to multiple nested calls, whereas
Q4 processes values iteratively.

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)))))))))

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy