Skip to content

Commit

Permalink
add Returns (JuliaLang#39794)
Browse files Browse the repository at this point in the history
  • Loading branch information
jw3126 authored and antoine-levitt committed May 9, 2021
1 parent 273339a commit 6e44558
Show file tree
Hide file tree
Showing 25 changed files with 141 additions and 86 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ New library functions
* Two argument methods `findmax(f, domain)`, `argmax(f, domain)` and the corresponding `min` versions ([#27613]).
* `isunordered(x)` returns true if `x` is value that is normally unordered, such as `NaN` or `missing`.
* New macro `Base.@invokelatest f(args...; kwargs...)` provides a convenient way to call `Base.invokelatest(f, args...; kwargs...)` ([#37971])
* New functor `Returns(value)`, which returns `value` for any arguments ([#39794])
* New macro `Base.@invoke f(arg1::T1, arg2::T2; kwargs...)` provides an easier syntax to call `invoke(f, Tuple{T1,T2}, arg1, arg2; kwargs...)` ([#38438])

New library features
Expand Down
8 changes: 4 additions & 4 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1604,7 +1604,7 @@ _cat_size_shape(dims, shape) = shape

_cshp(ndim::Int, ::Tuple{}, ::Tuple{}, ::Tuple{}) = ()
_cshp(ndim::Int, ::Tuple{}, ::Tuple{}, nshape) = nshape
_cshp(ndim::Int, dims, ::Tuple{}, ::Tuple{}) = ntuple(b -> 1, Val(length(dims)))
_cshp(ndim::Int, dims, ::Tuple{}, ::Tuple{}) = ntuple(Returns(1), Val(length(dims)))
@inline _cshp(ndim::Int, dims, shape, ::Tuple{}) =
(shape[1] + dims[1], _cshp(ndim + 1, tail(dims), tail(shape), ())...)
@inline _cshp(ndim::Int, dims, ::Tuple{}, nshape) =
Expand Down Expand Up @@ -1810,7 +1810,7 @@ function hvcat(nbc::Integer, as...)
mod(n,nbc) != 0 &&
throw(ArgumentError("number of arrays $n is not a multiple of the requested number of block columns $nbc"))
nbr = div(n,nbc)
hvcat(ntuple(i->nbc, nbr), as...)
hvcat(ntuple(Returns(nbc), nbr), as...)
end

"""
Expand Down Expand Up @@ -2238,9 +2238,9 @@ function mapslices(f, A::AbstractArray; dims)
end
nextra = max(0, length(dims)-ndims(r1))
if eltype(Rsize) == Int
Rsize[dims] = [size(r1)..., ntuple(d->1, nextra)...]
Rsize[dims] = [size(r1)..., ntuple(Returns(1), nextra)...]
else
Rsize[dims] = [axes(r1)..., ntuple(d->OneTo(1), nextra)...]
Rsize[dims] = [axes(r1)..., ntuple(Returns(OneTo(1)), nextra)...]
end
R = similar(r1, tuple(Rsize...,))

Expand Down
8 changes: 4 additions & 4 deletions base/abstractarraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ julia> selectdim(A, 2, 3)
@noinline function _selectdim(A, d, i, idxs)
d >= 1 || throw(ArgumentError("dimension must be ≥ 1, got $d"))
nd = ndims(A)
d > nd && (i == 1 || throw(BoundsError(A, (ntuple(k->Colon(),d-1)..., i))))
d > nd && (i == 1 || throw(BoundsError(A, (ntuple(Returns(Colon()),d-1)..., i))))
return view(A, idxs...)
end

Expand Down Expand Up @@ -225,7 +225,7 @@ function repeat(A::AbstractArray, counts...)
end

"""
repeat(A::AbstractArray; inner=ntuple(x->1, ndims(A)), outer=ntuple(x->1, ndims(A)))
repeat(A::AbstractArray; inner=ntuple(Returns(1), ndims(A)), outer=ntuple(Returns(1), ndims(A)))
Construct an array by repeating the entries of `A`. The i-th element of `inner` specifies
the number of times that the individual entries of the i-th dimension of `A` should be
Expand Down Expand Up @@ -491,7 +491,7 @@ julia> collect(eachslice(M, dims=2))
length(dims) == 1 || throw(ArgumentError("only single dimensions are supported"))
dim = first(dims)
dim <= ndims(A) || throw(DimensionMismatch("A doesn't have $dim dimensions"))
inds_before = ntuple(d->(:), dim-1)
inds_after = ntuple(d->(:), ndims(A)-dim)
inds_before = ntuple(Returns(:), dim-1)
inds_after = ntuple(Returns(:), ndims(A)-dim)
return (view(A, inds_before..., i, inds_after...) for i in axes(A, dim))
end
2 changes: 1 addition & 1 deletion base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1734,7 +1734,7 @@ function vcat(arrays::Vector{T}...) where T
return arr
end

_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(x->1, n-1)..., length(x)))
_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(Returns(1), n-1)..., length(x)))

## find ##

Expand Down
2 changes: 1 addition & 1 deletion base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ function iterate(d::ImmutableDict{K,V}, t=d) where {K, V}
!isdefined(t, :parent) && return nothing
(Pair{K,V}(t.key, t.value), t.parent)
end
length(t::ImmutableDict) = count(x->true, t)
length(t::ImmutableDict) = count(Returns(true), t)
isempty(t::ImmutableDict) = !isdefined(t, :parent)
empty(::ImmutableDict, ::Type{K}, ::Type{V}) where {K, V} = ImmutableDict{K,V}()

Expand Down
2 changes: 1 addition & 1 deletion base/env.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ variable may result in an uppercase `ENV` key.)
const ENV = EnvDict()

getindex(::EnvDict, k::AbstractString) = access_env(k->throw(KeyError(k)), k)
get(::EnvDict, k::AbstractString, def) = access_env(k->def, k)
get(::EnvDict, k::AbstractString, def) = access_env(Returns(def), k)
get(f::Callable, ::EnvDict, k::AbstractString) = access_env(k->f(), k)
in(k::AbstractString, ::KeySet{String, EnvDict}) = _hasenv(k)
pop!(::EnvDict, k::AbstractString) = (v = ENV[k]; _unsetenv(k); v)
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export
Rational,
Regex,
RegexMatch,
Returns,
RoundFromZero,
RoundDown,
RoundingMode,
Expand Down
12 changes: 6 additions & 6 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ module IteratorsMD

# zeros and ones
zero(::CartesianIndex{N}) where {N} = zero(CartesianIndex{N})
zero(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(x -> 0, Val(N)))
zero(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(Returns(0), Val(N)))
oneunit(::CartesianIndex{N}) where {N} = oneunit(CartesianIndex{N})
oneunit(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(x -> 1, Val(N)))
oneunit(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(Returns(1), Val(N)))

# arithmetic, min/max
@inline (-)(index::CartesianIndex{N}) where {N} =
Expand Down Expand Up @@ -458,7 +458,7 @@ module IteratorsMD

# Split out the first N elements of a tuple
@inline function split(t, V::Val)
ref = ntuple(d->true, V) # create a reference tuple of length N
ref = ntuple(Returns(true), V) # create a reference tuple of length N
_split1(t, ref), _splitrest(t, ref)
end
@inline _split1(t, ref) = (t[1], _split1(tail(t), tail(ref))...)
Expand Down Expand Up @@ -685,10 +685,10 @@ checkindex(::Type{Bool}, inds::Tuple, I::CartesianIndices) = all(checkindex.(Boo
# rather than returning N, it returns an NTuple{N,Bool} so the result is inferrable
@inline index_ndims(i1, I...) = (true, index_ndims(I...)...)
@inline function index_ndims(i1::CartesianIndex, I...)
(map(x->true, i1.I)..., index_ndims(I...)...)
(map(Returns(true), i1.I)..., index_ndims(I...)...)
end
@inline function index_ndims(i1::AbstractArray{CartesianIndex{N}}, I...) where N
(ntuple(x->true, Val(N))..., index_ndims(I...)...)
(ntuple(Returns(true), Val(N))..., index_ndims(I...)...)
end
index_ndims() = ()

Expand All @@ -698,7 +698,7 @@ index_ndims() = ()
@inline index_dimsum(::Colon, I...) = (true, index_dimsum(I...)...)
@inline index_dimsum(::AbstractArray{Bool}, I...) = (true, index_dimsum(I...)...)
@inline function index_dimsum(::AbstractArray{<:Any,N}, I...) where N
(ntuple(x->true, Val(N))..., index_dimsum(I...)...)
(ntuple(Returns(true), Val(N))..., index_dimsum(I...)...)
end
index_dimsum() = ()

Expand Down
36 changes: 36 additions & 0 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,42 @@ julia> [1:5;] |> x->x.^2 |> sum |> inv
"""
|>(x, f) = f(x)

"""
f = Returns(value)
Create a callable `f` such that `f(args...; kw...) === value` holds.
# Examples
```jldoctest
julia> f = Returns(42);
julia> f(1)
42
julia> f("hello", x=32)
42
julia> f.value
42
```
!!! compat "Julia 1.7"
Returns requires at least Julia 1.7.
"""
struct Returns{V} <: Function
value::V
Returns{V}(value) where {V} = new{V}(value)
Returns(value) = new{Core.Typeof(value)}(value)
end

(obj::Returns)(args...; kw...) = obj.value
function show(io::IO, obj::Returns)
show(io, typeof(obj))
print(io, "(")
show(io, obj.value)
print(io, ")")
end
# function composition

"""
Expand Down
2 changes: 1 addition & 1 deletion base/reshapedarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ end
# product of trailing dims into the last element
rdims_trailing(l, inds...) = length(l) * rdims_trailing(inds...)
rdims_trailing(l) = length(l)
rdims(out::Val{N}, inds::Tuple) where {N} = rdims(ntuple(i -> OneTo(1), Val(N)), inds)
rdims(out::Val{N}, inds::Tuple) where {N} = rdims(ntuple(Returns(OneTo(1)), Val(N)), inds)
rdims(out::Tuple{}, inds::Tuple{}) = () # N == 0, M == 0
rdims(out::Tuple{}, inds::Tuple{Any}) = ()
rdims(out::Tuple{}, inds::NTuple{M,Any}) where {M} = ()
Expand Down
1 change: 1 addition & 0 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ function show(io::IO, ::MIME"text/plain", f::Function)
end

show(io::IO, ::MIME"text/plain", c::ComposedFunction) = show(io, c)
show(io::IO, ::MIME"text/plain", c::Returns) = show(io, c)

function show(io::IO, ::MIME"text/plain", iter::Union{KeySet,ValueIterator})
isempty(iter) && get(io, :compact, false) && return show(io, iter)
Expand Down
16 changes: 8 additions & 8 deletions test/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,10 @@ function test_scalar_indexing(::Type{T}, shape, ::Type{TestAbstractArray}) where
B = T(A)
@test A == B
# Test indexing up to 5 dimensions
trailing5 = CartesianIndex(ntuple(x->1, max(ndims(B)-5, 0)))
trailing4 = CartesianIndex(ntuple(x->1, max(ndims(B)-4, 0)))
trailing3 = CartesianIndex(ntuple(x->1, max(ndims(B)-3, 0)))
trailing2 = CartesianIndex(ntuple(x->1, max(ndims(B)-2, 0)))
trailing5 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-5, 0)))
trailing4 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-4, 0)))
trailing3 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-3, 0)))
trailing2 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-2, 0)))
i=0
for i5 = 1:size(B, 5)
for i4 = 1:size(B, 4)
Expand Down Expand Up @@ -419,10 +419,10 @@ function test_vector_indexing(::Type{T}, shape, ::Type{TestAbstractArray}) where
N = prod(shape)
A = reshape(Vector(1:N), shape)
B = T(A)
trailing5 = CartesianIndex(ntuple(x->1, max(ndims(B)-5, 0)))
trailing4 = CartesianIndex(ntuple(x->1, max(ndims(B)-4, 0)))
trailing3 = CartesianIndex(ntuple(x->1, max(ndims(B)-3, 0)))
trailing2 = CartesianIndex(ntuple(x->1, max(ndims(B)-2, 0)))
trailing5 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-5, 0)))
trailing4 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-4, 0)))
trailing3 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-3, 0)))
trailing2 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-2, 0)))
idxs = rand(1:N, 3, 3, 3)
@test B[idxs] == A[idxs] == idxs
@test B[vec(idxs)] == A[vec(idxs)] == vec(idxs)
Expand Down
24 changes: 12 additions & 12 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1153,17 +1153,17 @@ end
# issue #5177

