Due date: November 17.
Alter the syntax of your language! Implement unless
.
Has the same semantics as if
, but executes the first branch if the predicate
is false and the second branch if the predicate is true.
Implement the macro from
. The macro binds a symbol and can perform the
operations where
, orderby
, and select
over the data it queries.
See the test case under test/pset3/core_test.clj
for more details.
Write with-file
. It takes a filename, and binds it to the symbol file
.
Within the macro body, file
refers to the java.io.File
object.
See the test case under test/pset3/core_test.clj
for more details.
What's wrong with this macro?
(defmacro square [n]
`(* ~n ~n))
Give us a failing case and write a corrected version of the macro!
Consider the following numeric if macro, which executes pos
, zero
, or neg
, base on the sign of val
.
(defmacro nif [val pos zero neg]
`(let [~'res ~val]
(cond (pos? ~'res) ~pos
(zero? ~'res) ~zero
:else ~neg)))
The fact below holds true as is:
(nif -1
"positive"
"zero"
"negative") => "negative"
However, this next fact doesn't. Identify the bug and fix it.
(let [res (java.util.Scanner. (java.io.FileInputStream. "project.clj"))]
(do (nif 0
"positive"
(prn (.nextLine res))
(prn "negative"))
(.close res))) => nil
The construct of monads play a central role in the Haskell programming language, where they underpin the IO system and many other parts of the language. At a high level, a monad allows for composable computation descriptions. For some helpful resources, see
- Haskell wiki article: https://wiki.haskell.org/Monad
- Clojure-focused introduction: https://github.com/khinsen/monads-in-clojure/blob/master/PART1.md
Consider the following list monad:
(def list-monad
{:return (fn [v] [v])
:bind (fn [mv f]
(if (seq mv)
(apply concat (map f mv))
[]))})
Using the above implementation, the fact below holds true:
(let [bind (:bind list-monad)
return (:return list-monad)]
(-> [1 2]
(bind (fn [a]
(-> [a (- a)]
(bind (fn [b]
(return (* 3 b))))))))) => '(3 -3 6 -6)
Now, write a macro, domonad
, that permits a nicer monad comprehension syntax
as follows:
(domonad list-monad
[a [1 2]
b [a, (- a)]]
(* 3 b)) => '(3 -3 6 -6)
Source: Leonardo Borges's Macro Workshop in Clojure