└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # clojure-exercises 2 | 3 | A bunch of simple exercises to get you started with Clojure. 4 | 5 | ## getting started 6 | 7 | To work on the exercises you need a clojure environment. Here are 8 | three recommended ways of getting one: 9 | 10 | - Work on the exercises online at http://clojurescript.io 11 | - If you want to start programming clojure for real, install Leiningen: https://leiningen.org 12 | - Nightcode is a nice and easy clojure IDE that you can install on 13 | Windows, OS X or Linux: https://sekao.net/nightcode/ 14 | 15 | ## useful stuff 16 | 17 | To work on the exercises you'll need to refer to these materials: 18 | 19 | - https://www.cis.upenn.edu/~matuszek/Concise%20Guides/Concise%20Clojure.html -- 20 | this nice cheat sheet 21 | - http://clojuredocs.org -- documentation for clojure functions (with examples!) 22 | - http://clojure.org/reference -- long-form documentation about clojure concepts 23 | 24 | ## exercises 25 | 26 | ### syntax 27 | 28 | 1. compute `1+1` 29 | 1. call the function `get` with arguments `"ciao"` and `1` 30 | 1. compute `(3+4/5)*6` 31 | 32 | 1. define a _vector_ with the elements `1`, `"hello"` and `true` 33 | 1. define a vector that contains the _keywords_ `:diff` and `:merge` 34 | 35 | 1. define a _map_ with the key `1` is associated with the value `"hello"` and the key `:key` 36 | with the value `[13 7]` 37 | 38 | 1. use `def` to define a _variable_ `my-map` that refers to the map `{1 2}`. 39 | Use the `assoc` function to add a new key and value to `my-map`. What does 40 | the `assoc` call return? What is the value of `my-map` after the call? 41 | 42 | 1. use `conj` to add a value to a vector 43 | 1. use the function `get` to get the second element from a vector 44 | 1. use the function `get` to get the value of a key from a map 45 | 1. get the value of a key from a map using the map itself as a function 46 | 1. get the value of a key from a map using a keyword as a function 47 | 48 | 1. use the function `get-in` to return the value `:treasure` from the value: 49 | 50 | ```clojure 51 | {:description "cave" 52 | :crossroads [{:contents :monster} 53 | nil 54 | {:contents [:trinket :treasure]}]} 55 | ``` 56 | 57 | 1. use `defn` to define a function hello that works like this: `(hello) ==> "hello!"` 58 | 1. define a function `double` that works like this: `(double 5) ==> 10`, `(double 1) ==> 2` 59 | 1. add a _docstring_ to the function `double`. Then show it using `(doc double)`. 60 | 1. challenge! implement a `factorial` function using recursion. 61 | 62 | ### conditionals & structures 63 | 64 | 1. use the `let` structure to define a local variable `b` with the value `"bork"`. 65 | Then use the `str` function to combine two `b`s into `"borkbork"`. 66 | 1. define a function `small?` that returns `true` for numbers under 100 67 | 1. define a function `message!` that has three cases: 68 | 69 | ```clojure 70 | (message! :boink) ==> "Boink!" 71 | (message! :pig) ==> "oink" 72 | (message! :ping) ==> "pong" 73 | ``` 74 | 75 | 1. reimplement `message!` using the `if` structure 76 | 1. reimplement `message!` using the `cond` structure 77 | 1. reimplement `message!` using the `case` structure 78 | 79 | 1. challenge! use the `loop` structure to add `1` to an empty vector until it has 10 elements. 80 | Note: `loop` can be hard. Don't get stuck on this exercise! 81 | 82 | ### functional programming? 83 | 84 | 1. increment all the numbers in the vector `[4 7 9 10]` by one. Use 85 | the `map` funktiota. Hint: the function `inc` 86 | 1. do the same as in the previous exercise, but leave only the even results in the vector. 87 | Use the functions `filter` and `even?` 88 | 1. use the `for` structure to go through this vector of maps: 89 | 90 | ```clojure 91 | [{:id 1 :value 7.0} {:id 2 :value 3.0} {:id 7 :value 1.1}] 92 | ``` 93 | 94 | and return a sequence of the `:value`s: `(7.0 3.0 1.1)` 95 | 1. Use the function `update-in` to change 3 into 4 in the value below: 96 | 97 | ```clojure 98 | {:shops [:shop-1] 99 | :customers [{:id "Pekka" 100 | :account {:balance 3}}]} 101 | ``` 102 | 103 | 1. challenge! use the `reduce` function to combine a vector of maps like this: 104 | 105 | ```clojure 106 | (combine [{:a 1 :b 2} {:c 3} {:d 4 :e 5}]) 107 | ==> {:a 1 :b 2 :c 3 :d 4 :e 5} 108 | ``` 109 | 110 | ### concurrency and parallelism 111 | 112 | Atoms and refs are one of the coolest features of clojure, enabling 113 | controlled mutation. This makes for safe & clear concurrent code. 114 | Unfortunately I only have some basic exercises here, nothing with 115 | concurrency. 116 | 117 | 1. define an _atom_ called `counter` that contains the value `4` 118 | 1. get the value of `counter` using the `@` operator 119 | 1. update `counter` to the value `5` with the function `reset!` 120 | 1. get the value of `counter` using the function `deref` 121 | 1. update `counter` to the value `6` by using the function `swap!` 122 | Hint: remember `inc`. 123 | 124 | 1. define a _ref_ called `account` that contains the value `4` 125 | 1. get the value of `account` 126 | 1. update `account` to the value `5` with the function `ref-set`. 127 | NB! you'll have to use the `dosync` macro 128 | 1. update `account` to the value `6` with the function `alter` 129 | 130 | ### what next? 131 | 132 | The website http://4clojure.com has lots of clojure exercises! 133 | --------------------------------------------------------------------------------