As I'm a few episodes behind, I'm not sure whether you still do there questions or whether my question is worth an episode, but I still wanted to ask: What do you think about about defining small helpers in a let
inside of the function? I quite like it, as they are private to the function (cannot be used outside) and I can initialize them with arguments to the outer function or other values calculated in the let. Otherwise I need to always pass these values as arguments to these inner functions. A colleague thinks that the function becomes too big that way. I actually only consider the let body to be the function body.
Will post a small example soon
(defn- xxx [{:keys [account-codes]}]
(let [relevant-line? (fn [line]
(contains? account-codes (:account-code line)))
# ...
Regarding too big. I often define these outside the let and then bind them there. It makes them easier to test as well. They are not as private, granted, but if my modules are small enough, that is not too much of a trade off.
@pez Can you elaborate on what you mean by binding the there? Are you using partial
?
It will depend on what my needs are... If I need the closure, or not, or if it is just a way to keep the let box shorter, or ability to test the utility function. In its simplest form it is just a (defn- foo ...)
and then a (let [f foo])
.
@igel I'm not sure if you've come across it, but letfn
also exists for this purpose. I think it can be a really handy technique if you want to close over a value passed into the function, or if you want some sort of mutual recursion where the functions reference each other.
I really do like make short little predicate functions and using those instead of long conditional statements. Since the condition can be pretty specific to the enclosing function, I like having the function definition inside the function.
On the other hand, sometimes I find myself needing the same little predicates in more than one place, so then I would promote it up to make it is own function.
If I think back on when I've done it myself, I've used a local function for keeping a recursion helper inside of the "public" function that needs it, or to create a local predicate so I can make my map/filter expressions more readable.
I don't use it very often, but I do use it sometimes.
Also, I'm looking forward to the episode! 🙂