In Clojure, there are several option for composition of functions. There are composition functions for:
Apply: for 'unwrapping' arguments
Partial: for arguments that are not yet given
Comp: for piping consecutive results through multiple functions
Juxt: for applying one argument on multiple functions
However, AFAIK there are no such composition functions that include branching. Are there any functions that compose functions in a branching way, like a functional version of if or cond ?
Of course an if version is easy to make (though this implementation might not be the quickest):
(defn iff
([pred rtrue] (iff pred rtrue identity))
([pred rtrue rfalse]
(fn [& args]
(if (apply pred args)
(apply rtrue args)
(apply rfalse args)))))
There could be discussion about by default returning identity in the 'else' case is the right choice, or if nil should be returned in such case.
The use of such function could produce more easy to read code. Instead of #(if (string? %) (trim %) %) it would become (iff string? trim), or with a cond version:
(condf string? trim,
vector? (partial apply str),
:else identity)
Do other FP languages have such constructs ? I can imagine it might be handy in compositions with comp and juxt. Why doesn't Clojure ?
Bonus points for nice iff / condf implementations :)
I'm not sure if this is a direct match for what you're looking for (the question, to me, is somewhat vague), but you should look into Monads and Arrows.
Monads allow you to chain together functions with a specific "bind" function that defines how to chain them. It could do some sort of if/else pipelining, as in the Maybe and Either monads, or it could simulate state, as in the State monad.
Monads are built into Haskell (as monads) and F# (as "Workflows"). I have seen monad libraries for Clojure (check this out for one), and there are probably Arrow libraries too.
Well there could be many such composition pattern you can come up and ask why this isn't in the core language. The reason is obvious, it is not feasible. The core of the language provide you all the constructs to build such patterns. These sort of features are more of a contrib kind of thing rather than core of the language.
As far as implementation is concerned it would as simple as something shown below:
(defn condf [& args]
(let [chain (partition 2 args)]
(fn [& params]
(first (for [[p f] chain :when (or (= :else p) (apply p params))]
(apply f params))))))
(def my-func (condf string? clojure.string/trim
vector? (partial apply str)
:else identity))
(my-func "Ankur ") ==> "Ankur"
(my-func [1 2 3]) ==> "123"
(my-func '(1 2 3)) ==> (1 2 3)
This approaches the idea of Strategic Programming. You may find the following paper of interest
The Essence of Strategic Programming by
Ralf Lämmel and Eelco Visser and Joost Visser
http://homepages.cwi.nl/~ralf/eosp/
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.20.1969
Related
I find myself writing a lot of clojure in this manner:
(defn my-fun [input]
(let [result1 (some-complicated-procedure input)
result2 (some-other-procedure result1)]
(do-something-with-results result1 result2)))
This let statement seems very... imperative. Which I don't like. In principal, I could be writing the same function like this:
(defn my-fun [input]
(do-something-with-results (some-complicated-procedure input)
(some-other-procedure (some-complicated-procedure input)))))
The problem with this is that it involves recomputation of some-complicated-procedure, which may be arbitrarily expensive. Also you can imagine that some-complicated-procedure is actually a series of nested function calls, and then I either have to write a whole new function, or risk that changes in the first invocation don't get applied to the second:
E.g. this works, but I have to have an extra shallow, top-level function that makes it hard to do a mental stack trace:
(defn some-complicated-procedure [input] (lots (of (nested (operations input)))))
(defn my-fun [input]
(do-something-with-results (some-complicated-procedure input)
(some-other-procedure (some-complicated-procedure input)))))
E.g. this is dangerous because refactoring is hard:
(defn my-fun [input]
(do-something-with-results (lots (of (nested (operations (mistake input))))) ; oops made a change here that wasn't applied to the other nested calls
(some-other-procedure (lots (of (nested (operations input))))))))
Given these tradeoffs, I feel like I don't have any alternatives to writing long, imperative let statements, but when I do, I cant shake the feeling that I'm not writing idiomatic clojure. Is there a way I can address the computation and code cleanliness problems raised above and write idiomatic clojure? Are imperitive-ish let statements idiomatic?
The kind of let statements you describe might remind you of imperative code, but there is nothing imperative about them. Haskell has similar statements for binding names to values within bodies, too.
If your situation really needs a bigger hammer, there are some bigger hammers that you can either use or take for inspiration. The following two libraries offer some kind of binding form (akin to let) with a localized memoization of results, so as to perform only the necessary steps and reuse their results if needed again: Plumatic Plumbing, specifically the Graph part; and Zach Tellman's Manifold, whose let-flow form furthermore orchestrates asynchronous steps to wait for the necessary inputs to become available, and to run in parallel when possible. Even if you decide to maintain your present course, their docs make good reading, and the code of Manifold itself is educational.
I recently had this same question when I looked at this code I wrote
(let [user-symbols (map :symbol states)
duplicates (for [[id freq] (frequencies user-symbols) :when (> freq 1)] id)]
(do-something-with duplicates))
You'll note that map and for are lazy and will not be executed until do-something-with is executed. It's also possible that not all (or even not any) of the states will be mapped or the frequencies calculated. It depends on what do-something-with actually requests of the sequence returned by for. This is very much functional and idiomatic functional programming.
i guess the simplest approach to keep it functional would be to have a pass-through state to accumulate the intermediate results. something like this:
(defn with-state [res-key f state]
(assoc state res-key (f state)))
user> (with-state :res (comp inc :init) {:init 10})
;;=> {:init 10, :res 11}
so you can move on to something like this:
(->> {:init 100}
(with-state :inc'd (comp inc :init))
(with-state :inc-doubled (comp (partial * 2) :inc'd))
(with-state :inc-doubled-squared (comp #(* % %) :inc-doubled))
(with-state :summarized (fn [st] (apply + (vals st)))))
;;=> {:init 100,
;; :inc'd 101,
;; :inc-doubled 202,
;; :inc-doubled-squared 40804,
;; :summarized 41207}
The let form is a perfectly functional construct and can be seen as syntactic sugar for calls to anonymous functions. We can easily write a recursive macro to implement our own version of let:
(defmacro my-let [bindings body]
(if (empty? bindings)
body
`((fn [~(first bindings)]
(my-let ~(rest (rest bindings)) ~body))
~(second bindings))))
Here is an example of calling it:
(my-let [a 3
b (+ a 1)]
(* a b))
;; => 12
And here is a macroexpand-all called on the above expression, that reveal how we implement my-let using anonymous functions:
(clojure.walk/macroexpand-all '(my-let [a 3
b (+ a 1)]
(* a b)))
;; => ((fn* ([a] ((fn* ([b] (* a b))) (+ a 1)))) 3)
Note that the expansion doesn't rely on let and that the bound symbols become parameter names in the anonymous functions.
As others write, let is actually perfectly functional, but at times it can feel imperative. It's better to become fully comfortable with it.
You might, however, want to kick the tires of my little library tl;dr that lets you write code like for example
(compute
(+ a b c)
where
a (f b)
c (+ 100 b))
Is there a reasonable way to have multiple def statements happen with destructing the same way that let does it? For Example:
(let [[rtgs pcts] (->> (sort-by second row)
(apply map vector))]
.....)
What I want is something like:
(defs [rtgs pcts] (->> (sort-by second row)
(apply map vector)))
This comes up a lot in the REPL, notebooks and when debugging. Seriously feels like a missing feature so I'd like guidance on one of:
This exists already and I'm missing it
This is a bad idea because... (variable capture?, un-idiomatic?, Rich said so?)
It's just un-needed and I must be suffering from withdrawals from an evil language. (same as: don't mess up our language with your macros)
A super short experiment give me something like:
(defmacro def2 [[name1 name2] form]
`(let [[ret1# ret2#] ~form]
(do (def ~name1 ret1#)
(def ~name2 ret2#))))
And this works as in:
(def2 [three five] ((juxt dec inc) 4))
three ;; => 3
five ;; => 5
Of course and "industrial strength" version of that macro might be:
checking that number of names matches the number of inputs. (return from form)
recursive call to handle more names (can I do that in a macro like this?)
While I agree with Josh that you probably shouldn't have this running in production, I don't see any harm in having it as a convenience at the repl (in fact I think I'll copy this into my debug-repl kitchen-sink library).
I enjoy writing macros (although they're usually not needed) so I whipped up an implementation. It accepts any binding form, like in let.
(I wrote this specs-first, but if you're on clojure < 1.9.0-alpha17, you can just remove the spec stuff and it'll work the same.)
(ns macro-fun
(:require
[clojure.spec.alpha :as s]
[clojure.core.specs.alpha :as core-specs]))
(s/fdef syms-in-binding
:args (s/cat :b ::core-specs/binding-form)
:ret (s/coll-of simple-symbol? :kind vector?))
(defn syms-in-binding
"Returns a vector of all symbols in a binding form."
[b]
(letfn [(step [acc coll]
(reduce (fn [acc x]
(cond (coll? x) (step acc x)
(symbol? x) (conj acc x)
:else acc))
acc, coll))]
(if (symbol? b) [b] (step [] b))))
(s/fdef defs
:args (s/cat :binding ::core-specs/binding-form, :body any?))
(defmacro defs
"Like def, but can take a binding form instead of a symbol to
destructure the results of the body.
Doesn't support docstrings or other metadata."
[binding body]
`(let [~binding ~body]
~#(for [sym (syms-in-binding binding)]
`(def ~sym ~sym))))
;; Usage
(defs {:keys [foo bar]} {:foo 42 :bar 36})
foo ;=> 42
bar ;=> 36
(defs [a b [c d]] [1 2 [3 4]])
[a b c d] ;=> [1 2 3 4]
(defs baz 42)
baz ;=> 42
About your REPL-driven development comment:
I don't have any experience with Ipython, but I'll give a brief explanation of my REPL workflow and you can maybe comment about any comparisons/contrasts with Ipython.
I never use my repl like a terminal, inputting a command and waiting for a reply. My editor supports (emacs, but any clojure editor should do) putting the cursor at the end of any s-expression and sending that to the repl, "printing" the result after the cursor.
I usually have a comment block in the file where I start working, just typing whatever and evaluating it. Then, when I'm reasonably happy with a result, I pull it out of the "repl-area" and into the "real-code".
(ns stuff.core)
;; Real code is here.
;; I make sure that this part always basically works,
;; ie. doesn't blow up when I evaluate the whole file
(defn foo-fn [x]
,,,)
(comment
;; Random experiments.
;; I usually delete this when I'm done with a coding session,
;; but I copy some forms into tests.
;; Sometimes I leave it for posterity though,
;; if I think it explains something well.
(def some-data [,,,])
;; Trying out foo-fn, maybe copy this into a test when I'm done.
(foo-fn some-data)
;; Half-finished other stuff.
(defn bar-fn [x] ,,,)
(keys 42) ; I wonder what happens if...
)
You can see an example of this in the clojure core source code.
The number of defs that any piece of clojure will have will vary per project, but I'd say that in general, defs are not often the result of some computation, let alone the result of a computation that needs to be destructured. More often defs are the starting point for some later computation that will depend on this value.
Usually functions are better for computing a value; and if the computation is expensive, then you can memoize the function. If you feel you really need this functionality, then by all means, use your macro -- that's one of the sellings points of clojure, namely, extensibility! But in general, if you feel you need this construct, consider the possibility that you're relying too much on global state.
Just to give some real examples, I just referenced my main project at work, which is probably 2K-3K lines of clojure, in about 20 namespaces. We have about 20 defs, most of which are marked private and among them, none are actually computing anything. We have things like:
(def path-prefix "/some-path")
(def zk-conn (atom nil))
(def success? #{200})
(def compile* (clojure.core.memoize/ttl compiler {} ...)))
(def ^:private nashorn-factory (NashornScriptEngineFactory.))
(def ^:private read-json (comp json/read-str ... ))
Defining functions (using comp and memoize), enumerations, state via atom -- but no real computation.
So I'd say, based on your bullet points above, this falls somewhere between 2 and 3: it's definitely not a common use case that's needed (you're the first person I've ever heard who wants this, so it's uncommon to me anyway); and the reason it's uncommon is because of what I said above, i.e., it may be a code smell that indicates reliance on too much global state, and hence, would not be very idiomatic.
One litmus test I have for much of my code is: if I pull this function out of this namespace and paste it into another, does it still work? Removing dependencies on external vars allows for easier testing and more modular code. Sometimes we need it though, so see what your requirements are and proceed accordingly. Best of luck!
I'm inspired by clojure's 1.5 cond-> macro.
Similarily, I want to create a macro of the same idea, applied to the function map. However, I have no idea where to start.
For example, I can't find the source for cond->. (probably because it's not released yet)
Any suggestions?
There is the source of cond-> https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6742
there are a variety of threading macros from the pallet project folks including apply-map-> which looks close to, though not exactly what you are looking for.
(letfn [(apply-map-
[arg f arg-coll]
`(let [arg# ~arg]
(apply ~f arg#
~#(butlast arg-coll)
(apply concat ~(last arg-coll)))))]
(defmacro apply-map->
"Apply in a threaded expression.
e.g.
(-> :a
(apply-map-> hash-map 1 {:b 2}))
=> {:a 1 :b 2}"
[arg f & arg-coll]
(apply-map- arg f arg-coll))
Perhaps there will be enough examples there for you to pick out what you need.
If I understand -- you want to write a macro that takes a list of partial function calls, and for each one, adds map (or apply map) to the beginning, and the previous result to the end?
While this doesn't directly answer how to write that macro, I wanted to point out that you have a couple of alternatives.
Factor out map
This is always true for pure functions:
(=
(map g (map f coll))
(map (comp g f) coll))
The refactored version only walks the collection once, and no intermediate collections need to be made.
Here's what it looks like with threading:
(=
(->> coll
(map f)
(map g))
(map #(->> % f g) coll))
Here's a concrete example in JS.
Transducers
Transducers are another pattern for doing this kind of thing in Clojure that work on more than just map. They're sort of an abstraction over reducer functions. Clojure's map / filter / reduce (etc.) will create a transducer if called without a collection. You can chain them with comp and use them in various contexts (lazy, eager, observable, whatever). Rich Hickey's talk on them is a good intro.
I wonder if there is an idiom in Clojure for combining several one argument functions into a new function accepting a vector. The new function should apply the first function to the first argument and so on.
I think this is useful in a number of situations. For example, you might want to transform x, y and z coordinates of a point using simpler unidimensional functions.
I would implement by myself as follows but I'm afraid it should already exists something similar in the standard API.
(defn vector-comp [& fns]
(fn [avect]
(vec (map #(%1 %2) fns avect))))
https://github.com/flatland/useful/blob/develop/src/useful/fn.clj#L90
Other way to write this:
(defn vector-comp [& fns]
#(map apply fns % (repeat nil)))
I am 99% sure there is no ready-made solution in the standard libraries (juxtcomes the closest that I know of)
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Which lesser-known but useful features of Clojure do you find yourselves using? Feel free to share little tricks and idioms, but try to restrict yourselves to Core and Contrib.
I found some really interesting information in answers to these similar questions:
Hidden features of Haskell
Hidden features of Python
Hidden features of Java
Hidden features of C
Hidden features of Perl
Hidden features of Ruby
There are many more "Hidden feature" questions for other languages, so I thought it would be nice to have one for Clojure, too.
Clojure has an immutable, persistent queue datatype, PersistentQueue, but it doesn't (yet?) have literal reader syntax or Clojure wrapper functions, so you have to create one via a Java call. Queues conj (push) onto the rear and pop from the front with good performance.
user> (-> (clojure.lang.PersistentQueue/EMPTY)
(conj 1 2 3)
pop)
(2 3)
Lists conj onto the front and pop from the front. Vectors conj onto the rear and pop from the rear. So queues are sometimes exactly what you need.
user> (-> ()
(conj 1 2 3)
pop)
(2 1)
user> (-> []
(conj 1 2 3)
pop)
[1 2]
(defn foo [a & [b c]] ...)
You can destructure the rest argument.
Update:
The latest commit to the git repo (29389970bcd41998359681d9a4a20ee391a1e07c) has made it possible to perform associative destructuring like so:
(defn foo [a & {b :b c :c}] ...)
The obvious use of this is for keyword arguments. Note that this approach prevents mixing keyword arguments with rest arguments (not that that's something one's likely to need very often).
(defn foo [a & {:keys [b c] :or {b "val1" c "val2"}] ...)
If you want default values for keyword arguments.
The read-eval reader macro: #=
(read-string "#=(println \"hello\")")
This macro can present a security risk if read is used on user input (which is perhaps a bad idea on its own). You can turn this macro off by setting *read-eval* to false.
You can apply functions to infinite argument sequences. For example
(apply concat (repeat '(1 2 3)))
produces a lazy sequence of 1,2,3,1,2,3... Of course for this to work the function also has to be lazy with respect to its argument list.
From the increasingly good ClojureDocs site an idiom using juxt
http://clojuredocs.org/clojure_core/clojure.core/juxt
;juxt is useful for forking result data to multiple termination functions
(->> "some text to print and save to a file"
((juxt
println
(partial spit "useful information.txt"))))