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 write code in vim, place the following code in your equivalent of ~/.vim/after/syntax/clojure.vim, and turn conceal on by setting conceallevel to 2:
syntax keyword clojureFunc partial conceal cchar=$
This shortens partial on screen for the reader and writer but doesn’t make a mess of things for others.
I use this trick for making shorthand notations in most languages (e.g., the anonymous function keyword—fn, lambda, whatever—is concealed to the greek letter lambda in many languages).
Related
In Clojure, how do you print the contents of a vector? (I imagine to the console, and usually for debugging purposes). If the answer can be generalized to any Seq that would be good.
Edit:
I should add that it should be a simple function that gives output that looks reasonable, so prints an item per line - so can be easily used for debugging purposes. I'm sure there are libraries that can do it, but using a library really does seem like overkill.
I usually use println. There are several other printing functions that you might want to try. See the "IO" section of the Clojure cheatsheet.
This isn't Java. Just print it, and it will look OK.
You can also use clojure.pprint/pprint to pretty-print it. This can be helpful with large, complex data structures.
These methods work for all of the basic Clojure data structures.
Exception: Don't print infinitely long lazy structures such as what (range) returns--for obvious reasons. For that you may need to code something special.
This works for me:
(defn pr-seq
([seq msg]
(letfn [(lineify-seq [items]
(apply str (interpose "\n" items)))]
(println (str "\n--------start--------\n"
msg "\nCOUNT: " (count seq) "\n"
(lineify-seq seq) "\n---------end---------"))))
([seq]
(pr-seq seq nil)))
Example usages:
(pr-seq [1 2 3])
(pr-seq (take 20 blobs) (str "First 20 of " (count blobs) " Blobs")))
If you want to just print out the elements of the sequence/vector you could just map println to your sequence/vector, but make sure you force map to evaluate using dorun:
(dorun (map println [1 2 3 4]))
This can be applied to sequences too:
(dorun (map println '(1 2 3 4)))
Another way you can do this with apply is to curry map with println and apply it to the sequence/vector:
(apply (partial map println) [[1 2 3 4]])
(apply (partial map println) ['(1 2 3 4)])
Another way you can do this is with doseq:
(doseq [e [1 2 3 4]]
(println e))
(doseq [e '(1 2 3 4)]
(println e))
This one at least stops the text going out too far to the right:
(defn pp
([n x]
(binding [pp/*print-right-margin* n]
(-> x clojure.pprint/pprint)))
([x]
(pp 100 x)))
It is possible to do partials of this function to alter the width.
Please help me get off the ground with Clojure. I've searched and read, but all I see is how to add the number 1 using the function inc.
I'm trying to understand the very basics of map. All I want to do is to add the value 5 to each element in a collection. I've tried a number of different approaches, but nothing comes close. Here is one pathetic incomplete attempt:
(map (+ 5 ???) [0 1 2])
This must be childishly simple, but not for a non-functional programmer like me.
Thanks.
The first argument to map is the function you want to apply to each element in the input sequence. You could create a function and supply it:
(defn plus5 [x] (+ 5 x))
(map plus5 [0 1 2])
if you don't want to declare a named function you could create an anonymous one inline e.g.
(map (fn [x] (+ 5 x)) [0 1 2])
and you can shorten the function definition to:
(map #(+ 5 %) [0 1 2])
(+ 5 ???) is an expression, not a function.
(defn foo [x] (+ 5 x)) is a named function.
(fn [x] (+ 5 x)) is an anonymous function.
#(+ 5 %) is a faster way of writing an anonymous function.
These lines do what you want:
(map foo [0 1 2])
(map (fn [x] (+ 5 x)) [0 1 2])
(map #(+ 5 %) [0 1 2])
I find this site helpful sometimes, when looking at a language I've never seen before. If you search for "function," you'll find a whole section on how to define them. There are also six examples in the official Clojure docs for map. This is for Scala, but here's another answer on SO that explains map and reduce (left fold) pretty well.
Use partial application (see partial) to create a function that adds 5 to its argument:
(partial + 5)
You can try it yourself:
user> ((partial + 5) 10)
;; => 15
Now map it over your list:
user> (map (partial + 5) [0 1 2])
;; => [5 6 7]
In clojure, I would like to push a thrush value through a list of functions, but I'm not sure how to do so in an idiomatic way. The idea is that I will have a list containing an unknown number of functions, and I'd like to take advantage of the variadic nature of thrush.
So, something like this...
(->> 1 inc inc inc)
; 4
(->> 1 '(inc inc inc))
; does not work, of course
reduce does this nicely in this context
user> (reduce #(%2 %1) 1 [inc inc inc])
4
user> (defn thrush [val funs] (reduce #(%2 %1) val funs))
#'user/thrush
user> (thrush 1 [inc inc inc dec])
3
When possible sitck to functions over macros for such things
I think comp is the most idiomatic option here, though it will have prefix syntax instead. This is also more in keeping with normal Clojure (fn args) notation.
=> ((comp inc inc inc) 1)
4
Combine it with the idiomatic apply if a function normally takes variadic arguments, but you want to feed it a collection.
=> ((apply comp (repeat 3 inc)) 1)
4
Be aware though it threads from right to left
=> ((comp str inc inc inc) 1)
"4"
=> ((comp inc inc inc str ) 1)
ClassCastException java.lang.String cannot be cast to java.lang.Number
This also complies more with Clojure/Lisp s-expressions.
If you want more 'easy' human readable notation, Arthur Ulfeldt's answer is perfecly acceptable, and a nice example of reduce and functional programming. Using it 'as is' might get in the way of getting acquainted with the 'simplicity' of s-expressions though..
Be careful with macro's !
The reason why -> and ->> are macro's is that they actively rewrite forms, so you can use normally incomplete argument notation like (filter odd?) in their scope without having to resort to overuse of partial. This can't be done with normal function compostition.
Best learn to make the most of normal function composition before turning to macro's. There's a lot of pitfalls in them for the unaccustomed, and should be used sparingly.
How about:
user=> (def my-fns [inc inc inc])
#'user/my-fns
user=> (->> 1 ((apply comp my-fns)))
4
I suppose you could do this:
(defmacro thrush-list [x flist] `(->> ~x ~#flist))
(thrush-list 1 [inc inc inc])
; 4
I am working my way through labrepl and I saw some code that follows this pattern:
;; Pattern
(apply #(apply f %&) coll)
;; Concrete example
user=> (apply #(apply + %&) [1 2 3 4])
10
This seems to be equivalent to this pattern:
;; Pattern
(apply f coll)
;; Concrete example
user=> (apply + [1 2 3 4])
10
Are these patterns equivalent? If not, what's the difference and when would you use one over the other?
I took the former pattern from the step function in the cellular-automata lab of labrepl:
(defn step
"Advance the automation by one step, updating all cells."
[board]
(doall
(map (fn [window]
(apply #(apply map brians-brain-rules %&)
(doall (map torus-window window))))
(torus-window board))))
Update: I added a concrete example of each pattern to help make the question clearer.
No, there is no difference. There is no reason to write the longer form; I can only assume it was arrived at by gradual changes to code that made sense at one time.
Essentially, both forms accomplish the same thing and are more or less the same. Each provides a way to introduce an anonymous function.
Using #(... is a Clojure reader shorthand for an anonymous function. It is kind of equivalent to (fn [arg1 & args]... , but you cannot embed one #(... anonymous function inside another, and arguments are expressed as % %2... or %1 %2... rather than with vector binding (fn [arg & args].
Both are methods to express an anonymous function. #(... is used for simpler functions, and (fn... is used for more detailed functions.
#(... tends to make things look a little neater.
For example
(map #(+ 10 %1) [ 1 3 5 7 ])
Will add 10 to everything
Suppose I want to map everything to the constant 1. I have tried
(map #(1) [ 1 3 5 7 ])
But I don't understand the compiler error.
(map #(1) [ 1 3 5 7 ])
Won't work for two reasons:
#(1) is a zero-argument anonymous function, so it won't work with map (which requires a one-argument function when used with one input sequence).
Even if it had the right arity, it wouldn't work because it is trying to call the constant 1 as a function like (1) - try (#(1)) for example if you want to see this error.
Here are some alternatives that will work:
; use an anonymous function with one (ignored) argument
(map (fn [_] 1) [1 3 5 7])
; a hack with do that ignores the % argument
(map #(do % 1) [1 3 5 7])
; use a for list comprehension instead
(for [x [1 3 5 7]] 1)
; use constantly from clojure.core
(map (constantly 1) [1 3 5 7])
Of the above, I think the versions using constantly or for should be preferred - these are clearer and more idiomatic.
The anonymous function #(+ 10 %1) is equivalent to:
(fn [%1]
(+ 10 %1))
Whereas #(1) is equivalent to:
(fn []
(1))
And trying to call 1 as a function with no args just won't work.
I got this from clojure.org
by googling the words "clojure constant function" as I am just beginning to look at clojure
(map (constantly 9) [1 2 3])
cheers