Julia broadcasting notation: period before or after?

Why broadcasting for operators like +,*,^ have a period before and for function like sin have a period after? Silly examples are

[1,2,3] +. 4
+.([1,2,3],4)
[1,2,3]==.[4,5,6]

In-fix function have the dot before, normal ones after. If you want to apply an infix “normally” you have to use parenthesis:

julia> (+).([1,2,3],4)
3-element Vector{Int64}:
 5
 6
 7
1 Like

I am not sure if this is the only reason, but there is an ambiguity problem that arises from the fact Julia allows floating point literals to start at the dot.

1.0+.5 # ambiguous parsing if the dot was after the operator

Not sure if there is some reason for not putting the dot always at the start (as function names cannot begin with numbers).

1 Like

The answer here is history and a gradient descent to a local optimum. You can kinda-sorta ret-con it into making sense by thinking of the ( as a function application operator.

2 Likes

But you get the same ambiguity with the dot in front of the plus because you don’t need to write the zero in 1.0

1.+0.5
3 Likes

I would have opted for the maximum ambiguity example myself…

1.+.5
7 Likes

Also, functions names will be preceded by a dot if the module is not implicit, eg. Bar.foo()

What does this syntax (…) do? I think it depends on the context:

(1,2) # construct tuple
(+) # generic function

Yeah, that’s the kinda-sorta part. Parens are also used for precedence, grouping of expressions, tuples, named tuples and more… in addition to function calls.

In actuality, you can’t split sin.(x), into either sin. nor .(. It’s just sin.(x). That’s just the way it is.

3 Likes

Broadcasting doesn’t work without it. It is for operators like + that aren’t “normally” used as functions, even though they do have corresponding functions. So while you can use the +(x,y) function for scalars, it does not work if you want to broadcast it unless you are a bit more explicit about what you are broadcasting which is what the parentheses give you.

julia> 1 .+ [2,3]
2-element Vector{Int64}:
 3
 4

julia> +.(1,[2,3])
ERROR: syntax: numeric constant "." cannot be implicitly multiplied because it ends with "."
Stacktrace:
 [1] top-level scope
   @ none:1

julia> (+).(1,[2,3])
2-element Vector{Int64}:
 3
 4
2 Likes

This important part is the comma. (1,) makes a tuple, but (1) is just 1 where the parentheses define precedence.