Say I have a function that needs two arguments and where the order of arguments affects the results.
Is it possible to pass the first argument into a partial or comp function and the other aside of it, like this:
(defn bar [arg1 arg2] (- arg1 arg2))
(def baz (partial (bar arg1)))
(def qux (comp str (bar arg1)))
(baz arg2)
(qux arg2)
If I want to pass arg2 into the function, could I do something like this?
(def baz2 (partial (bar _ arg2)))
(def qux2 (comp str (bar _ arg2)))
(baz arg1)
(qux arg1)
partial
only "fills in" arguments on the left side, so if you need to skip arguments you must use fn
:
(def baz2 #(bar %1 arg2))
Note also that comp
requires that all its arguments be functions, so your qux
and qux2
are actually nonsense. They should be:
(def qux (comp str baz))
(def qux2 (comp str baz2))
In general, Clojure core functions will place the variable most likely to change last to make composition with comp
and partial
more natural. (E.g., the collection argument is almost always last in Clojure, except for things like into
where it makes sense to put it first.) When you design your own functions you should stick to this convention so you can compose your functions more easily.
Scheme SRFI 26 has a useful macro cut
for slotting parameters like this.
Usage would be like so for your subtracting bar
:
((cut bar <> 1) 2)
;=> 1
((comp str (cut - <> 1)) 2)
;=> "1"
Where the <>
symbol represents the slot to be filled.
It is a fun exercise to implement a cut
in Clojure yourself, but here is one port by @Baishampayan Ghose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With