Hi all,
I seem to be running into the same kind of situation often, where I feel the need for a certain operation, but can’t seem to find a handy way to perform it in Clojure. Theoretically, it feels as though a cartesian product of functions would do the trick.
This might seem like a very theoretical question, but I often (mostly when using threading macro’s) find myself in the situation where I have something that feels like a tuple of objects (I program in Python often), where I have an operation I want to perform only on one element of the tuple, or to apply operations to each of the elements.
In made up clojure this might be something like:
([inc, dec] [2 2])
->[3 2]
where two functions that act on integers are combined into a function that acts on a pair of integers.
Or more often I find myself wanting to create a [f, identity]. For example, as a toy-project I’m trying to do some accounting in Clojure a la hledger. I had just created a definition
(defn make-transaction [date description & postings]
{:date date
:description descriptions
:postings (map (partial apply make-posting) postings)})
And created some test data:
(def data
[["2021/01/01" "Buy an apple"
["expenses:groceries" 0.45]
["assets:checking" -0.45]]
["2021/01/15" "Buy a lemon"
["expenses:lemons" 0.30]
["assets:checking" -0.30]]
["2021/02/01" "Buy another apple"
["expenses:groceries" 0.45]
["assets:checking" -0.45]]
["2021/02/03" "Buy a red grapefruit"
["expenses:grapefruits" 0.80]
["assets:checking" -0.80]]])
And now I want to make local-date’s of the dates, instead of strings. I think the make-transaction shouldn’t do the parsing, so I want to hand it parsed dates. Being lazy, I’d love it if I could do something like
(map [#(local-date "yyyy/MM/dd" %) identity & identity ] data)
to only apply the function local date to each first entry and keep everything else. This would save me from having to add (local-date "yyyy/mm/dd )
four times.
So summarizing, I think I have three questions:
- How to apply a function only to a single element of a vector and keep the rest (is this what lenses do?)
- More generally, how to construct the cartesian product of functions. Or, how to achieve a similar result or avoid the use of cartesian products by being more clojuristic
- Do you see something about my thinking (e.g. the mention of the Python tuple) that indicates that I haven’t used Clojure enough
Thanks in advance for any thoughts!
Florian