Learning Haskell some time ago, I felt in love with pointfree notation and especially convenient partial function application - just supply args you know. In Clojure, I have partial
all the time. I think having a special syntax for partial in reader will be nice to have.
Look at the sample code:
; Notation with points:
(map (+ 10 (* % 2)) [1 2 3])
; With partial:
(map (comp (partial + 10) (partial * 2)) [1 2 3])
; Let #[] syntax means partial application in reader:
(map (comp #[+ 10] #[* 2]) [1 2 3])
This is so nice! Is there something like this? Is there possibility to define custom reader macro?
An anonymous function syntax #(...) can be used similarly to what you are trying to do:
user=> (map (comp (partial + 10) (partial * 2)) [1 2 3])
(12 14 16)
is equivalent to:
user=> (map (comp #(+ 10 %) #(* 2 %)) [1 2 3])
(12 14 16)
A tiny little difference is %
which just means a function argument, in this case the first and only.
I really like your idea for a partial function notation using the #[ ] literal.
Unfortunately, Clojure does not let us enhance the #() notation directly, but we can define ourselves a macro like #p
for a partial application.
Given you have a function
(defn partial-wrap
[args]
(concat '(partial) args))
defined in myapp.core
.
You can add the following entry into the data_readers.clj
at the top of your classpath:
{p myapp.core/partial-wrap}
(usually one should use a namespace qualified symbol here like a/p
, since unqualified symbols are reserved for Clojure. Nevertheless unqualified symbols do work, you need to rely on Clojure not overwriting them in a future version).
This finally allows to do almost what you asked for:
(map (comp #p[+ 10] #p[* 2]) [1 2 3])
=> (12 14 16)
I found an approach to have partial in cases like in my question: (map #(+ 10 (* 2 %)) [1 2 3)
. Use ->>
macro: (map #(->> % (* 2) (+ 10)) [1 2 3]
. Similar macros are ->
, ..
and doto
applicable in different situations.
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