In Fortran and some other languages, you can write exp(x)
whether x is a scalar or an array. In Julia, you need to write exp.(x)
if x is an array. What is the benefit of requiring the dot?
There are plenty of functions that would be ambiguous, such as multiplication between two matrices of the same shape â do you want that to be matrix multiplication or elementwise? You need both for e.g. convolutional neural networks. Languages like Python with numpy generally make those choices on an ad-hoc basis, and avoid ambiguity by assigning multiple operators or just not letting you broadcast most functions.
Julia gives you the ability to broadcast any function, and has the programmer explicitly specify when you want to broadcast in order to resolve the ambiguity.
ETA: making broadcasting part of the syntax also allows certain optimizations, check out More Dots: Syntactic Loop Fusion in Julia
There is a well defined function usually called âexponentialâ of a matrix. It is not equal generally to the exponential of each element of the matrix. You can see this:
julia> a = rand(10,10)
julia> exp(a) == exp.(a)
false
If exp(a)
did the exponential of every element of the matrix, how would you express the matrix exponentiation? You would then have to define some mat_exp
which would lose many of the advantages that multiple dispatch brings us.
Oh! @Satvik is a much faster typer!
I would say that this kind of disambiguation is a useful side effect of requiring dots for broadcasting functions like exp
, but it was not the primary motivation. The primary motivations were:
-
You want the caller to decide what functions to apply elementwise, and it should work for any function. The function implementor should not need to decide this in advance, as explained here.
-
Having the caller indicate elementwise functions syntactically allows us to guarantee that nested elementwise calls are âfusedâ into a single loop without temporary arrays, as explained here. This is not a mere micro-optimizationâfusion can have order-of-magnitude effects on performance and memory usage.
In early versions of Julia , functions like exp
and sqrt
did operate elementwise on array arguments, and we had separate functions expm
and sqrtm
for the âmatrix algebraâ versions (similar to Matlab and Numpy). After dot broadcasting was introduced in Julia 0.6, the latter functions could be renamed to exp
and sqrt
as a happy side effect.
Canât overstate how much how a great decision that was. Iâm regularly amazed when writing plot(some_complicated_function.(1:N)). In Matlab I had to constantly worry about the shape of the input to a function whenever I thought I could want to apply it elementwise later.
14 posts were split to a new topic: When does exp(A) â exp.(A)
?