c = fill(1,2,3,4)
m1 = mapslices(x-> fill(1,2,3), c, dims=[1,2])
m2 = mapslices(x-> fill(1,2,4), c, dims=[1,3])
m3 = mapslices(x-> fill(1,3,4), c, dims=[2,3])
m1 = mapslices(_ -> fill(1,2,3), c, dims=[1,2])
m2 = mapslices(_ -> fill(1,2,4), c, dims=[1,3])
m3 = mapslices(_ -> fill(1,3,4), c, dims=[2,3])
@test size(m1) == size(m2) == size(m3) == size(c)

n1 = mapslices(x-> fill(1,6), c, dims=[1,2])
n2 = mapslices(x-> fill(1,6), c, dims=[1,3])
n3 = mapslices(x-> fill(1,6), c, dims=[2,3])
n1a = mapslices(x-> fill(1,1,6), c, dims=[1,2])
n2a = mapslices(x-> fill(1,1,6), c, dims=[1,3])
n3a = mapslices(x-> fill(1,1,6), c, dims=[2,3])
n1 = mapslices(_ -> fill(1,6) , c, dims=[1,2])
n2 = mapslices(_ -> fill(1,6) , c, dims=[1,3])
n3 = mapslices(_ -> fill(1,6) , c, dims=[2,3])
n1a = mapslices(_ -> fill(1,1,6), c, dims=[1,2])
n2a = mapslices(_ -> fill(1,1,6), c, dims=[1,3])
n3a = mapslices(_ -> fill(1,1,6), c, dims=[2,3])
@test size(n1a) == (1,6,4) && size(n2a) == (1,3,6) && size(n3a) == (2,1,6)
@test size(n1) == (6,1,4) && size(n2) == (6,3,1) && size(n3) == (2,6,1)

Expand Down Expand Up @@ -1659,7 +1659,7 @@ end
Nmax = 3 # TODO: go up to CARTESIAN_DIMS+2 (currently this exposes problems)
for N = 1:Nmax
#indexing with (UnitRange, UnitRange, UnitRange)
args = ntuple(d->UnitRange{Int}, N)
args = ntuple(Returns(UnitRange{Int}), N)
@test Base.return_types(getindex, Tuple{Array{Float32, N}, args...}) == [Array{Float32, N}]
@test Base.return_types(getindex, Tuple{BitArray{N}, args...}) == Any[BitArray{N}]
@test Base.return_types(setindex!, Tuple{Array{Float32, N}, Array{Int, 1}, args...}) == [Array{Float32, N}]
Expand Down Expand Up @@ -1786,7 +1786,7 @@ end
@test mdsum(A) == 15
@test mdsum2(A) == 15
AA = reshape(aa, tuple(2, shp...))
B = view(AA, 1:1, ntuple(i->Colon(), i)...)
B = view(AA, 1:1, ntuple(Returns(:), i)...)
@test isa(Base.IndexStyle(B), Base.IteratorsMD.IndexCartesian)
@test mdsum(B) == 15
@test mdsum2(B) == 15
Expand All @@ -1799,7 +1799,7 @@ end
A = reshape(a, tuple(shp...))
@test mdsum(A) == 55
@test mdsum2(A) == 55
B = view(A, ntuple(i->Colon(), i)...)
B = view(A, ntuple(Returns(:), i)...)
@test mdsum(B) == 55
@test mdsum2(B) == 55
insert!(shp, 2, 1)
Expand Down
54 changes: 28 additions & 26 deletions test/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1180,8 +1180,8 @@ timesofar("datamove")

