As @laborg says, !
and broadcast .
have nothing to do with each other.
The exclamation mark is not syntax, and doesn’t do anything, so if you create a function foo
, and then try to add an exclamation mark, you get
julia> foo!(1)
ERROR: UndefVarError: foo! not defined
Stacktrace:
[1] top-level scope at none:0
So foo!
does not exist, you have to explicitly define it. The !
is just an ordinary character that you can put into a name. Defining, for example hello!world = 4
, creates a variable with the name hello!world
. But everyone has just agreed that if your function modifies any of its input arguments, then the name of that function should end with !
to help the user see what’s going on.
The broadcast .
is very different. If you add a .
to a function or an operator it changes how it works. If you take your function foo
and add a dot to it, it will work:
julia> foo.(1:3)
3-element Array{Float64,1}:
1.3817732906760363
0.4931505902785393
-0.8488724885405782
(I have actually defined f(x) = sin(x) + cos(x)
). You don’t need to define the function foo.
, instead, .
is a syntax that changes the behaviour of foo
(unlike !
!!)
The dot broadcast operator in its simplest sense changes your functions to work elementwise, so foo.(1:3)
will loop over the input 1:3
and produce an output vector.
As for the in-place behaviour, you get that when assigning. If you already have a length 3 vector called y
lying around, you can do this
y .= foo.(1:3)
Then y
will be modified in-place
, in stead of having to define a new output variable for foo.
.
Dot broadcasting can do a lot more, this was just the simplest possible example. Take a look here for a much more educational introduction: More Dots: Syntactic Loop Fusion in Julia