tomtom
February 27, 2020, 4:25am
#1
docs said:

`f.(args...)`

is equivalent to `broadcast(f, args...)`

however, I found that `f.()`

is not calling `broadcast(f, )`

:

```
Base.broadcast(::typeof(exp), x) = println("exp ", x);
x = [1.0, 2.0];
julia> Base.broadcast(exp, x)
exp [1.0, 2.0]
julia> exp.(x)
2-element Array{Float64,1}:
2.718281828459045
7.3890560989306495
```

in above, `exp.()`

is not calling the `broadcast()`

I tried to override. Is there any method to enforce it? thanks.

tomtom
February 27, 2020, 6:49am
#3
I mean, why `f.()`

not compiled into `broadcast(f, )`

?

I donβt know the answer to that, but in case you didnβt know, hereβs how to check what is being called:

```
julia> @code_lowered (()->f.(x))()
CodeInfo(
1 β %1 = Base.broadcasted(Main.f, Main.x)
β %2 = Base.materialize(%1)
βββ return %2
```

tkf
February 27, 2020, 7:35am
#5
Alternatively:

```
julia> Meta.@lower f.(x)
:($(Expr(:thunk, CodeInfo(
@ none within `top-level scope'
1 β %1 = Base.broadcasted(f, x)
β %2 = Base.materialize(%1)
βββ return %2
))))
```

`broadcast(f, x)`

needs to return an array if `x`

is an array. If `f.(g.(x))`

is lowered to `broadcast(f, broadcast(g, x))`

, it would need to create intermediate array. Instead, `julia`

does

```
julia> Meta.@lower f.(g.(x))
:($(Expr(:thunk, CodeInfo(
@ none within `top-level scope'
1 β %1 = Base.broadcasted(g, x)
β %2 = Base.broadcasted(f, %1)
β %3 = Base.materialize(%2)
βββ return %3
))))
```

If you read the manual youβd notice that `broadcasted`

(note `ed`

) does not do the actual computation. Rather, the actual computation is done in `materialize`

without creating any intermediate arrays.

Itβs actually `broadcast(f, )`

that calls (the lowered version of) `f.()`

:

julia> string.(("one","two","three","four"), ": ", 1:4)
4-element Array{String,1}:
"one: 1"
"two: 2"
"three: 3"
"four: 4"
```
"""
broadcast(f::Tf, As...) where {Tf} = materialize(broadcasted(f, As...))
# special cases defined for performance
@inline broadcast(f, x::Number...) = f(x...)
@inline broadcast(f, t::NTuple{N,Any}, ts::Vararg{NTuple{N,Any}}) where {N} = map(f, t, ts...)
"""
broadcast!(f, dest, As...)
Like [`broadcast`](@ref), but store the result of
`broadcast(f, As...)` in the `dest` array.

3 Likes