Skip to content

Syntax for maybe-mutating operations #30407

@chethega

Description

@chethega

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions