Disclaimer again: I'm a Clojure newbie. Thanks for the help.
My previous question ( Clojure's defrecord - how to use it?) resulted in a working data structure and methods: https://gist.github.com/3353281
Question: Is there a way to avoid passing in my data structure to all of the methods that operate on it? Or is this the way you're supposed to do it in idiomatic Clojure?
Data should always be passed explicitly.
If you're using nested assocs, you should probably be using assoc-in instead.
Related
I use Emacs+CIDER. I like to be able to do something akin to just evaling (quil/frame-rate 90). But Calling that function is only possible within a sketch function. So I have added a live-calls function in which I put these kinds of code, and I call live-calls at the start of the draw function. Which is a very ugly hack. What's the idiomatic way to achieve this?
I found the answer by searching in closed issues in github:
(quil.applet/with-applet sketch-name
(q/frame-rate 3))
In this code headerTable and rowsTable are Java Objects. Here the same method with the same argument is being called on them:
(.setHorizontalAlignment headerTable Element/ALIGN_LEFT)
(.setHorizontalAlignment rowsTable Element/ALIGN_LEFT)
Is there a better way of doing this? I would think there must be a way to combine the two calls into one somehow. But since this is 'side effecting' code, perhaps not??
I'm thinking of an answer without writing a custom function or macro, something like "just use juxt or comp", but then maybe I'm being a bit too prescriptive...
Edit Type hinting was mentioned by Leonid Beschastny, so just in case it helps, here's the Java method signature:
public void setHorizontalAlignment(int horizontalAlignment)
And the class is PdfPTable, from iText. (This code is being used to create PDF files).
There are many possible refactorings, one would be
(run! #(.setHorizontalAlignment ^PdfPTable % Element/ALIGN_LEFT)
[headerTable rowsTable])
there are plenty protocols vs multimethods comparisions, but why not to use higher order functions?
Let's come with example:
We have some data (record for example). And we have methods serialize and deserialize.
Say that we want to save it into file, into json, and into database.
Should we create protocol called SerializationMethod and records called database, json, file that implement them? It looks kind of hack to create records only to use protocol. Second solution - multimethod - could take string parameter with serialization output and decide how to do this. But I am not sure that is right way to go...
And third way is to write function serialize and then pass there data and serializing function. But now I can not name serializing and deserializing method with same name (json fo example):
(defn serialize [method data]
(method data))
(defn json[data]
(...))
The question is how can I (or how should I) do this. Is there more generic way with higher order function? Or maybe I don't understand something well?
That are my first steps with clojure so please be tolerant.
Converting to JSON is different from writing to a database or a file because the latter are IO operations, the first is a pure transformation of data. With that in mind, I wouldn't recommend to implement them under the same interface.
Now assuming you had various serialization implementations, lets say json and fressian, it would certainly not be a good idea to implement them on every data structure that you want to (de-/)serialize. Your observation that that would be a hack is correct. More concisely, it would be limiting a record to be only (de-/)serializable with one implementation.
Instead, it would be more effective to have different Serializers, each implementing the same interface:
(defrecord JSONSerializer []
SerializationMethod
(serialize [this data] ...)
(deserialize [this data] ...))
(defrecord FressianSerializer []
SerializationMethod
...)
This way we end up having several serializer objects that can be passed to functions that require one. Those functions don't need to be concerned with the implementation.
Could higher order functions be passed instead?
(defn do-something
[params serialize deserialize]
...)
It would work, too. Notice however that this style can quickly grow out of hand. E. g. consider a scenario where a function should be written that deserializes data from one format and serializes it to the other.
Is there a difference, performance or otherwise, between using a deffilterop and using a purse clojure function?
http://nathanmarz.com/blog/introducing-cascalog-a-clojure-based-query-language-for-hado.html mentions that filtering can be done with clojure functions like (< ?age2 ?age1) however looking at https://github.com/nathanmarz/cascalog/wiki/Guide-to-custom-operations it looks like you can define a function like (deffilterop is-2? [x] (= x 2)).
So my question is, is there any difference between these two approaches and if not which is the preferred syntax?
Note: It also looks like all of the defxxxop functions are being deprecated for defxxxfn instead. https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/src/clj/cascalog/logic/def.clj#L131
Turns out there is no difference from a performance perspective. The deffilterop is useful for making a parameterized function.
I wish to use the clojure "get" keyword for my own function. How can I prevent clojure from using the "get" defined in the standard libraries?
As mentioned this is not necessarily a good idea, but you can do it like this:
user=> (ns your.name.space
(:refer-clojure :exclude [get]))
nil
your.name.space=> (defn get [] "something")
#'your.name.space/get
your.name.space=>
I wouldn't recommend using get for anything but getting a value out of a collection, since that's what anyone reading your code would expect it to do.
If you don't want to do that, Wodin's answer is what you want.
If you actually want to "overload" get as per your title, that is, make the standard get function work with your own collection type - just make sure your collection implements ILookup, Map, or IPersistentSet and you can provide your own get/valAt method.