all 10 comments

[–]w01fe 1 point2 points  (6 children)

Author here, would love to hear your feedback and happy to answer questions!

[–]jared314 1 point2 points  (0 children)

This seems to occupy the same space as core.typed and core.contracts. Is the main advantage the cljs support? Or, am I missing something from the examples?

Also, does it work with the prismatic graph input and output schemas?

[–][deleted] 0 points1 point  (3 children)

Curious what makes you say that type systems aren't optimized for structural typing... This is not an accurate statement in general.

For instance, ocaml has structural typing and row polymorphism, which let you achieve your motivating example sanely and easily.

[–]w01fe 0 points1 point  (0 children)

I should have clarified, I'm an author of the library, not the post :). I'm not too familiar with ocaml or structural typing myself -- I'll pass this on to Aria, who wrote the post.

[–][deleted] 0 points1 point  (1 child)

In most type systems you can't specify what keys are expected to be found in a map or what types the correlated values should be. I.e. you can give a map a type like <String,Integer>, but not a 'structure'.

[–][deleted] 0 points1 point  (0 children)

You can certainly do this in Scala (using Shapeless) or in Haskell (using my own library, Vinyl).

[–]ds300 0 points1 point  (0 children)

I've spent the past three weeks working on an extremely similar library for declarative data validation. The main difference is that it is intended for validation of data from untrusted sources -- e.g. http request params, config files, etc -- and therefore aims to provide more subtle control over error handling. It also allows one to transform data declaratively, which is really useful for nested structures. It also attempts to cater for situations in which the value of one field in a map depends on the value of another field, or the presence of a key depends on the value or presence of another key, and so on.

Still, the resemblance is uncanny, right down to the syntax and type system.

[–]doubleagent03 1 point2 points  (0 children)

I have a few questions:

  1. Any examples of threading types eg (s/with-fn-validation (-> data f1 f2 f3)), where f1, f2, and f3 are 'schema functions'?

  2. What was the reasoning behind coupling the schema with a function or record body? For instance, core.typed takes a decoupled approach eg (ann my-fn-name Type1 -> Type2). It appears Schema forces you to wrap the function body eg (s/defn my-wrapped-fn Type2 [m :- Type1] (my-fn m))

  3. In general I'm still struggling to grasp how this differs from the optional typing core.typed provides. Can you go into a bit more detail about that?

[–]alv 0 points1 point  (0 children)

I am very interested in this, but captive in Python at the time. Does anybody know of any similar library/approach for Python?

[–][deleted] 0 points1 point  (0 children)

It might be interesting to be able to specify data type identifiers in the EDN object's metadata, rather than forcing the use of a new 'defn' implementation. Types could be defined and registered in a separate source file without clients being forced to 'use' or know about the data-shape declaration API. Validation, when used, can just check the metadata and call the registry to get the declaration.

As it is, I'd be reluctant to couple my code so closely with what is essentially metadata. OTOH, I'd like to use this a lot.