This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

## 2018-12-20

## Channels

- # adventofcode (47)
- # announcements (3)
- # aws (29)
- # bangalore-clj (3)
- # beginners (63)
- # boot (2)
- # braveandtrue (40)
- # calva (34)
- # cider (37)
- # cljs-dev (8)
- # clojars (3)
- # clojure (45)
- # clojure-europe (2)
- # clojure-france (4)
- # clojure-gamedev (1)
- # clojure-india (2)
- # clojure-italy (44)
- # clojure-japan (4)
- # clojure-nl (39)
- # clojure-serbia (1)
- # clojure-spec (21)
- # clojure-uk (75)
- # clojurescript (28)
- # cursive (24)
- # data-science (3)
- # datomic (31)
- # emacs (13)
- # fulcro (35)
- # hoplon (21)
- # jobs-discuss (66)
- # nrepl (18)
- # off-topic (72)
- # pathom (35)
- # re-frame (20)
- # reagent (54)
- # shadow-cljs (35)
- # spacemacs (9)
- # specter (8)
- # sql (13)
- # testing (9)
- # tools-deps (21)
- # vim (3)

Sorry for answering a day later, but our time zones are probably way off and I had a busy day. 🙂

No problem, Slack is actually not too bad at compensating for timezone offsets, if you don’t mind waiting a bit for replies. 🙂

I played with writing a `my-comp`

function, and I used recursion (not `reduce`

). I will say that I’ve been writing Clojure for 7 or 8 years, and I’m pretty comfortable in it, but I still found this problem a bit tricky, even having a pretty good idea how it should be solved.

The basic pattern of recursion is that you figure out the easy problem, also known as the “base case”, and then figure out how to have the function solve slightly more complex problems by calling itself. And it’s only *slightly* more complex. You don’t have to figure out all possible answers, you just have to figure out two cases: the base case, and the “base case + 1".

So, for example, to write a factorial function, you first solve the simple case where `n = 1`

```
(defn fact [n]
(if (= n 1)
1
,,,
))
```

Then for numbers greater than 1, you take the definition of “factorial” and try to find some way to phrase it in terms of itself.

`factorial(n) = n * (n - 1) * (n - 2) * ... 2 * 1`

is the “naive” definition of factorial, but we can write that more concisely by defining it recursively: `factorial(n) = n * factorial(n - 1)`

So in Clojure terms we get this: ```
(defn fact [n]
(if (= n 1)
1
(* n (fact (dec n)))))
```

So far so good? This is the “easy” part — we’re doing recursion with *data*, and getting back a result that is *data*. What makes Chapter 5 tricky is that we want to do the same thing with HOFs (Higher Order Functions).

We still want to solve the problem the same way: look for a simple, base case that we know the answer to, and then try to find a way to define our fn recursively so that it eventually winds down to our simple base case.

For this particular problem, *Brave and True* gives us the simple base case: “comp” with two functions.

```
(defn brave-comp [f g]
(fn [& args]
(f (apply g args))))
```

Now all we have to do is figure out the recursive case.I’ll stop there so you can have a look at this and ask any questions. This *might* be enough to get you heading in the right direction, but recursion is a tricky concept to master, and doubly tricky when you’re trying to apply recursion to higher-order functions. We’re pretty close to solving this though, so you might want to take a whack at this on your own and see if you can crack it.

Awesome explanation! Thank you 🙂 I have tried many hours yesterday after I spoke here, and have a file full of unfinished half-thoughts, but with this explanation I think that I have at least a clue. Well, it's not working right now, but I believe I'm not that far, so I'll keep trying a bit more 😄

I really don't get the part of "a way of using recursion that will naturally give you the last-to-first order without reverse" 😕

Well, I'd say just ignore that part for now and just see if you can figure out the recursive bit.

If you get the recursive bit, the last-to-first order bit will kind of solve itself.

This is what I have so far

```
(defn my-comp [f & fs]
(fn [& args]
(let [res (apply f args)]
(loop [[head & tail] fs
result res]
(if (not (nil? tail))
(recur tail (apply head (vector result))))))))
```

But it isn't working 😕 gives me "nil" always.I have no experience with forcing evaluation with apply, so maybe this is where it's going wrong.

And using `reverse`

I could probably just ask for `[& fs]`

in `my-comp`

and reverse it, extract the head, etc.

The structure of my solution looks very similar to the `factorial`

function I used as an example.

Though you can use recur without a loop. It makes recursion a bit safer in clojure but you’re probably not recursing a lot with a comp function though 😄

2 or more functions (you could do it so that it supports 1 function, but that’s kind of an edge case and it nicer not to worry about that until you get the 2-or-more version working)

If you look at my `factorial`

function above, the function definition contains 1 call back to itself, without `loop`

or `recur`

.

Oh right, I think I used the wrong term. It still iterates n times. Just as your comp will have to call itself for however many functions are provided to it?

Right, it will keep recursing until it gets down to the base case, which is the 2-argument version of `my-comp`

Ah ok, we’re on the same page then. Isn’t it preferred to use recur though rather than directly calling the function?

Depends on your goal: if you want to avoid blowing the stack for long sequences, `recur`

is better. If you want to illustrate the principle of recursion, it’s nice not to have to worry about it, and just call directly--it makes the code a little simpler.

Arguably, `comp`

is a special case: you’ll only be using it for code that you write, and you’re unlikely to try and comp together so many functions that you blow the stack. (It could happen, though, in which case you’ll need the `recur`

version.)

In general real-world programming, it’s usually better to use `recur`

to avoid the stack overflow problem.

Hmm, “Depends on your goal..” etc sounds snooty. I should have just said, “Yes, usually you would prefer `recur`

and I’m just making an exception in this case to make the exercise simpler.”

You’re right. The code is simpler doing it directly the solution I had in mind would only have recur’d the inner anonymous function when we need to reach the outer my-comp function.

You could probably make that work by adding more args to the anonymous function but likely not practical or worth it