CLojure: higher order functions versus protocols versus multimethods

there are many protocols against multipoint comparisons, but why not use higher order functions? Let's give an example: We have some data (for example, a record). And we have methods to serialize and deserialize . Let's say we want to save it to a file, to json and to a database. Should we create a protocol named SerializationMethod and entries named database , json , filewho implement them? It looks like hacking records just to use the protocol. The second solution - multimethod - can take a string parameter with serialization output and decide how to do it. But I'm not sure if this is the right way ... And the third way is to write a serialize function and then pass the data and serialization function there. But now I am unable to name a serialize and deserialize method with the same name (like json fo):

(defn serialize [method data]
  (method data))

(defn json[data]
  (...))

      

The question is how can I (or how can I do it) do this. Is there a more general way with a higher order function? Or maybe I don't understand something well? These are my first steps with clojure, so please be patient.

+3


source to share


1 answer


Converting to JSON is different from writing to a database or file as the latter are I / O operations, the former is pure data conversion. With this in mind, I would not recommend implementing them under the same interface.

Now, assuming you had different serialization implementations, say json and fressian, it would be a good idea to implement them in every data structure you want to (de - /) serialize. Your comment that it was a hack is correct. More succinctly, this would restrict writing to only (de - /) serializable with one implementation.

Instead, it would be more efficient to have different Serializers, each of which implements the same interface:

(defrecord JSONSerializer []
  SerializationMethod
  (serialize [this data] ...)
  (deserialize [this data] ...))

(defrecord FressianSerializer []
  SerializationMethod
  ...)

      



This way, we get several serializer objects that can be passed to functions that require it. These functions do not have to be implementation-related.

Can higher order functions be passed?

(defn do-something 
  [params serialize deserialize]
  ...)

      

This will work too. Note, however, that this style can quickly grow out of control. E. g. consider a scenario in which a function is to be written that deserializes data from one format and serializes it to another.

+2


source







All Articles