Clojure source for repeatedly reads:
Takes a function of no args, presumably with side effects, and returns
an infinite (or length n if supplied) lazy sequence of calls to it.
Without knowing the above explanation, how do I infer that the below definition of repeatedly takes a function of no arguments?
(defn repeatedly
([f] (lazy-seq (cons (f) (repeatedly f))))
([n f] (take n (repeatedly f))))
By looking for references of the function being passed in.
Note:
(f)
f is only referenced three times in the definition. Two of those times are it being passed in to recursive calls (you can tell it's not being called because it's not surrounded by brackets), and once where it's called.
In the case where it's called (surrounded by brackets), you can tell it expects 0 arguments since none are being passed to it.
Related
Just when I thought I had a pretty good handle on macros, I came across the source for some which looked a bit odd to me at first glance.
(defn some
[pred coll]
(when (seq coll)
(or (pred (first coll)) (recur pred (next coll)))))
My first instinct was that seems like it would be stack consuming, but then I remembered: "No, dummy, or is a macro so it would simply expand into a ton of nested ifs".
However mulling it over a bit more I ended up thinking myself in a corner. At expansion time the function source would look like this:
(defn some
[pred coll]
(when (seq coll)
(let [or__4469__auto__ (pred (first coll))]
(if or__4469__auto__
or__4469__auto__
(recur pred (next coll))))))
Now what's got me confused is that final recur call. I've always thought that macroexpansion occurs prior to runtime, yet here you have to actually call the already expanded code at runtime in order for the second macroexp .... wait a second, I think i just figured it out.
There is no second macroexpansion, there are no nested if blocks, only the one if block. The call to recur just keeps rebinding pred and coll but the same single block above keeps testing for truth until it finds it, or the collection runs out and nil is returned.
Can someone confirm if this is a correct interpretation? I had initially confused myself thinking that there would be an interleaving of macroexpansion and runtime wherein at runtime the call to recur would somehow result in a new macro call, which didn't make sense since macroexpansion must occur prior to runtime. Now I think I see where my confusion was, there is only ever one macro expansion and the resulting code is used over and over in a loop.
To start with, note that any function can serve as an implicit loop expression. Also, recur works just like a recursive function call, except it does not use up the stack because of a compiler trick (that is why loop & recur are "special forms" - they don't follow the rules of normal functions).
Also, remember that when is a macro that expands into an if expression.
Having said all that, you did reach the correct conclusion.
There are two modes of recursion going on here:
The or macro is implicitly recursive, provoked by the sequence of argument
forms into generating a tree of if forms.
The some function is explicitly recursive, provoked into telling the single
sequence of its final argument. The fact that this recursion is
recurable is irrelevant.
Every argument to the or macro beyond the first generates a nested if form. For example, ...
=> (clojure.walk/macroexpand-all '(or a b c))
(let* [or__5501__auto__ a]
(if or__5501__auto__ or__5501__auto__
(let* [or__5501__auto__ b]
(if or__5501__auto__ or__5501__auto__ c))))
You have two arguments to or, so one if form. As Alan Thompson's excellent answer points out, the surrounding when unwraps into another if form.
You can have as many nested if forms as you like, the leaves of the if tree, all of them, are in tail position. Hence all immediate recursive calls there are recurable. If there was no such tail recursion, the recur call would fail to compile.
As also explained in the answers of this question, Clojure determines the number of parameters of an anonymous function (defined through #()), by the maximal parameter index referenced in the body (e.g. if the maximal referenced parameter is %4, then that anonymous function has 4 parameters).
Question: is there some syntax to tell the Clojure compiler that an anonymous function expects one parameter, even not referencing that parameter? Or, in this case, the only "clean way"* is to use the fn syntax? (* "Clean way": I'm aware that in most cases, you could reference the dummy parameter without affecting the function -- see below, but I would like to avoid such workarounds.)
My use case: I have a function (defn foo [predicate]), where predicate expects exactly one argument, and I would like to test foo with a predicate that always returns true. (I.e., something like #(true).) This causes an ArityException since the interpreter thinks that #(true) expects zero arguments.
In this particular case, I could use some clever hack like #(or true %), but:
It is almost as much to type as the fn-variant.
I'm interested if there is a generic solution.
Edit: so to be clear, I'm looking for something like this:
#[1](true) ;; the anonymous function takes one parameter
No. Just use fn. That's what it's for.
If it's a constant return you are after you can use constantly:
(map (constantly 10) '(1 2 3 4 5))
; ==> (10 10 10 10 10)
If it's not you can use fn with a rest argument:
(fn [& _]
some-side-effect-expression)
; ==> non functional value
In fact this can be done on higher order functions where you don't need all the passes arguments:
(some-fun (fn [a b & _] (+ a b)) '(1 2 3 4 5))
; ==> (3 5 7 9)
If you insist on the #( ... ) syntax, you can write
#(do % true)
... incurring no run-time penalty, whatever you want to return.
But (constantly true), as #Sylvester suggests, is idiomatic, and accepts any argument list:
((constantly true) 1 2 "Buckle my shoe");true
In Clojure, there is a higher-order function reductions, which you would use with arguments similar to reduce and will return a sequence containing all intermediate results.
Is there an equivalent in Common Lisp? I was unable to find any reference to it online, including the various books/articles on https://common-lisp.net/tutorials/ but given Lisp's heritage as a family of List Processing languages I imagined a list->list function like reductions will exist across dialects.
There is no standard function for it. You could define one easily:
(defun reductions (function sequence &rest args
&key key from-end (start 0) end initial-value)
(declare (ignore key from-end start end initial-value))
"Return a list of intermediate values from reducing SEQUENCE with FUNCTION."
(let* ((reductions (list))
(result (apply #'reduce
(lambda (&rest arguments)
(let ((result (apply function arguments)))
(push result reductions)
result))
sequence
args)))
(values (or (nreverse reductions)
(list result))
result)))
(reductions #'+ '(1 2 3 4 5 6 7 8 9 10) :initial-value 0)
;=> (1 3 6 10 15 21 28 36 45 55)
Edit: Use APPLY with &REST ARGS instead of calling REDUCE directly. Some implementation of REDUCE might not work if NILs are supplied for keyword arguments.
Edit2: The reducing function can be called with 0 or 2 arguments.
Edit3: When REDUCE is called with a list of only one element, the only element is returned as is. The reducing function is not called at all, which means the list of reductions would be empty. I added an OR to return the final result wrapped in a list in that situation (to match Clojures behaviour). I also changed the code to return the final result as a second return value (might be useful and "why not?").
OK, a fibonacci function in Clojure:
(defn give-fibs []
((fn fib-seq [a b]
(cons a (lazy-seq (fib-seq b (+ a b)))))
0 1))
Now, my question is, when I call it like so, I get an error :
(take 10 give-fibs)
edit, error is - java.lang.IllegalArgumentException: Don't know how to create ISeq from: four_cloj.core$give_fibs
However, it works when I call:
(take 10 (give-fibs))
When I check out what's going on, I can't really explain it:
(class (give-fibs)) ; clojure.lang.Cons
(class give-fibs) ; four_cloj.core$give_fibs
??
give-fibs is just that - the function itself. The concept of a function as a value that can be passed around (for example, as argument to take) takes some getting used to, but it's perfectly sensible and normal.
(give-fibs) is the result of calling give-fibs with no arguments, which is what you want in this context. The result is a list, and each element of a list is a Cons object, which is what class tells you.
In this expression you don't really call give-fibs:
(take 10 give-fibs)
you just pass the function itself to take. What you want is to actually call give-fibs in order to pass result of it to take:
(take 10 (give-fibs))
Remember that the first element in an s-expression is considered to be in function position, that is to say it will be executed. Therefore give-fibs and (give-fibs) are different in that the former is the actual function being passed to take and the latter is calling that function, and therefore returning the result to be passed to take.
Thats why (class give-fibs) is a function, and (class (give-fibs)) is a Cons cell as expected.
Just remember the first var after an opening bracket is in function position and will be executed, and its perfectly valid to pass an unexecuted function to another.
What is convention for local vars that has same meaning as function argument?
If I need local variable that has as its initial state value of function argument (and thus has the same meaning), how should I call it?
As artificial example (that, however, demonstrates quite popular construction in Clojure):
(defn sum [coll]
(loop [local-coll coll, result 0]
(if (empty? local-coll)
result
(recur (rest local-coll) (+ (first local-coll) result)))))
Here local-coll is initialized to the value of coll initially, and it also holds this meaning during looping. local-coll is definitely not a good name for it, but what is?
In Haskell it is a good style to put quote (') to the end of variable/function name, e.g. var'. In Common Lisp sometimes I saw names ending with asterisk (*). Clojure has same notation for function that duplicate another function meaning but have a bit different semantics (e.g. list*). But this notation is also frequently used in docstrings to indicate that there may be several items of this type (e.g. (methodname [args*] body)* or (try expr* catch-clause* finally-clause?)) and thus can confuse when used for local var names.
Java interop also provides things like defn-, that is names ending with hyphen (-) to indicate private methods in generated classes. So it makes some sense to use hyphen for local (private for a function) variables too (though it seems a bit weird for me).
So, what the way should I go when naming my local variables with the same meaning as function argument?
I think it's fine to shadow the argument name when you don't need the original argument any more:
(defn sum [coll]
(loop [coll coll, result 0]
(if (empty? coll)
result
(recur (rest coll) (+ (first coll) result)))))
Other variations that I've seen are:
(loop [c colls] ...)
(loop [coll initial-coll] ...)
(loop [foo foo-coll] ...)
(loop [s specs] ...)