The key to understanding Julia’s design choice is that neither arithmetic operators nor number types get “special treatment”:
-
*
is just an operator like any other. It is usually defined for rings, ie objects for which some notion of multiplication (commutative or non-commutative) makes sense. This includes real and complex numbers,ForwardDiff.Dual
numbers, matrices, strings… the list is literally endless since you can always define new methods. -
Subtypes of
<:Number
or<:AbstractMatrix
are types like any other. So if you prefer, you can write completely generic code, eg for a power calculation by doubling, without knowing which type you are dealing with — it is enough to know that*
is supported.
The broadcasting machinery is designed to take care of your use case. At the moment, you have to use something like the solution by @ffevotte, which may look cumbersome but has the advantage of being transparent and consistent with the language.
Other design choices, eg like R’s, are certainly possible, but they break the generic interfaces which are highly valued by experienced Julia users.