Clojure Goodness: Repeating A Value Or Function Invocation
In Clojure we can use the
repeat function to get an infinite sequence of a given value. We can pass a length argument to get a fixed size sequence of the value. Clojure also provides the
repeatedly function that takes as argument a function without arguments. A infinite sequence of invocations of the function is returned. Just like with the
repeat function we can pass a length argument so the returned sequence has a fixed size.
We use the
repeatedly function in the following example:
(ns mrhaki.core.repeat (:require [clojure.test :refer [is]]) (:import (java.time LocalTime))) ;; repeat creates an infinite sequence of the given value. (is (= ["Clojure" "Clojure" "Clojure"] (take 3 (repeat "Clojure")))) ;; We can pass a length argument to restrict the number of ;; times the value is repeated. (is (= ["rocks" "rocks" "rocks"] (repeat 3 "rocks"))) (defn parrot-talk [s] (repeat 2 s)) (is (= ["Polly wants a cracker" "Polly wants a cracker"] (parrot-talk "Polly wants a cracker"))) (defn before? "Helper function returns true if t1 is before t2, false otherwise" [[^LocalTime t1 ^LocalTime t2]] (.isBefore t1 t2)) (defn current-time "Return current time"  (LocalTime/now)) ;; repeatedly create an infinite sequence of function invocations. ;; The function must have no arguments. (is (before? (take 2 (repeatedly current-time)))) (is (before? (repeatedly 2 current-time))) (defn latest-time "Get the 'latest' time from a collection with time values." [coll] (reduce (fn [latest time] (if (.isAfter latest time) latest time)) coll)) (def current-times (repeatedly 100 current-time)) ;; as each time is later than the next time value ;; the following equation must be true. (is (= (latest-time current-times) (last current-times)))
Written with Clojure 1.10.1.