-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
A somewhat typical situation is that we need to compute a = b + c, and we know that whatever object that was previously bound to a is not needed anymore. However, we don't know whether a is effectively immutable (e.g. Int, SArray) or mutable (e.g. BigInt, Array), because we are writing generic code. In the immutable case, a = b + c is the right thing. In the Array case, a .= b .+ c is the right thing, and in the BigInt case the right thing is Base.GMP.MPZ.add!(a, b, c).
Assignments can have three types of mutation semantics: (1) no mutation, use a = ..., (2) mutate, use a .= ... as syntactic sugar for a function call, (3) do whatever is fast.
We currently can't express (3), i.e. we want a way for programmers to express that mutation is a valid optimization. In case of functions with long names, this could be done with keyword argument, e.g. a = union(a, b; inplace = true) instead of a = union(a,b) (immutable set) or union!(a,b) (mutable set). But it is not entirely clear what to use for infix operators.
Something that appears to be still free (i.e. currently a parsing failure) is a ?.= b .+ c, which could use a modification of the broadcast machinery: Lower this to a = broadcast!(MaybeInplace(), +, a, b, c) which then becomes either a = (broadcast!(+, a, b, c); a) / a = (Base.GMP.MPZ.add!(a,b,c); a) in the mutable case, or a = (broadcast(+,b,c)) in the immutable case, depending on types and operations. a !.= ... and a ?= ... are also free.