diff --git a/NEWS.md b/NEWS.md index 5b5dc10873c5ad..b283fad4854831 100644 --- a/NEWS.md +++ b/NEWS.md @@ -24,6 +24,8 @@ This section lists changes that do not have deprecation warnings. * `broadcast` now handles tuples, and treats any argument that is not a tuple or an array as a "scalar" ([#16986]). + * `broadcast` now treats `Ref` arguments as 0-dimensional arrays ([#18965]). + Library improvements -------------------- @@ -688,4 +690,5 @@ Language tooling improvements [#18339]: https://github.com/JuliaLang/julia/issues/18339 [#18346]: https://github.com/JuliaLang/julia/issues/18346 [#18839]: https://github.com/JuliaLang/julia/issues/18839 +[#18965]: https://github.com/JuliaLang/julia/issues/18965 [#19018]: https://github.com/JuliaLang/julia/issues/19018 diff --git a/base/broadcast.jl b/base/broadcast.jl index 061a20363d5c45..bb2eeac5cf468f 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -265,15 +265,16 @@ end """ broadcast(f, As...) -Broadcasts the arrays, tuples and/or scalars `As` to a container of the +Broadcasts the arrays, tuples, `Ref` and/or scalars `As` to a container of the appropriate type and dimensions. In this context, anything that is not a -subtype of `AbstractArray` or `Tuple` is considered a scalar. The resulting +subtype of `AbstractArray`, `Ref` or `Tuple` is considered a scalar. The resulting container is established by the following rules: - If all the arguments are scalars, it returns a scalar. - If the arguments are tuples and zero or more scalars, it returns a tuple. - - If there is at least an array in the arguments, it returns an array - (and treats tuples as 1-dimensional arrays) expanding singleton dimensions. + - If there is at least an array or a `Ref` in the arguments, it returns an array + (and treats any `Ref` and tuple as 0-dimensional and 1-dimensional arrays, + respectively) expanding singleton dimensions. A special syntax exists for broadcasting: `f.(args...)` is equivalent to `broadcast(f, args...)`, and nested `f.(g.(args...))` calls are fused into a @@ -315,11 +316,16 @@ julia> abs.((1, -2)) julia> broadcast(+, 1.0, (0, -2.0)) (1.0,-1.0) -julia> broadcast(+, 1.0, (0, -2.0), [1]) +julia> broadcast(+, 1.0, (0, -2.0), Ref(1)) 2-element Array{Float64,1}: 2.0 0.0 +julia> (+).([[0,2], [1,3]], Ref{Vector{Int}}([1,-1])) +2-element Array{Array{Int64,1},1}: + [1,1] + [2,2] + julia> string.(("one","two","three","four"), ": ", 1:4) 4-element Array{String,1}: "one: 1" diff --git a/doc/manual/arrays.rst b/doc/manual/arrays.rst index ba99ceb0419731..b726de3f11eedf 100644 --- a/doc/manual/arrays.rst +++ b/doc/manual/arrays.rst @@ -526,7 +526,7 @@ function elementwise: Elementwise operators such as ``.+`` and ``.*`` perform broadcasting if necessary. There is also a :func:`broadcast!` function to specify an explicit destination, and :func:`broadcast_getindex` and :func:`broadcast_setindex!` that broadcast the indices before indexing. Moreover, ``f.(args...)`` is equivalent to ``broadcast(f, args...)``, providing a convenient syntax to broadcast any function (:ref:`man-dot-vectorizing`). -Additionally, :func:`broadcast` is not limited to arrays (see the function documentation), it also handles tuples and treats any argument that is not an array or a tuple as a "scalar". +Additionally, :func:`broadcast` is not limited to arrays (see the function documentation), it also handles tuples and treats any argument that is not an array, tuple or `Ref` as a "scalar". .. doctest:: diff --git a/doc/stdlib/arrays.rst b/doc/stdlib/arrays.rst index 494adf1647a27e..d643c9687f2dab 100644 --- a/doc/stdlib/arrays.rst +++ b/doc/stdlib/arrays.rst @@ -640,11 +640,11 @@ All mathematical operations and functions are supported for arrays .. Docstring generated from Julia source - Broadcasts the arrays, tuples and/or scalars ``As`` to a container of the appropriate type and dimensions. In this context, anything that is not a subtype of ``AbstractArray`` or ``Tuple`` is considered a scalar. The resulting container is established by the following rules: + Broadcasts the arrays, tuples, ``Ref`` and/or scalars ``As`` to a container of the appropriate type and dimensions. In this context, anything that is not a subtype of ``AbstractArray``\ , ``Ref`` or ``Tuple`` is considered a scalar. The resulting container is established by the following rules: * If all the arguments are scalars, it returns a scalar. * If the arguments are tuples and zero or more scalars, it returns a tuple. - * If there is at least an array in the arguments, it returns an array (and treats tuples as 1-dimensional arrays) expanding singleton dimensions. + * If there is at least an array or a ``Ref`` in the arguments, it returns an array (and treats any ``Ref`` and tuple as 0-dimensional and 1-dimensional arrays, respectively) expanding singleton dimensions. A special syntax exists for broadcasting: ``f.(args...)`` is equivalent to ``broadcast(f, args...)``\ , and nested ``f.(g.(args...))`` calls are fused into a single broadcast loop. @@ -685,11 +685,16 @@ All mathematical operations and functions are supported for arrays julia> broadcast(+, 1.0, (0, -2.0)) (1.0,-1.0) - julia> broadcast(+, 1.0, (0, -2.0), [1]) + julia> broadcast(+, 1.0, (0, -2.0), Ref(1)) 2-element Array{Float64,1}: 2.0 0.0 + julia> (+).([[0,2], [1,3]], Ref{Vector{Int}}([1,-1])) + 2-element Array{Array{Int64,1},1}: + [1,1] + [2,2] + julia> string.(("one","two","three","four"), ": ", 1:4) 4-element Array{String,1}: "one: 1"