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

Equality of => and fn-schema? #376

Open
peter opened this issue Sep 30, 2016 · 2 comments
Open

Equality of => and fn-schema? #376

peter opened this issue Sep 30, 2016 · 2 comments

Comments

@peter
Copy link

peter commented Sep 30, 2016

This may not be a bug, but I was wondering if => and fn-schema should produce equal records, i.e why aren't they equal in this example:

(require '[schema.core :as s])
(def fn-sig (s/fn-schema (s/fn :- s/Bool [a :- s/Str b :- s/Int])))
(def arrow-sig (s/=> s/Bool s/Str s/Int))
(= fn-sig arrow-sig) ; => false

fn-sig ; => (=> Bool Str Int)
(type fn-sig) ; => schema.core.FnSchema
arrow-sig ; => (=> Bool Str Int)
(type arrow-sig) ; => schema.core.FnSchema

My use case here is that I'm trying to validate the signature of a function parameter and have come up with something like this:

(def ModelWriteFnSchema (s/fn-schema (s/fn :- Doc [app :- App model :- Model doc :- Doc])))
(def ModelWriteFn (s/constrained Function #(= (s/fn-schema %) ModelWriteFnSchema)))

Using => instead of fn-schema seemed more elegant but I couldn't get that to work.

@w01fe
Copy link
Member

w01fe commented Sep 30, 2016

I'm not sure that I would recommend this -- if you really want this validation, another approach would be to wrap the function that's an argument in a schematized function.

That said, we do test equality like this in the tests (just to make sure fns get the right schemas):

https://github.com/plumatic/schema/blob/master/test/cljx/schema/core_test.cljx#L855

The catch is, if you look inside the objects:

user> (pprint (clojure.data/diff (s/=> s/Bool s/Str s/Int) (s/fn-schema (s/fn :- s/Bool [a :- s/Str b :- s/Int]))))
({:input-schemas [[{:name arg0} {:name arg1}]]}
 {:input-schemas [[{:name a} {:name b}]]}
 {:input-schemas
  [[{:optional? false, :schema java.lang.String}
    {:optional? false, :schema Int}]],
  :output-schema java.lang.Boolean})

you can see that the issue is the argument names are part of the fn-schema (and I don't think there's a way to provide them). They are in there to provide nice documentation of the arglists for tooling, IIRC. I guess technically FnSchema could ignore them when computing equality, but then it couldn't be a Record, and all in all I'm not sure it would be a net win.

That said, if you really want this, you could just write your own `equivalent-fn-schemas

@w01fe
Copy link
Member

w01fe commented Sep 30, 2016

oops, submitted by accident.

That said, if you really want this, you could just write your own equivalent-fn-schemas function that ignores the arg names and use that in place of =.

Does that all make sense? HTH

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