Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for :list #431

Open
helins opened this issue Apr 27, 2021 · 5 comments
Open

Support for :list #431

helins opened this issue Apr 27, 2021 · 5 comments

Comments

@helins
Copy link
Contributor

helins commented Apr 27, 2021

I realized that there is currently no support for :list, unlike other collections (:vector, :set). Since this is pretty basic, I was wondering if it was somehow a deliberate choice. If not, a PR looks fairly straightforward to write.

@ikitommi
Copy link
Member

I was dropped at some point of not being very useful - :sequential is a better alternative for most cases as it covers both lists and sequences and because of that, transformations don't have to coerce the mapped results back into a list.

(list? '())
(list? (conj '() 1))
(list? (reverse '()))
(list? (list (seq '())))
; => true

(list? (map identity '()))
(list? (cons 1 '()))
(list? (seq '()))
(list? (concat '() '()))
; => false

Do you find explicit list useful?

here's the commit: 0acde2b

@helins
Copy link
Contributor Author

helins commented Apr 28, 2021

Granted, this has probably never caused much problems because lists are seldom used in the vast majority of projets. They are commonly used in metaprogramming but not much elsewhere. I was more surprised because of the fact that it is a core data structure rather than by unfulfilled obvious use cases.

The only reason I noticed it is, once again, due to generation. :sequential generates a vector, so do all the seqexp schemas but :cat (or when wrapped in :cat) which generates a lazy seq. So a :list or rather a :seq of ints passing both validation and generation must be written like this:

[:and
 [:cat [:* :int]]
 seq?]
 
 ;; Note, does not allow :ref

Or

[:and
 [:sequential
  {:gen/fmap #(or (list* %)
                            '())}
  :int]
 seq?]

Which looks a bit over-engineered for a simple list. Unless I am missing something?

@ikitommi
Copy link
Member

Registering a custom -collection-schema would be the way to do that.

Sadly, the current impl of m/-collection-schema is not the best for this (one would also have to install new methods on various multimethods like malli.generator/-schema-generator etc.

But then again, we can make m/-collcection-schema more versatile: #433.

@helins
Copy link
Contributor Author

helins commented May 13, 2021

So it looks that there is now everything needed for having :list?

What would a good PR be like, anything besides those points? Adding:

  • -collection-schema into core base-schemas
  • :list method in malli.generator/-schema-generator
  • :list method in malli.json-schema/accept that mimicks :vector
  • :list method in malli.clj-kondo/accept that simply returns :list

Note on example in #433: predicate should be seq? instead of list? since seqs and lists and interchangeable in pratice. A bit suprisingly, list* produces a seq, not a list.

I would argue that it is a good idea having :list since it's a core data structure and it will make it easier using Malli for describing code-related things (macros, fns operating over code, ...).

@helins
Copy link
Contributor Author

helins commented May 13, 2021

(and it is also consistent with having support for list?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants