Fork me on GitHub
#admin-announcements
<
2015-12-19
>
sveri08:12:12

@akiva: @jaen @gfredericks Thanks for the suggestions, as I just have a very simple usecase now I go with data.json and provide a value function.

sveri08:12:07

Hm, does prismatic have a concept of generics? What I want is to declare that, whatever comes into that function, has to be returned too. Is that possible?

jaen08:12:59

Not sure what that means exactly, any example use case?

sveri09:12:52

@jaen: If I pass in a date, then I want to return a date, if I pass in a String, I want to return a string, if I pass in T I want to return T.

jaen09:12:26

By "prismatic" you mean schema, yes? So doesn't (schema.core/validate s/Int 12) already do it?

jaen09:12:31

Or am I misunderstanding something?

sveri09:12:37

@jaen: Yes, I mean prismatic schema. These are two functions, both receive a parameter of whatever type

sveri09:12:42

and may return the same type

sveri09:12:05

This could be an invariant of a function, whatever type comes in, has to be returned

sveri09:12:13

Does that make more sense?

jaen09:12:32

How about

(s/set-fn-validation!)

(s/defn function :- ArgSchema [arg :- ArgSchema] ...)
this will verify your function takes and return the same shape of data (or throw otherwise). Is that something you mean?

sveri09:12:30

No, I dont talk about the shape directly, although, in a prismatic sense it might be the same. I am not sure how else to express this. Maybe you could have a look at: https://docs.oracle.com/javase/tutorial/java/generics/types.html "A Generic Version of the Box Class" if you want. The closest thing I can imagine is:

sveri09:12:26

But this would also accepting that param is a Str, but returns an Inst

sveri09:12:31

Which is not what I want

jaen09:12:02

Ahh, so you mean like A -> A.

jaen09:12:28

For some reason I didn't catch on you wanted parametrically polymorphic function with same parameter and return type, sorry. Was to caught in the schema part of the question.

jaen09:12:31

I'm not sure if schema supports any way of relating the parameter schemas to the return schema. Sounds like a core.typed thing.

jaen10:12:00

I imagine you could cheat with a conditional schema, like so:

(defmulti make-return-schema-for-fun (fn [& args] (mapv class args)))
(defmethod make-return-schema-for-fun [String] [_] s/Str)
(defmethod make-return-schema-for-fun [Integer] [_] s/Int)
(defmethod make-return-schema-for-fun [Long] [_] s/Int)

(defn fun [arg1]
  (let [return-value (* 2 (Integer. arg1))] ; calculate function return here
    (s/validate (make-return-schema-for-fun arg1) return-value)
    return-value))
but that doesn't look too nice to me TBH...

jaen10:12:21

This code above will work with (fun 2) but fail for (fun "2") with a schema error, because input type doesn't match output type.

jaen10:12:30

But again, that feels... weird, to say the least.

sveri10:12:38

Interesting solution, but its more handcrafted and I agree, the logic itself is hidden inside 10 lines boilerplate code

sveri10:12:21

Well, it's nice to finally see the limits of prismatic schema

jaen10:12:53

Well, I guess it might have looked a bit nicer using actual conditional schema or that newfangled abstract schema map, but would still feel like a hack to me nonetheless.

jaen10:12:58

(def FunSchema
  (s/conditional
    (comp string? :arg1)
      {:arg1 s/Str :return s/Str}

    (comp integer? :arg1)
      {:arg1 s/Int :return s/Int}))

(defn fun [arg1]
  (let [return-value (* 2 (Integer. arg1))] ; calculate function return here
    (s/validate FunSchema {:arg1 arg1 :return return-value})
    return-value))

jaen10:12:09

You could macro it up to avoid writing out the boilerplate each time

jaen10:12:16

But I would still feel somewhat iffy using this.

sveri10:12:22

@jaen: Thanks, I'll take a not of it if I need it once really hard I might use it. But for my current usecase this is to much overload