-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patha3.rkt
More file actions
113 lines (82 loc) · 3.26 KB
/
a3.rkt
File metadata and controls
113 lines (82 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#lang racket
#|
CSC324 — 2024F — Assignment 3
Polymorphic Types, Type Classes, and Macros
Tasks
1. Polymorphic Types [See Haskell file for Task 1.]
2. Infinite Lists [See Haskell file for Task 2.]
3. Implement Functor Tree [See Haskell file for Task 3.]
4. Macros [See Racket file for Task 4.]
(a) my-first-macro
(b) def-func
All function bodies to implement are marked with "Complete me".
Recall that #; means "expression comment". Uncomment the tests as you complete the tasks.
Note that by default, DrRacket only displays output for failing test cases.
If you don't see any output, that means you've passed the tests.
IMPORTANT: You are NOT allowed to modify existing imports or add new imports.
|#
(module+ test (require rackunit))
(provide my-first-macro def-func)
#|
-------------------------------------------------------------------------------
* Task 4: Macros *
-------------------------------------------------------------------------------
(a) my-first-macro
Complete `my-first-macro` so that the three tests below pass.
- Your solution must not literally contain 'A, 'X, 'Y, or 'Z.
- Your solution must not use a new `define` (except for the given four).
If your solution satisfies these properties and passes the three tests below, you will get full marks.
|#
(module+ test
(check-equal? (my-first-macro x) (list (list 'a 'A "a" "A") (list 'x 'X "x" "X") (list 'x 'X "x" "X")))
(check-equal? (my-first-macro y) (list (list 'a 'A "a" "A") (list 'y 'Y "y" "Y") (list 'x 'X "x" "X")))
(check-equal? (my-first-macro z) (list (list 'a 'A "a" "A") (list 'z 'Z "z" "Z") (list 'x 'X "x" "X"))))
(define a 'A)
(define x 'X)
(define y 'Y)
(define z 'Z)
(define-syntax-rule (my-first-macro x2)
(let* (
[list_a (list 'a a "a" "A")]
[list_c (list 'x x "x" "X")]
[upper_string (symbol->string x2)]
[lower_string (string-downcase upper_string)]
[lower_symbol (string->symbol lower_string)])
(list list_a (list lower_symbol x2 lower_string upper_string) list_c))
)
#|
(b) def-func
The macro `def-func` will provide a new syntax form for defining simple tail recursive functions.
Consider the following tail recursive function.
(define (factorial-tail n acc)
(cond [(<= n 0) 0]
[(= n 1) acc]
[(factorial-tail (- n 1) (* acc n))]))
We want to define a macro that allows us to use the following python-like definition to define this function.
(def-func factorial-tail (n acc) :
base ([(<= n 0) -> 0]
[(= n 1) -> acc])
rec (- n 1) (* acc n))
Define the `def-func` macro to perform such transformations.
|#
(module+ test
(def-func factorial-tail (n acc) :
base ([(<= n 0) -> 0]
[(= n 1) -> acc])
rec (- n 1) (* acc n))
(def-func fibonacci (n a b) :
base ([(= n 0) -> a]
[(= n 1) -> b])
rec (- n 1) b (+ a b))
(check-equal? (factorial-tail 1 1) 1)
(check-equal? (factorial-tail 3 1) 6)
(check-equal? (factorial-tail 6 1) 720)
(check-equal? (fibonacci 10 0 1) 55))
(define-syntax def-func
(syntax-rules (: base -> rec)
[(def-func function-name (<arguments> ...) :
base ([<condition> -> <expr>] ...)
rec <new_arguments> ...)
(define (function-name <arguments> ...)
(cond [<condition> <expr>] ... [(function-name <new_arguments> ...)]))]
))