Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

As I mentioned in class, the presence of macros in the lisp family of languages

ID: 3817335 • Letter: A

Question

As I mentioned in class, the presence of macros in the lisp family of languages has led to many subtly-different implementations of the same concept. Just as function definition isn't a fundamental operation (it is composed of definition and lambda), the let mechanism can be constructed from lambda alone. The Clojure code

(let [x 10, y 20] (* x y))

is equivalent to

((fn [x y] (+ x y)) 10 20). Thus, many different implementations exist (In fact, some of the differences in let forms have been cited in the renaming of PLT Scheme to Racket (https://racket-lang.org/new-name.html)

Let's help make schemers more at home in Clojure with a macro that allows scheme-style macros to be used.

Rather than try to support both syntaxes from a single macro, you'll define a new one such that

(let-scm ((x 10) (y 20)) (+ x y))

is the same thing as

(let [x 10 y 20] (+ x y))

For clarity, here is another example that I want you to be sure that you can support.

;; this is just a helper to ensure that the let

;; arguments are only evaluated once

(defn print-and-val [val]

(println "this should only print once")

val)

(let-scm ((x (+ 5 5))

(y (print-and-val 20))

(z 30))

   (println "x =" x)

   (println "y =" y)

   (println "z =" z)

   (+ x y z))

Should produce

this should only print once

x = 10

y = 20

z = 30

and

(pprint

(macroexpand-1

'(let-scm ((x (+ 5 5))

(y (print-and-val 20))

(z 30))

   (println "x =" x)

   (println "y =" y)

   (println "z =" z)

   (+ x y z))))

should produce

(clojure.core/let

[x (+ 5 5) y (print-and-val 20) z 30]

(println "x =" x)

(println "y =" y)

(println "z =" z)

(+ x y z))

NOTE: you'll only get the namespace on the let if you use syntax-quoting (which is advisable, but not required).


EXTRA NOTE: Your macro needs to be able to handle an arbitrary number of assignments and an arbitrary number of statements in the body. This can be solved in a one or two line macro. That's making use of some built-in higher-order functions. If you implement everything from scratch it will take more of course. But if you find yourself having to write a bunch of code to handle corner cases then you are probably on the wrong track.

Explanation / Answer

(defvar a)
(defvar b)
(defvar c)

(write-line " Enter two numbers : ")

   (setf a(read))
   (setf b(read))

(sb-thread:make-thread(lambda()(progn(sleep 0)
               (setf c(+ a b))
               (print "ADDITION : ")
               (print c))))

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote