# Base.Fix2 can be constructed using broadcasting syntax but does not retain broadcasting functionality

**URL:** <https://discourse.julialang.org/t/base-fix2-can-be-constructed-using-broadcasting-syntax-but-does-not-retain-broadcasting-functionality/124770>\
**Category:** General Usage\
**Tags:** question\
**Created:** [January 14, 2025, 3:41pm UTC](https://discourse.julialang.org/t/base-fix2-can-be-constructed-using-broadcasting-syntax-but-does-not-retain-broadcasting-functionality/124770 "2025-01-14T15:41:34Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![croberts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/croberts/32/9465_2.png) [@croberts](https://discourse.julialang.org/u/croberts)\
**Post date:** [January 14, 2025, 3:41pm UTC](https://discourse.julialang.org/t/base-fix2-can-be-constructed-using-broadcasting-syntax-but-does-not-retain-broadcasting-functionality/124770/1 "2025-01-14T15:41:34Z")

</div>

Example:

```julia
a = [1,2,3]

(>=(2)).(a) # works as intended 
.>=(2) # can be constructed 
.>=(2).f # fields do not retain information that function should be broadcasted
(.>=(2))(a) # breaks 
(x -> x .>= 2)(a) # intended behavior.  
.>=(a, 2) # also intended behavior. 

```

Is there a reason that Base.Fix2 does not retain information that the function should be broadcasted, or is this an oversight? If there is a reason, then why isn’t an exception thrown when `.>=(2)` it is constructed?

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [January 14, 2025, 5:12pm UTC](https://discourse.julialang.org/t/base-fix2-can-be-constructed-using-broadcasting-syntax-but-does-not-retain-broadcasting-functionality/124770/2 "2025-01-14T17:12:02Z")

</div>

Okay, this is definitely a little bit of a journey. Two things to note at the top.

1. `Int`s in Julia are iterable.

```julia
julia> collect(1)
0-dimensional Array{Int64, 0}:
1

```

1. Broadcasting attempts to materialize a vector with the result of the broadcast eagerly.

When you run `.>=(2)`, it calls the top-level `Base.broadcast` function which in turn calls `materialize(broadcasted(f, As...))`. `broadcasted` returns what you’d expect: `Base.Broadcast.Broadcasted(>=, (1,))`, but `materialize` returns the surprising `Base.Fix2(>=, 2)`.

Digging into materialize, it normally uses `similar` to create a destination `Array` and then copies the result of broadcasting `f` over the arguments. In this case, where the input is a “0-dimensional Array” (an `Int`), it instead returns the result without an `Array` wrapper (because you couldn’t access the contents of a 0-dim Array to get the value).

Edit:  
To get a lazy broadcasting object, you could do:

```julia
julia> x = Base.Fix1(broadcast, >=(2))
(::Base.Fix1{typeof(broadcast), Base.Fix2{typeof(>=), Int64}}) (generic function with 1 method)

julia> x([1,2,3])
3-element BitVector:
 0
 1
 1

```

---

<div class="post-metadata">

**Author:** ![croberts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/croberts/32/9465_2.png) [@croberts](https://discourse.julialang.org/u/croberts)\
**Post date:** [January 14, 2025, 5:34pm UTC](https://discourse.julialang.org/t/base-fix2-can-be-constructed-using-broadcasting-syntax-but-does-not-retain-broadcasting-functionality/124770/3 "2025-01-14T17:34:17Z")

</div>

Great sleuthing and excellent exposition! I understand now why it behaves as it does.

Would it make sense for Julia Base to add something like:

```julia
fix2_functions = [>=, <=, ==] # and other functions for which Base.Fix2 is called when the function is applied to a single argument 

# For exposition purposes, using ::NTuple{Any, 1} even though equivalent to the more parsiminous ::Tuple 
Base.broadcast(f::Union{typeof.(fix2_functions)...}, args::NTuple{Any, 1}...) =  
    Base.Fix1(broadcast, f(args...)) 

```

Current behavior of `.>=(2)` is unintuitive. The only reason someone would ever write `.>=(2)` is if to broadcast the comparison over some as-yet undefined iterable.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [January 14, 2025, 5:40pm UTC](https://discourse.julialang.org/t/base-fix2-can-be-constructed-using-broadcasting-syntax-but-does-not-retain-broadcasting-functionality/124770/4 "2025-01-14T17:40:35Z")

</div>

The question of how to do partial application in Julia is… fraught. Lots of ideas about how to do it, what the rules should be, etc., but not a lot of consensus or momentum.

I think special casing a few functions is not great.

If I were in charge, I’d use underscores for partial application, so the way to do this would be:

```julia
julia> f = _.>=2

julia> f([1,2,3])
[false, true, true]

```

But I’m not in charge, thankfully 🙂

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [January 14, 2025, 5:52pm UTC](https://discourse.julialang.org/t/base-fix2-can-be-constructed-using-broadcasting-syntax-but-does-not-retain-broadcasting-functionality/124770/5 "2025-01-14T17:52:10Z")

</div>

This is exactly the same as `.√(2)` — that will call sqrt on all the element(s) in its argument and return the result(s). Similarly `.>(2)` calls `>` on all the element(s) in its arg and returns the result(s). In both cases there’s exactly one (unwrapped) result — `1.414...` and a `Fix2`, respectively.

It’s just tricky in this case because calling `>` on a single arg returns a function to be later called. It’s true that you wouldn’t usually use construct an array of functions like this, but you totally can — and you can even do something useful with it. Here I’ll apply different thresholds to each column:

```julia-repl
julia> checks = .>([-1 -0.5 0 0.5 1])
1×5 Matrix{Base.Fix2{typeof(>), Float64}}:
 Fix2{typeof(>), Float64}(>, -1.0) … Fix2{typeof(>), Float64}(>, 1.0)

julia> randn(10,5) .|> checks
10×5 BitMatrix:
 1 0 1 1 0
 1 1 0 0 0
 1 1 1 1 0
 1 1 0 1 0
 1 1 1 0 0
 1 1 0 1 0
 1 1 0 0 0
 1 1 0 1 1
 1 0 1 1 0
 1 0 1 0 0

```

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [January 14, 2025, 5:59pm UTC](https://discourse.julialang.org/t/base-fix2-can-be-constructed-using-broadcasting-syntax-but-does-not-retain-broadcasting-functionality/124770/6 "2025-01-14T17:59:07Z")

</div>

Given that numbers are iterable in Julia v1, I agree with @mbauman. There is no way to generically look at a type and know if it should be treated as a vector-like thing or a scalar thing.

In a bigger picture sense, though, I wish that numbers were not iterable so that it could be meaningful to distinguish between `Base.broadcast(typeof(>=), ::Number)` and `Base.broadcast(typeof(>=), ::AbstractArray)`.

---

<div class="post-metadata">

**Author:** ![croberts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/croberts/32/9465_2.png) [@croberts](https://discourse.julialang.org/u/croberts)\
**Post date:** [January 14, 2025, 5:59pm UTC](https://discourse.julialang.org/t/base-fix2-can-be-constructed-using-broadcasting-syntax-but-does-not-retain-broadcasting-functionality/124770/7 "2025-01-14T17:59:18Z")

</div>

Ah, this makes a lot of sense.

Given that my question is actually a special case for the more general question of what syntax Julia should use for partial application (mrufsvold 2nd reply in thread) – the answer to which has not been decided – nothing should be done about my specific question.

Thanks!

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [January 14, 2025, 6:03pm UTC](https://discourse.julialang.org/t/base-fix2-can-be-constructed-using-broadcasting-syntax-but-does-not-retain-broadcasting-functionality/124770/8 "2025-01-14T18:03:46Z")

</div>

There are huge advantages to “pushing” the `.` down to the time that you use it — specifically it will then _fuse_ with other `.`s in the same expression. It also generally tracks with Julia’s best practices — define the “scalar” operation and then use it broadcastedly _at the call site_ when necessary.

In other words, your `(.>=(2))(a) # breaks` example should be written as `(>=(2)).(a)`, or perhaps more readably:

```julia
op = >=(2)
op.(a)

```
