Learning to read and write recursively

I am very new to Clojure and I have seen this template in other languages ​​before. I think I know how recursion works, but I don’t know how to read and how to think in such a way that this code can be written. Here's a trivial example:

(defn remove-dups [str]
  (when-let [[fst & rst] (seq str)]
    (if (= fst (first rst))
      (remove-dups rst)
      (cons fst (remove-dups rst)))))

I’m sure that an experienced Kladurorist doesn’t look very complicated. However, I still do not know how to read such code. Maybe there is a pattern that you should learn to understand? Lisp and Clojure are said to be reading “inside out,” but I can't find a quick way to mentally parse code like this. Maybe there is a way to "expand" recursive patterns by printing steps? Please, someone will teach me to think in terms of "divide and conquer."

+4
source share
2 answers

I suspect this is a question that many people who want to get closer to Clojure ask themselves, and most of them are afraid to ask, so thanks for leaving. It is also a very personal commitment to wrap the brain around recursion. And I say this from expropriation. Back in college, I was a teacher in a course that introduced recursion (for five years), and I spend these five years trying to figure out a “way” to “show” people how to deploy code snippets like this.

During this time, I developed these ideas that seemed to hold on in every case:

  • No one could read this code at the first exposure
  • As soon as they “understood”, they could not then explain it in a useful way to those who had not yet “received”.
  • , "", ( )

, , - , . -, .

, :

  • ( , ): Clojure Leiningen + emacs + clj-refactor . .
  • ( ) . , , , , , .
  • , . , , ( ).
  • , . , , , , , .

, , , , , .

+4

, . , , /. n n + 1. - n, n-1. 1 0, .

, , ( ) (, ) ( ). [fst & rst] (seq str). Clojure, .

(let [fst (first str) rst (rest str)])

, . , , , , - (, , ..). , , - cons, , cons.

remove-duplicates: , , , , () , (remove-dups rst). , , (remove-dups rst) ( ).

.

(defn remove-dups [str] (if (empty? str) nil (let [fst (first str) rst (rest str)] (if (= fst (first rst)) (remove-dups rst) (cons fst (remove-dups rst))))))

"" nil 3.

+1

Source: https://habr.com/ru/post/1621359/


All Articles