Skip to content

Equality of => and fn-schema? #376

Open

Description

@peter

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.

Activity

  1. w01fe commented on Sep 30, 2016

    @w01fe
    Member

    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

  2. w01fe commented on Sep 30, 2016

    @w01fe
    Member

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions