square root array using composition function


#1

I want to make this function:

sum(sqrt.(rand(20)))

using function composition, I tried this forms, but none works.

(sum ∘ sqrt.)(rand(10))
(sum ∘ sqrt)(rand(10))
(sum .∘ sqrt)(rand(10))
(sum ∘ sqrt)(.rand(10))

How do I do this function composition works?


#2

Close, it’s the one permutation you didn’t try:

julia> (sum ∘ sqrt).(rand(10))
10-element Array{Float64,1}:
 0.8980420507456252
 0.2847174420155775
 0.6851298609821408
 0.6751897599452852
 0.976812014821054
 0.10750987261017839
 0.47214123436582084
 0.9207085026619227
 0.544544821255565
 0.31831962863085816

You’re just composing functions not doing element-wise composition of vectors of functions, so you just use . The . is part of the call syntax, not the name of the function. You can think of .( ) as the “vectorized call operator” just like ( ) after an expression is the normal call operator.


#3

That isn’t equivalent to sum(sqrt.(rand(20))) because it is broadcasting sum as well. I don’t think that there is a way to achieve this using function composition.


#4
sum ∘ (x -> sqrt.(x))

?


#5

I mean there’s this:

julia> (sum ∘ (v -> sqrt.(v)))(rand(20))
13.539906421661865

But I’m not sure why you’d want to write that instead of sum(sqrt.(rand(20))).


#6

if the rand is to be part of it, then the simplest is

sum(x -> sqrt(rand()), 1:20)

if the rand(20) is a placeholder for another array X, then

sum(sqrt, X)

#8

OP probably expected that something like sqrt. or (sqrt.) could be syntactic sugar to x -> sqrt.(x)

Is there any reason why it is not?


#9

I believe that this transformation would break broadcast fusion. For example:

a(x) = 2x
b(x) = x/2
x = rand(10000);

@btime a.(b.(x));            #  9.7 μs
@btime a.((x -> b.(x))(x));  # 23.6 μs

(using timing results as a proxy for broadcast fusion…)