@check_bit_operation findfirst(x->x, b1) Union{Int,Nothing}
@check_bit_operation findfirst(x->!x, b1) Union{Int,Nothing}
@check_bit_operation findfirst(x->true, b1) Union{Int,Nothing}
@check_bit_operation findfirst(x->false, b1) Union{Int,Nothing}
@check_bit_operation findfirst(Returns(true ), b1) Union{Int,Nothing}
@check_bit_operation findfirst(Returns(false), b1) Union{Int,Nothing}

@check_bit_operation findall(b1) Vector{Int}
end
Expand Down Expand Up @@ -1275,49 +1275,51 @@ timesofar("find")
@test_throws BoundsError findprevnot(b2, 1001)
@test_throws BoundsError findprev(!, b2, 1001)
@test_throws BoundsError findprev(identity, b1, 1001)
@test_throws BoundsError findprev(x->false, b1, 1001)
@test_throws BoundsError findprev(x->true, b1, 1001)
@test_throws BoundsError findprev(Returns(false), b1, 1001)
@test_throws BoundsError findprev(Returns(true ), b1, 1001)
@test findprev(b1, 1000) == findprevnot(b2, 1000) == findprev(!, b2, 1000) == 777
@test findprev(b1, 777) == findprevnot(b2, 777) == findprev(!, b2, 777) == 777
@test findprev(b1, 776) == findprevnot(b2, 776) == findprev(!, b2, 776) == 77
@test findprev(b1, 77) == findprevnot(b2, 77) == findprev(!, b2, 77) == 77
@test findprev(b1, 76) == findprevnot(b2, 76) == findprev(!, b2, 76) == nothing
@test findprev(b1, -1) == findprevnot(b2, -1) == findprev(!, b2, -1) == nothing
@test findprev(identity, b1, -1) == findprev(x->false, b1, -1) == findprev(x->true, b1, -1) == nothing
@test findprev(identity, b1, -1) == nothing
@test findprev(Returns(false), b1, -1) == nothing
@test findprev(Returns(true), b1, -1) == nothing
@test_throws BoundsError findnext(b1, -1)
@test_throws BoundsError findnextnot(b2, -1)
@test_throws BoundsError findnext(!, b2, -1)
@test_throws BoundsError findnext(identity, b1, -1)
@test_throws BoundsError findnext(x->false, b1, -1)
@test_throws BoundsError findnext(x->true, b1, -1)
@test_throws BoundsError findnext(Returns(false), b1, -1)
@test_throws BoundsError findnext(Returns(true), b1, -1)
@test findnext(b1, 1) == findnextnot(b2, 1) == findnext(!, b2, 1) == 77
@test findnext(b1, 77) == findnextnot(b2, 77) == findnext(!, b2, 77) == 77
@test findnext(b1, 78) == findnextnot(b2, 78) == findnext(!, b2, 78) == 777
@test findnext(b1, 777) == findnextnot(b2, 777) == findnext(!, b2, 777) == 777
@test findnext(b1, 778) == findnextnot(b2, 778) == findnext(!, b2, 778) == nothing
@test findnext(b1, 1001) == findnextnot(b2, 1001) == findnext(!, b2, 1001) == nothing
@test findnext(identity, b1, 1001) == findnext(x->false, b1, 1001) == findnext(x->true, b1, 1001) == nothing
@test findnext(identity, b1, 1001) == findnext(Returns(false), b1, 1001) == findnext(Returns(true), b1, 1001) == nothing

