Skip to content

Latest commit

 

History

History
115 lines (69 loc) · 3.8 KB

2020-06-23.md

File metadata and controls

115 lines (69 loc) · 3.8 KB

Accessing members of a collection by using it as a verb

4clojure's 21st problem

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))))

Accessing members

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 bindings

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.

  • lets cannot be reassigned.

Example

(let [cats 5]
    (str "I have " cats " cats.")) ; will return "I have 5 cats."

Vars

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

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.

Naming functions

All the ways to declare a function in Clojure

Anonymous functions

(fn [x] (+ x 1))
#(+ % 1)
(partial + 1)

Named functions

(def incr (fn [x] (+ x 1)))
(defn incr [x] (+ x 1))
(fn incr [x] (+ x 1))

Passing arguments to functions

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})

Other Updates

Little ClojureFam update

You can now track my progress in the ClojureFam repository as well, I created my learner card!

Meta Commentary

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.