practicalli / practicalli/clojure

Clojure.core - loop

Open
#15 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Makefile
Stars
117
Forks
36
PR merge metrics
No merged PRs in 30d

Description

Often in functional langues iteration (for loops or while loops in C) are expressed as recursive function calls and the compiler recognizes those recursive calls as being loops and compiles them as such. Clojure doesn't do that, and instead provides the less general combination of loop/recur which in usage follow the same pattern as an iterative process encoded as recursive function calls
(this might be a good point for something about for not being a loop in clojure)

Clojure's for loop is like for-comprehensions in Python, I think?

one way to think of loop in Clojure is that while it is possible to write loops similar to how they are written in imperative languages, it is definitely not typical "idiomatic" Clojure code. A purely functional loop expression does not modify any values that are visible when you enter the loop, and technically it doesn't modify the 'loop variables' either. The first time you start the loop, the symbols given in square brackets are 'bound' (similar to assigned, but only once) to the initial values shown.
Leave out the possibility of nested loop expressions for simplicity for the moment.
The loop body is evaluated, say having some conditional expressions like if or cond, but no assignment statements like you would find in imperative languages.
Either that branching ends with evaluating an expression that is not a recur expression, and that value becomes the return value of the entire loop expression.
Or it ends with evaluating a recur expression. That is similar to a recursive call to the beginning of the loop expression, with new initial values for all loop 'variables' (except they are not variables). So those loop variables are kinda sorta "assigned a value only once at the beginning of each loop iteration", not at arbitrary points in the middle.

To illustrate Andy's description
user=> (loop [acc 0 n 10]
(if (pos? n)
(recur (+ acc n) (dec n))
acc))
55

So that is maybe a 'negative' way to explain it, by the restrictions imposed on you -- you get to 'assign' (really 'bind') a value to the loop 'variables' (more technically 'symbols') at most one time per iteration through the loop, not any number of times you want like you could in imperative programming languages. Also the loop symbols are purely local to the loop -- they are out of scope when the loop returns (again, unlike in most imperative languages).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with issue #15 and determine where this explanation of Clojure loop/recur belongs in the repository; no target file or test is named. Clarify the scope before editing, including the contrast with imperative loops and Clojure's for comprehensions. Done means the documentation gives a concise, accurate explanation with the provided example.

Written by the indexing model from the issue text.

Assessment

Tech stack
clojure
Domain
documentation
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.