Skip to content

Instantly share code, notes, and snippets.

@albert-yu
Last active June 27, 2018 20:53
Show Gist options
  • Save albert-yu/544fa46fda477780be5461224f536b86 to your computer and use it in GitHub Desktop.
Save albert-yu/544fa46fda477780be5461224f536b86 to your computer and use it in GitHub Desktop.
;;-------------------------------------------
;; FUNCTIONS
;; https://clojure.org/guides/learn/functions
;;-------------------------------------------
;; 1)
;; Define a function greet that takes no arguments and prints "Hello".
;; Replace the _ with the implementation: (defn greet [] _)
(defn greet [] (println "Hello"))
;; 2)
;; Redefine greet using def, first with the fn special form and
;; then with the #() reader macro.
;; using fn
(def greet (fn [] (println "Hello")))
;; using #()
(def greet #(println "Hello"))
;; 3)
;; Define a function greeting which:
;; Given no arguments, returns "Hello, World!"
;; Given one argument x, returns "Hello, x!"
;; Given two arguments x and y, returns "x, y!"
(defn greeting
([] (greeting "World"))
([x] (greeting "Hello" x))
([x y] (str x ", " y "!"))
)
;; tests
(assert (= "Hello, World!" (greeting)))
(assert (= "Hello, Clojure!" (greeting "Clojure")))
(assert (= "Good morning, Clojure!" (greeting "Good morning" "Clojure")))
;; 4)
;; Define a function do-nothing which takes a single argument x and returns it,
;; unchanged.
(defn do-nothing [x] x)
;; In Clojure, this is the identity function.
;; By itself, identity is not very useful, but it is sometimes necessary
;; when working with higher-order functions.
(source identity)
;; 5)
;; Define a function always-thing which takes any number of arguments, ignores
;; all of them, and returns the keyword :thing.
(defn always-thing [& args] :thing)
;; 6)
;; Define a function make-thingy which takes a single argument x.
;; It should return another function, which takes any number of arguments
;; and always returns x.
(defn make-thingy [x] (fn [& args] x))
;; Tests
(let [n (rand-int Integer/MAX_VALUE)
f (make-thingy n)]
(assert (= n (f)))
(assert (= n (f :foo)))
(assert (= n (apply f :foo (range)))))
;; In Clojure, this is the constantly function.
(source constantly)
;; 7)
;; Define a function triplicate which takes another function and calls it
;; three times, without any arguments.
(defn triplicate [f] (apply f []) (apply f []) (apply f []))
;; with dotimes
(defn triplicate [f] (dotimes [n 3] (apply f [])))
;; 8)
;; Define a function opposite which takes a single argument f. It should return another
;; function which takes any number of arguments, applies f on them, and then calls not on
;; the result. The not function in Clojure does logical negation.
;; not sure if this is right
(defn opposite [f] (fn [& args] (not (apply f args))))
;; In Clojure, this is the complement function.
(defn complement
"Takes a fn f and returns a fn that takes the same arguments as f,
has the same effects, if any, and returns the opposite truth value."
[f]
(fn
([] (not (f)))
([x] (not (f x)))
([x y] (not (f x y)))
([x y & zs] (not (apply f x y zs)))))
;; 9)
;; Define a function triplicate2 which takes another function and any number of arguments,
;; then calls that function three times on those arguments. Re-use the function you defined
;; in the earlier triplicate exercise.
(defn triplicate2 [f & args]
(triplicate (fn [] (f args))))
;; 10)
;; Using the java.lang.Math class (Math/pow, Math/cos, Math/sin, Math/PI),
;; demonstrate the following mathematical facts:
;; The cosine of pi is -1
(def pi Math/PI)
(assert (= -1.0 (Math/cos pi)))
;; For some x, sin(x)^2 + cos(x)^2 = 1
;; First, define float equality
(defn fuzzy= [tolerance x y]
(let [diff (Math/abs (- x y))]
(< diff tolerance)))
;; Define square func
(defn sqre [x] (Math/pow x 2))
;; Generate random float
(def number (rand))
(def fl_one 1.0)
(assert
(fuzzy= fl_one
0.000000001 ;; error tolerance
(+ (sqre (Math/cos number)) (sqre (Math/sin number)) ))
fl_one)
;; 11)
;; Define a function that takes an HTTP URL as a string,
;; fetches that URL from the web, and
;; returns the content as a string.
;; Hint: Using the java.net.URL class and its openStream method.
;; Then use the Clojure slurp function to get the content as a string.
(import java.net.URL)
(defn http-get [url]
(slurp (.openStream (URL. url))))
(assert (.contains (http-get "http://www.w3.org") "html"))
;; In fact, the Clojure slurp function interprets its argument as a URL first before
;; trying it as a file name. Write a simplified http-get:
(defn http-get [url]
(slurp url))
;; 12)
;; Define a function one-less-arg that takes two arguments:
;; f, a function
;; x, a value
;; and returns another function which calls f on x plus any additional arguments.
(defn one-less-arg [f x]
(fn [& args] (apply x args)))
;; In Clojure, the partial function is a more general version of this.
;; 13)
;; Define a function two-fns which takes two functions as arguments, f and g.
;; It returns another function which takes one argument, calls g on it, then calls f on
;; the result, and returns that.
;; That is, your function returns the composition of f and g.
(defn two-fns [f g]
(fn [x] (f (g x))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment