During this activity, students should be able to:
This activity helps the student develop the following skills, values and attitudes: ability to analyze and synthesize, capacity for identifying and solving problems, and efficient use of computer systems.
Individually, solve the following set of meta-programming exercises using Clojure macros.
Place all your functions in a name space called macros
.
This is the documentation for Clojure's or
macro:
or
macro
Usage:
(or)
(or x)
(or x & next)
Evaluates its expressions one at a time, from left to right. If a form returns a logical true value, it returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression. (or) returns nil.
Write a macro called my-or
that works as described above. Make sure that any expression gets evaluated at most once. You may not use Clojure's or
macro. Usage examples:
(macros/my-or) ⇒ nil (macros/my-or false :one nil :two false :three) ⇒ :one (macros/my-or false false nil) ⇒ nil (macros/my-or nil nil false) ⇒ false
Write a macro called do-loop
that implements a post-test loop control statement. It must combine the functionality of C's do-while
statement and Pascal's repeat-until
statement.
This construct consists of a body (one or more expressions, presumably with side effects) and a final conditional form prefaced with a :while
or :until
keyword. First, the expressions in the body are evaluated sequentially, and then the condition is evaluated. If the final form uses a :while
keyword, the body of the loop is repeated while the condition holds true. On the other hand, if the final form uses an :until
keyword, the body of the loop is repeated while the condition holds false (or in other words, the loop terminates when the condition is true). Returns nil
.
Here are some examples:
(def i (atom 0)) (macros/do-loop (println @i) (swap! i inc) (:until (= @i 5))) ;;; prints: ;;; 0 ;;; 1 ;;; 2 ;;; 3 ;;; 4 ⇒ nil (def j (atom 1)) (macros/do-loop (println @j) (swap! j inc) (:while (<= @j 5))) ;;; prints: ;;; 1 ;;; 2 ;;; 3 ;;; 4 ;;; 5 ⇒ nil
Write a macro called do-reverse
. It should work like the ordinary do
special form, but evaluating its expressions in reverse order. This macro should always return nil
.
Examples:
(do-reverse) ⇒ nil (do-reverse (println "one") (println "two") (println "three")) ;;; prints: ;;; three ;;; two ;;; one ⇒ nil (do-reverse (do (println "a") (* 6 7)) (println "b")) ;;; prints: ;;; b ;;; a ⇒ nil
Write a macro called def-pred
, that takes a name, an arg vector, and a body of one or more expressions. The macro should define two predicate functions: a regular one and its negated version. The name of the negated predicate should be the same as name but with a "not-
" prefix, and its result should be negated using the not
function (see the test code for an example).
Examples:
(macroexpand-1 '(def-pred less-than-one? [x] (< x 1))) ⇒(do (clojure.core/defn less-than-one? [x] (< x 1)) (clojure.core/defn not-less-than-one? [x] (clojure.core/not (do (< x 1))))) (def-pred less-than-one? [x] (< x 1)) (less-than-one? 0) ⇒ true (less-than-one? 2) ⇒ false (not-less-than-one? 0) ⇒ false (not-less-than-one? 2) ⇒ true (macroexpand-1 '(def-pred plural? [s] (println "check s in" s) (= \s (last s))))) ⇒ (do (clojure.core/defn plural? [s] (println "check s in" s) (= \s (last s))) (clojure.core/defn not-plural? [s] (clojure.core/not (do (println "check s in" s) (= \s (last s)))))) (def-pred plural? [s] (println "check s in" s) (= \s (last s))) (plural? "boys") ;;; prints: ;;; check s in boys ⇒ true (plural? "girl") ;;; prints: ;;; check s in girl ⇒ false (not-plural? "boys") ;;; prints: ;;; check s in boys ⇒ false (not-plural? "girl") ;;; prints: ;;; check s in girl ⇒ true
NOTE: You will likely need to use the Clojure functions str
and symbol
when producing the negated predicate name.
Using the Online Assignment Delivery System (SETA), deliver the file called macros.clj
containing your solutions. No assignments will be accepted through e-mail or any other means.
IMPORTANT: The program source file must include at the top the author's personal information (name and student id) within comments. For example:
;;; ITESM CEM, November 21, 2012. ;;; Clojure Source File ;;; Activity: Macros ;;; Author: Steve Rogers, 1166611 . . (The rest of the program goes here) .
Due date: Wednesday, November 21.
This activity will be evaluated using the following criteria:
-10 | The program doesn't contain within comments the author's personal information. |
---|---|
10 | The program contains syntax errors. |
DA | The program was plagiarized. |
10-100 | Depending on the amount of exercises that were solved correctly. |