I have a class(created by deftype) and I want to make several static members like deserialize on it. I tried to add theirs signatures in interface but it is'nt worked for me(code below).
(definterface INmk
(serialize [])
(deserialize [string])
(print []))
(deftype NmkLinear [^:volatile-mutable a
^:volatile-mutable b
^:volatile-mutable x-sum
^:volatile-mutable y-sum
^:volatile-mutable xy-sum
^:volatile-mutable xq-sum
^:volatile-mutable n]
INmk
(serialize [this]
(str "{\"a\":" a
" \"b\":" b
" \"x-sum\":" x-sum
" \"y-sum\":" y-sum
" \"xy-sum\":" xy-sum
" \"xq-sum\":" xq-sum
" \"n\":" n
"}"))
(deserialize [str]
(let [j (json/read-str str :key-fn keyword)]
(NmkLinear.
(:a j) (:b j) (:x-sum j) (:y-sum j) (:xy-sum j) (:xq-sum j) (:n j))))
If you genuinely need a static method for some reason, then you need to fall back to gen-class.
http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/gen-class
This lets you annotate methods with the appropriate metadata to specify they should be static.
^{:static true}
As Nathan says, static members don't apply to interfaces.
Interfaces in Java don't allow static methods to be defined on them; the only static members allowed are constants (where any field you create is assumed to be static and final), the Java Language Specification says, "The access modifier static pertains only to member interfaces". If Java can't do this then Clojure's definterface can't either, of course.
Static methods are not polymorphic so defining them on an interface would not be useful anyway. Keep things like deserialize as stand-alone functions instead (or otherwise look for a different way to organize this).
EDIT: Starting with Java 8 you can add static methods to an interface, so most of the above is out-of-date. (Also I'm not clear whether Clojure is on supporting this.) It seems from your example this is not actually what you want, though. If you add it to the interface then the method implementation will be the same for all implementations of the interface.
Related
I'd like to hide the details of my persistence layer behind some sort of interface. In Java I would just create an interface and choose the correct implementation in some sort of bootup function. I'm still struggling on how to do that in Clojure. I don't necessarily need any type-safety here, I trust in my unit tests to find any issues there. The best thing I could come up with was to create a map containing anonymous functions with specific keys, like so:
(def crux-db {
:get-by-id (fn [id] (get-obj...))
:save (fn [id obj] (store-obj...))
})
(def fs-db {
:get-by-id (fn [id] (get-obj...))
:save (fn [id obj] (store-obj...))
})
If I'm not missing something, this would allow me to replace the database implementation by def-ing (def db crux-db) or (def db fs-db), as long as all the functions exist in all implementation maps. Somehow I feel like this is not the clojure way but I can't put my finger on it. Is there another way to do this?
Protocols are a way to do that. They let you define what functions should be there. And
you can later implement them for different things with e.g.
a defrecord.
A protocol is a named set of named methods and their signatures, defined using defprotocol:
(defprotocol AProtocol
"A doc string for AProtocol abstraction"
(bar [a b] "bar docs")
(baz [a] [a b] [a b c] "baz docs"))
No implementations are provided
Docs can be specified for the protocol and the functions
The above yields a set of polymorphic functions and a protocol object
all are namespace-qualified by the namespace enclosing the definition
The resulting functions dispatch on the type of their first argument, and thus must have at least one argument
defprotocol is dynamic, and does not require AOT compilation
defprotocol will automatically generate a corresponding interface, with the same name as the protocol, e.g. given a protocol my.ns/Protocol, an interface my.ns.Protocol. The interface will have methods corresponding to the protocol functions, and the protocol will automatically work with instances of the interface.
Since you mentioned crux in your code, you can have a peek at how they
use it
here
and then using defrecords to implement some of
them
There are several ways to achieve this. One way would be to use protocols. The other way would be to just use higher-order functions, where you would "inject" the specific function and expose it like so:
(defn get-by-id-wrapper [implementation]
(fn [id]
(implementation id)
...))
(defn cruxdb-get-by-id [id]
...)
(def get-by-id (get-by-id-wrapper cruxdb-get-by-id))
Also worth mentioning here are libraries like component or integrant which are used to manage the lifecylce of state.
Clojure style (and good software engineering in general) puts emphasis on lots of small functions, a subset of which are publicly visible to provide an external interface.
In Clojure there seem to be a couple of ways to do this:
(letfn [(private-a ...)
(private-b ...)]
(defn public-a ...)
(defn public-b ...))
(defn- private-a ...)
(defn- private-b ...)
(defn public-a ...)
(defn public-b ...)
The letfn form seems more verbose and perhaps less flexible, but it reduces the scope of the functions.
My guess is that letfn is intended only for use inside other forms, when little helper functions are used in only a small area. Is this the consensus? Should letfn ever be used at a top level (as I've seen recommended before)? When should it be used?
letfn is intended for use in cases of mutual recursion:
(letfn [(is-even? [n]
(if (zero? n)
true
(is-odd? (dec n))))
(is-odd? [n]
(if (zero? n)
false
(is-even? (dec n))))]
(is-even? 42))
;; => true
Don't use it at the top level.
Also don't use the defn macro anywhere else than at the top level unless you have very specific reasons. It will be expanded to the def special form which will create and intern global var.
The purpose of letfn is totally different from the purpose of defn form. Using letfn at the top level does not give you same properties of defn, since any bindings of names to functions bound inside letfn is not visible outside its scope. The binding for functions bound inside let or letfn is not available outside its lexical scope. Also, the visibility of functions bound inside letfn is independent of the order in which they are bound inside that lexical scope. That is not the case with let.
My rules are these:
If a subsidiary function is used in one public one, define it
locally with let or letfn.
If it is used in several, define it at top level with defn-.
And
Don't use let or letfn at top level.
Don't use def or defn or defn- anywhere other than top level.
I'm new to clojure and I'm trying to make sense of the different design choices available in different situation. In this particular case I would like to group tightly coupled functionality and make it possible to pass the functions around as a collection.
When to use function maps to group tightly related functionality and when to use protocols (+ implementations)?
What are the advantages and drawbacks?
Is either more idiomatic?
For reference, here are two examples of what I mean. With fn maps:
(defn do-this [x] ...)
(defn do-that [] ...)
(def some-do-context { :do-this (fn [x] (do-this x)
:do-that (fn [] (do-that) }
and in the second case,
(defprotocol SomeDoContext
(do-this[this x] "does this")
(do-that[this] "does that")
(deftype ParticularDoContext []
SomeDoContext
(do-this[this x] (do-this x))
(do-that[this] (do-that))
It all depends on what you meant by "tightly related functionality". There can be 2 interpretations:
These set of functions implement a particular component/sub-system of the system. Example: Logging, Authentication etc. In this case you will probably use a clojure namespace (AKA module) to group the related functions rather than using a hash map.
These set of functions work together on some data structure or type or object etc. In this case you will use Protocol based approach, which allows ad-hoc polymorphism such that new types can also provide this set of functionality. Example: Any interface kind of thing: Sortable, Printable etc.
Protocols are like Interfaces so if what you're trying to create is one, use a protocol.
If you're just trying to group related functions somewhere use a namespace, it's ok to have your functions floating there attached to no particular Object.
It seems to me you're thinking about Objects and using the map just to simulate an Object or a struct you're attaching your functions together. Feels unnatural to me unless it's indeed a type or protocol, and you should use defrecord, deftype and defprotocol in those cases.
An example taken from here about using defprotocol and defrecord:
(defprotocol IAnimal
"the animal protocol"
(inner-report [o] "a report"))
(defrecord Dog []
IAnimal
(inner-report [o]
(println "Woof Woof.\n")))
(defrecord Cat []
IAnimal
(inner-report [o]
(println "Meow Meow.\n")))
My first impression would be that the first way is data oriented and the second way is type oriented. So far, I prefer data oriented.
Perhaps the decision is related with Alan Perlis quote: "It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures."
EDIT:
After posting the previous version of my question I discovered that the real problem is with nested functions.
If I have a closure within a deftype I can not update any mutable fields from within that closure.
E.g. the following works:
(deftype Test [^:unsynchronized-mutable x]
TestInterface
(perform [this o] (set! x o)))
but this does not:
(deftype Test [^:unsynchronized-mutable x]
TestInterface
(perform [this o] (fn [] (set! x o)) nil)) ; throws a compiler error about assigning to non-mutable field
Is there any way to reach up and access the field? Doing (set! (.x this) o) results in:
ClassCastException user.Test cannot be cast to compile__stub.user.Test user.Test/fn--152 (NO_SOURCE_FILE:3
When trying to run the code.
Code for TestInterface for completeness:
(definterface TestInterface (perform [o]))
Consider that the version which does not work would, if it did work, return a closure which could escape into the wild and get called from wherever, setting your unsynchronized local and messing things up terribly.
If you insist on doing this sort of thing, you can always create an interface with a setter for your mutable field, implement it in your type and call the setter wherever you need to set this field.
Direct mutation ((set! (.-x foo) ...)) won't work, since mutable fields of Clojure types (both unsynchronized and volatile) are private.
defn = public
defn- = private
Perhaps I have bad Clojure coding style -- but I find that most functions I write in Clojure are small helper functions that I do not want to expose.
Is there some configuration option, where:
defn = private by default,
and to make something public, I have to do defn+?
Thanks!
No. There is not.
An alternative approach which might or might not work for you is to declare a foo.bar.internal namespace containing all the private helpers which is used by your foo.bar namespace. This has advantages over private function declarations when you want to use private functions in macro expansions.
If the "helper functions" are very likely to be used once, you could choose to make them locals of your bigger functions, or write them as anonymous functions. See letfn: http://clojuredocs.org/clojure_core/clojure.core/letfn and http://clojuredocs.org/clojure_core/clojure.core/fn.
I hardly ever use letfn myself.
The beauty of Clojure being a Lisp, is that you can build and adapt the language to suit your needs. I highly recommend you read On Lisp, by Paul Graham. He now gives his book away for free.
Regarding your suggestion of defn+ vs defn vs defn-. This sound to me like a good case for writing your own Macro. defn is a function and defn- is a macro. You can simply redefine them as you wish, or wrap them in your own.
Here follows a suggestion to implementation, based mainly on Clojure's own implementation - including a simple utility, and a test.
(defmacro defn+
"same as Clojure's defn, yielding public def"
[name & decls]
(list* `defn (with-meta name (assoc (meta name) :public true)) decls))
(defmacro defn
"same as Clojure's defn-, yielding non-public def"
[name & decls]
(list* `defn (with-meta name (assoc (meta name) :private true)) decls))
(defn mac1
"same as `macroexpand-1`"
[form]
(. clojure.lang.Compiler (macroexpand1 form)))
(let [ ex1 (mac1 '(defn f1 [] (println "Hello me.")))
ex2 (mac1 '(defn+ f2 [] (println "Hello World!"))) ]
(defn f1 [] (println "Hello me."))
(defn+ f2 [] (println "Hello World!"))
(prn ex1) (prn (meta #'f1)) (f1)
(prn ex2) (prn (meta #'f2)) (f2) )
As stated by #kotarak, there is no way (as far as I know) to do that, nor is it desirable.
Here is why I dislike defn- :
I found out that when using various Clojure libraries I sometimes need to slightly modify one function to better suit my particular needs.
It is often something quite small, and that makes sense only in my particular case. Often this is just a char or two.
But when this function reuses internal private functions, it makes it harder to modify. I have to copy-paste all those private functions.
I understand that this is a way for the programmer to say that "this might change without notice".
Regardless, I would like the opposite convention :
always use defn, which makes everything public
use defn+ (that doesn't exist yet) to specify to the programmer which functions are part of the public API that he is supposed to use. defn+ should be no different from defnotherwise.
Also please note that it is possible to access private functions anyway :
;; in namespace user
user> (defn- secret []
"TOP SECRET")
;; from another namespace
(#'user/secret) ;;=> "TOP SECRET"