Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure: separating comp and partial arguments

Tags:

clojure

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)
like image 792
leontalbot Avatar asked Dec 07 '22 09:12

leontalbot


2 Answers

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.

like image 68
Francis Avila Avatar answered Dec 11 '22 09:12

Francis Avila


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.

like image 32
A. Webb Avatar answered Dec 11 '22 08:12

A. Webb