@test findlast(b1) == Base.findlastnot(b2) == 777
@test findfirst(b1) == Base.findfirstnot(b2) == 77

b0 = BitVector()
@test findprev(x->true, b0, -1) == nothing
@test_throws BoundsError findprev(x->true, b0, 1)
@test_throws BoundsError findnext(x->true, b0, -1)
@test findnext(x->true, b0, 1) == nothing
@test findprev(Returns(true), b0, -1) == nothing
@test_throws BoundsError findprev(Returns(true), b0, 1)
@test_throws BoundsError findnext(Returns(true), b0, -1)
@test findnext(Returns(true), b0, 1) == nothing

b1 = falses(10)
@test findprev(x->true, b1, 5) == 5
@test findnext(x->true, b1, 5) == 5
@test findprev(x->true, b1, -1) == nothing
@test findnext(x->true, b1, 11) == nothing
@test findprev(x->false, b1, 5) == nothing
@test findnext(x->false, b1, 5) == nothing
@test findprev(x->false, b1, -1) == nothing
@test findnext(x->false, b1, 11) == nothing
@test_throws BoundsError findprev(x->true, b1, 11)
@test_throws BoundsError findnext(x->true, b1, -1)
@test findprev(Returns(true), b1, 5) == 5
@test findnext(Returns(true), b1, 5) == 5
@test findprev(Returns(true), b1, -1) == nothing
@test findnext(Returns(true), b1, 11) == nothing
@test findprev(Returns(false), b1, 5) == nothing
@test findnext(Returns(false), b1, 5) == nothing
@test findprev(Returns(false), b1, -1) == nothing
@test findnext(Returns(false), b1, 11) == nothing
@test_throws BoundsError findprev(Returns(true), b1, 11)
@test_throws BoundsError findnext(Returns(true), b1, -1)

