Skip to content
New issue

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

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

Already on GitHub? # 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

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

No branches or pull requests

2 participants