I have one function that does some (possibly lengthy) work (defn workwork [x] ...) and some other functions to check if the call will succeed ahead of time (defn workwork-precondition-1 [x] ...).
The precondition functions should be evaluated every time workwork is called (e.g. using :pre). The precondition functions should also be collected (and:ed) in a single function and made available to client code directly (e.g. to disable a button).
Which is the idiomatic way to solve this in Clojure while avoiding code duplication?
In particular, is there any way to evaluate the pre-conditions of a function without running the function body?
You can just collect your preconditions into a function:
(defn foo-pre [x]
(even? x))
Then call the function in a :pre-style precondition:
(defn foo [x]
{:pre [(foo-pre x)]}
…)
For functions introduced using defn, you can extract the :pre-style preconditions from the metadata on the Var:
(-> #'foo meta :arglists first meta)
;= {:pre [(foo-pre x)]}
And similarly for the :arglists entries for any other arities.
There are two caveats here:
The automatically-generated :arglists entry in the Var's metadata maybe be overridden. Overriding :arglists results in the above kind of useful automatically-generated metadata to be thrown out.
The {:pre [(foo-pre x)]} value returned by the above (-> #'foo meta …) expression contains foo-pre as a literal symbol – it'd be your responsibility to figure out which function it referred to at foo's point of definition. (This may or may not be possible – for example foo could be defn'd inside a top-level let or letfn form, with foo-pre a local function.)
And finally, anonymous functions may use :pre and :post, but there is currently no mechanism for extracting them from the function itself.
to evaluate the function precondition without running the function body,you can use robert-hooke library https://github.com/technomancy/robert-hooke/
(use 'robert.hooke)
(defn workwork [x] ...)
(defn workwork-precondition-1
[f x]
(if (precondition-1-satisfied? x)
(f x)
:precondition-1-not-satisfied))
(add-hook #'workwork #'workwork-precondition-1)
Related
Are functions dispatched by defmulti executing in the context/scope of the dispatcher?
I want to set a dynamic var *foo* for dispatched defmethod call.
I have a feeling that I will need to wrap the call to the dispatcher but wanted to confirm with the Clojure magicians.
RESOLVED
As per underlying suspicions confirmed by #schaueho, the following does what I need
;; Multimethod dispatch
(defmulti consume :type)
;; wrapper for dispatch
(defn consume-it [{:keys [token-fn]:as expression}]
"Wraps consume to imbue term name resolutions"
(if token-fn
(binding [*lookup-fn* token-fn]
(consume expression))
(consume expression)))
If I understand you correctly, you would like to use binding within the dispatch function. The purpose of the dispatch function is to return a value that will be used to identify the method to invoke, not to actually call the identified method.
(def ^:dynamic *dynvar* nil)
(defmulti mymulti
(fn [two args]
(binding [*dynvar* (new-value two args)]
(compute-dispatch-value two args)))
In this example, compute-dispatch-value would be see the new binding of *dynvar*, but any invoked method afterwards wouldn't.
I have a method on an object.
myObject.myMethod(1)
I can invoke this in Clojure
(.myMethod myObject 1)
I can also invoke it using information from the lexical environment
(let [x 1] (.myMethod myObject x))
Can I do this with a partial? E.g.
(let [myPartial (partial .myMethod myObject)]
(myPartial 1))
This gives me a
java.lang.RuntimeException: Unable to resolve symbol: .myMethod in this context
I'm currently making this work with an anonymous function
(let [myThing #(.myMethod myObject %)]
(myThing 1))
But if it would be nice to use a partial in this case. Is it possible?
I'm sure the answer will be to do with binding and dispatch but I don't yet have a feeling for where during the compiling and execution the dispatch happens.
You can have partial in your case, use (memfn).
(memfn myMethod args)
In the REPL:
user=> (doc memfn)
-------------------------
clojure.core/memfn
([name & args])
Macro
Expands into code that creates a fn that expects to be passed an
object and any args and calls the named instance method on the
object passing the args. Use when you want to treat a Java method as
a first-class fn. name may be type-hinted with the method receiver's
type in order to avoid reflective calls.
I know that in Java, if I pass an object to a method as an argument, then the method will let the argument variable point to the same object rather than making a duplicate. How about in Clojure? For example:
(defn print-from-reader [rdr]
(print (.read rdr)))
(...inside some code...
(with-open [rdr (Reader file)]
(print-from-rader rdr)))
Does print-from-reader make another copy of rdr in memory when rdr is passed in, or it's pointing to the same rdr that's already created by with-open binding?
And is there any way to check if two clojure instances are pointing to same memory?
Sorry about my bad terms such as "pointing to" and "instances", I am a newbie in Clojure and still learning it. :-)
According to answer to this question on google groups it's pass by value.
Clojure inherits the argument-passing semantics from Java. So it is pass-by-value, where the value passed is an object reference. In addition there are optimization facilities that enable the passing of primitive-typed values.
So functions don't make copies when parameters are passed. rdr in your code will be the same instance.
Makes sense to implement it like that due to java interoperability - otherwise you couldn't (easily) modify java objects' state with its method.
You can test it easily:
(import 'java.util.HashMap)
(def m (new HashMap))
(defn foo [m] (defn bar [m] (.put m "testkey" "testvalue")) (bar m) (println (get m "testkey")))
(foo m)
Results in :
testvalue
nil
If bar created its own copy of m, then the println wouldn't print the value assigned inside bar.
Clojure is pass-by-value just like Java. I think of it as, the references are passed by value.
It isn't a stretch for Clojure to work like this, Scheme and Common Lisp behave the same way.
You can test whether two references point to the same memory with identical?:
(identical? x y)
Tests if 2 arguments are the same object
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.
For the sake of example, suppose I've wrapped a StringBuilder in a function so I can use it more easily in Clojure. I can easily make the no-arg version of the function call toString on the buffer e.g.
(defn builder
([^StringBuilder sb]
(fn
([] (.toString sb))
([& args]
(doseq [arg args]
(.append sb arg)))))
([] (builder (StringBuilder.))))
This is perfectly workable, however, I wonder how I could just override .toString() on the function itself so I could return the state of the StringBuilder or any other object that I have closed over.
You could try using https://github.com/technomancy/serializable-fn, which makes functions include their closed-over scope when they print. It will print the pr-str of the stringbuilder, though, which may or may not be exactly what you want.