Rekursion puolustus / In Defence of Recursion

Panu A. Kalliokoski
Helsinki Clojure Meetup / Haskell Meetup
ke 30.10.2024

Cute thing with no informational content

Mitä rekursio on? | What is recursion?

(defn even-elements [coll]
  (if (empty? coll) []
    (cons (first coll)
          (even-elements (rest (rest coll))))))

iloinen panda


(declare saha-aalto)
(def saha-aalto (concat (range 30) saha-aalto))

tappajapanda


Mitkä kielet tukevat rekursiota? | Which languages support recursion?

Miten ohjelmoijat suhtautuvat rekursioon? | What kind of stance do programmers have towards recursion?


ujo retiisi


(jatk./cont.)


kuolaava peruna


Miksi rekursiota pitää ja saa käyttää? | Why you should and may use recursion?


söpö panda


(jatk./cont.)

Vihdoinki jotain koodia! | Finally some code!

(defn long-subs-count [coll threshold]
  (count (filter (fn [elem] (> (count elem) threshold)) coll)))

(defn long-subs-count [coll threshold]
  (cond
    (empty? coll) 0
    (> (count (first coll)) threshold)
      (inc (long-subs-count (rest coll) threshold))
    :else (long-subs-count (rest coll) threshold)))

Entä alun esimerkki? | How about the example at the beginning?

(defn even-elements [coll]
  (map first (partition 1 2 coll)))

(defn even-elements [coll]
  (cond
    (empty? coll) []
    (cons (first coll)
          (even-elements (rest (rest coll))))))

Tällaisessa se alkaa mennä vaikeaksi | In cases like this it gets hairy

(defn elem-surrounded-by [coll surrounder]
  (some (fn [[e1 e2 e3]]
          (and (= e1 surrounder)
               (= e3 surrounder)
               e2))
        (partition 3 1 coll)))

(defn elem-surrounded-by [coll surrounder]
  (cond
    (empty? coll) nil
    (and (= surrounder (first coll))
         (= surrounder (second (rest coll))))
      (second coll)
    :else (elem-surrounded-by (rest coll) surrounder)))

Mites tää? | How about this?

(defn occurrences [data pred?]
  (count (filter pred? (flatten data))))

(defn occurrences [data pred?]
  (cond
    (pred? data) 1
    (not (coll? data)) 0
    (empty? data) 0
    :else (+ (occurrences (first data) pred?)
             (occurrences (rest data) pred?))))

Ne jotka on tosi vaivalloisia ilman | Those really toilsome without

(defn match? [pattern haystack]
  (or
    (and (empty? pattern) (empty? haystack))
    (and (or (= (first pattern) (first haystack))
             (= (first pattern) \?))
         (match? (rest pattern) (rest haystack)))
    (and (= (first pattern) \*)
         (or (match? (rest pattern) haystack)
             (match? pattern (rest haystack))))))

Mites ne mahdottomat? | What about the impossible ones?

(defn splits [vec]
  (map (fn [index] [(subvec vec 0 index) (subvec vec index)])
       (range 1 (inc (count vec)))))

(defn partitions [vec]
  (cond
    (empty? vec) [[]]
    (empty? (rest vec)) [[vec]]
    :else (mapcat (fn [[prefix suffix]]
                    (map (partial cons prefix) (partitions suffix)))
                  (splits vec))))

Miksei rekursiota käytetä (enemmän)? | Why is recursion not used (more)?


pettynyt pupu


Tiedon puute | Lack of knowledge


hikeentynyt porkkana


Ennenaikainen optimointi | Premature optimisation


vahingoniloinen nauris


Estetiikka | Æsthetics

Tarinan opetus | The moral of the story

Kiitos keskittymisestä / Tack för att ni lyssnade / Thank you for focusing

Tiesittekö, että rekursiolla voi generoida kivoja sävelmiä?
Did you know recursion is great for generating nice melodies?