@testset "issue 32568" for T = (UInt, BigInt)
for x = (1, 2)
Expand Down Expand Up @@ -1382,8 +1384,8 @@ timesofar("reductions")
b2 = bitrand(l)
@test map(~, b1) == map(x->~x, b1) == broadcast(~, b1)
@test map(identity, b1) == map(x->x, b1) == b1
@test map(zero, b1) == map(x->false, b1) == falses(l)
@test map(one, b1) == map(x->true, b1) == trues(l)
@test map(zero, b1) == map(Returns(false), b1) == falses(l)
@test map(one, b1) == map(Returns(true), b1) == trues(l)

@test map(&, b1, b2) == map((x,y)->x&y, b1, b2) == broadcast(&, b1, b2)
@test map(|, b1, b2) == map((x,y)->x|y, b1, b2) == broadcast(|, b1, b2)
Expand All @@ -1407,8 +1409,8 @@ timesofar("reductions")
@test map!(~, b, b1) == map!(x->~x, b, b1) == broadcast(~, b1) == b
@test map!(!, b, b1) == map!(x->!x, b, b1) == broadcast(~, b1) == b
@test map!(identity, b, b1) == map!(x->x, b, b1) == b1 == b
@test map!(zero, b, b1) == map!(x->false, b, b1) == falses(l) == b
@test map!(one, b, b1) == map!(x->true, b, b1) == trues(l) == b
@test map!(zero, b, b1) == map!(Returns(false), b, b1) == falses(l) == b
@test map!(one, b, b1) == map!(Returns(true), b, b1) == trues(l) == b

@test map!(&, b, b1, b2) == map!((x,y)->x&y, b, b1, b2) == broadcast(&, b1, b2) == b
@test map!(|, b, b1, b2) == map!((x,y)->x|y, b, b1, b2) == broadcast(|, b1, b2) == b
Expand Down
Loading

0 comments on commit 6e44558

Please sign in to comment.