Finite lazy-seq - how to terminate?

Questions on lazy-seq.

I stumbled on below code from clojure essential reference book

(defn untangle [n xs]
  (letfn [(step [xs] 
            (lazy-seq 
              (cons 
                (take-nth n xs)
                (step (rest xs)))))] 
    (take n (step xs))))

(untangle 2 (interleave (range 3) (repeat 3 ".")))
;; ((0 1 2) ("." "." "."))

I understand if xs is an infinite sequence. It generates next element on demand.
But it’s a finite sequence. My question is how the lazy-seq knows when it terminates the step function.

Cheers,
sun

The lazy-seq is infinite, not finite–i.e. it doesn’t terminate the step function. the key is the (take n (step xs)), that’s why the output is finite. If you change it to (take 10 (step xs)) for example, you’ll get this output: ((0 1 2) ("." "." ".") (1 2) ("." ".") (2) (".") () () () ())

1 Like

hmmm, even if the input is finite, it can generatie infinite sequence.
thanks a lot.

Hello @sunjlee!

Glad you got your problem solved.

For future reference, if you paste your code like this into your editor, you get syntax highlighting, which makes it easier to read the code:

```clojure
(defn untangle [n xs]
(letfn [(step [xs]
(lazy-seq
(cons
(take-nth n xs)
(step (rest xs)))))]
(take n (step xs))))

(untangle 2 (interleave (range 3) (repeat 3 “.”)))
;; ((0 1 2) ("." “.” “.”))
```

That way, you can even keep your code indentation:

(defn untangle [n xs]
  (letfn [(step [xs]
            (lazy-seq
             (cons
              (take-nth n xs)
              (step (rest xs)))))]
    (take n (step xs))))

(untangle 2 (interleave (range 3) (repeat 3 “.”)))
;; ((0 1 2) ("." “.” “.”))

Thanks!

Teodor

1 Like

Three backtick?

2019년 7월 13일 (토) 오후 1:13, Teodor Heggelund via ClojureVerse [email protected]님이 작성:

Yup, triple backtick in before and after the code. And clojure after the first backtick.

Read this https://guides.github.com/features/mastering-markdown/