malli

2025-05-18T06:14:25.335539Z

Hi folks, I've got a question about trying to use lazy-cat with malli. Here's a complete example:

(require 
  '[malli.core :as m]
  '[malli.instrument :as mi])

(defn numbers [n]
  (lazy-cat (repeat n n) (numbers n)))

(m/=> numbers [:=> [:cat :int] [:sequential :int]])

;(mi/instrument!)

(take 3 (numbers 10))
If I run the above example, I get three 10s, as expected. If I remove the comment on mi/instrument! and re-run the example, I get a stack overflow. It seems like instrumentation causes the infinite seq to be fully realized. Is this a known issue or do I need to write the spec differently?

2025-05-19T13:03:17.546779Z

I guess it makes sense since the output would need to be fully realized to ensure everything is valid. The take happens downstream of the spec validation.

opqdonut 2025-05-19T13:05:38.450829Z

yep

2025-05-19T23:12:44.587509Z

Use :every for potentially infinite collections. https://github.com/metosin/malli?tab=readme-ov-file#seqable-schemas

2025-05-19T23:13:23.234809Z

It checks a bounded number of elements (100 by default IIRC).

2025-05-19T23:14:02.602999Z

Nice!!!

2025-05-19T23:14:06.098049Z

Thanks!

😁 1
2025-05-19T23:19:50.335049Z

It doesn't require sequential? tho fwiw. You might need to use [:and [:every :int] sequential?] if you care about that (relevant for generators).

👍 1
opqdonut 2025-05-20T04:51:05.276749Z

thanks, I didn't know about :every 😅

opqdonut 2025-05-19T05:36:45.423029Z

I don't think malli has anything for lazy validation of lazy sequences. I think you'll just need to skip instrumenting that function.

👍 1