The question of this problem was to reimplement nth
. nth
retrieves the nth item of a collection. Since I know a little bit of Scheme I immediately reached for a recursive pattern. This is definitely possible for this problem but there must be a better solution that I did not think about. And if I don't force myself I will not be learning much Clojure.
My answer, with a recursion (fn nthel [l n] (if (= n 0) (first l) (nthel (rest l) (- n 1))))
However it is possible to access a vector's members by using the vector as verb:
user=> ([:a :b :c] 1) ; :b
My new solution is much shorter:
(fn nthel [l n] ((vec l) n))
It was interesting to see that most of the people who completed all of the 4clojure problems also used a recursion.
Clojure from the Ground Up -- Chapter 3
let
lets you declare a symbol, within a specific expression. This looks like a local variable.
-
It takes a vector, and we alternate between symbol and meaning.
-
They will be executed in order.
-
Symbols won't be accessible outside of the expression.
-
You can also override an existing symbol.
-
let
s cannot be reassigned.
(let [cats 5]
(str "I have " cats " cats.")) ; will return "I have 5 cats."
Vars are mutable variables and use the def
keyword to be created. It's a different type of value. It binds a symbol to a value, like this (def cats 5)
. This is to be used carefully in Clojure.
Functions are like verbs, inc
is a symbol which points to a "verb". In this case, inc
is short for increment. You can refer to a symbol without evaluating it with a quote, so like 'inc
, which will return inc
. It will be the case for every value and also function calls like '(inc 1)
. I have started collecting here the functions that I encounter. You always put the function first and can add the arguments afterwards. A function is like a let
, but unbound. It's also evaluated later, when it is passed arguments. It's created with fn
.
Function shorthand A function written like this (fn [x] (+ x 2))
can be rewritten like this #(+ x 2)
, or if it has several arguments %1
, %2
are to be used.
(fn [x] (+ x 1))
#(+ % 1)
(partial + 1)
(def incr (fn [x] (+ x 1)))
(defn incr [x] (+ x 1))
(fn incr [x] (+ x 1))
You can create a function that takes no argument with []
.
It is possible to declare a function that will take different numbers of arguments: 0, 1 or more. This is how you define them, you give it a list:
(defn incr
([] 1)
([x] (+ x 1)))
You can also create a function that takes an unlimited number of arguments: it will lump all the "extra" arguments after &
together in a list. Anything before the $
is mandatory.
(defn vargs
[x y & more-args]
{:x x
:y y
:more more-args})
- Added 12 functions to the cheatsheet
- Did 7 4clojure problems
You can now track my progress in the ClojureFam repository as well, I created my learner card!
I already find myself going back to my notes and cheatsheet, more often than going back to the original text. In a way I trust what I have been writing, which is vastly different than when I was in school. That may be explained by the fact that I can actually go at my own pace here.