Skip to content
Merged
4 changes: 2 additions & 2 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
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(Always(nbc), nbr), as...)
end

"""
Expand Down Expand Up @@ -2112,7 +2112,7 @@ _sub2ind_vec(i) = ()

function _ind2sub(inds::Union{DimsInteger{N},Indices{N}}, ind::AbstractVector{<:Integer}) where N
M = length(ind)
t = ntuple(n->similar(ind),Val(N))
t = ntuple(Always(similar(ind)),Val(N))
for (i,idx) in pairs(IndexLinear(), ind)
sub = _ind2sub(inds, idx)
for j = 1:N
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(Always(true), t)
isempty(t::ImmutableDict) = !isdefined(t, :parent)
empty(::ImmutableDict, ::Type{K}, ::Type{V}) where {K, V} = ImmutableDict{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 @@ -21,6 +21,7 @@ export
AbstractUnitRange,
AbstractVector,
AbstractVecOrMat,
Always,
Array,
AbstractMatch,
AbstractPattern,
Expand Down
32 changes: 32 additions & 0 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,38 @@ julia> [1:5;] |> x->x.^2 |> sum |> inv
"""
|>(x, f) = f(x)

# always
"""
f = Always(value)

Create a callable `f` such that `f(args...; kw...) === value` holds.

# Examples

```jldoctest
julia> f = Always(42);

julia> f(1)
42

julia> f("hello", x=32)
42
```

!!! compat "Julia 1.7"
Always requires at least Julia 1.7.
"""
struct Always{V} <: Function
value::V
end

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

"""
Expand Down
18 changes: 9 additions & 9 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(Always(fill(1,2,3)), c, dims=[1,2])
m2 = mapslices(Always(fill(1,2,4)), c, dims=[1,3])
m3 = mapslices(Always(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(Always(fill(1,6) ), c, dims=[1,2])
n2 = mapslices(Always(fill(1,6) ), c, dims=[1,3])
n3 = mapslices(Always(fill(1,6) ), c, dims=[2,3])
n1a = mapslices(Always(fill(1,1,6)), c, dims=[1,2])
n2a = mapslices(Always(fill(1,1,6)), c, dims=[1,3])
n3a = mapslices(Always(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
6 changes: 3 additions & 3 deletions test/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ end
@test collect(takewhile(<(4),1:10)) == [1,2,3]
@test collect(takewhile(<(4),Iterators.countfrom(1))) == [1,2,3]
@test collect(takewhile(<(4),5:10)) == []
@test collect(takewhile(_->true,5:10)) == 5:10
@test collect(takewhile(Always(true),5:10)) == 5:10
@test collect(takewhile(isodd,[1,1,2,3])) == [1,1]
@test collect(takewhile(<(2), takewhile(<(3), [1,1,2,3]))) == [1,1]
end
Expand All @@ -209,8 +209,8 @@ end
@test collect(dropwhile(<(4), 1:10)) == 4:10
@test collect(dropwhile(<(4), 1:10)) isa Vector{Int}
@test isempty(dropwhile(<(4), []))
@test collect(dropwhile(_->false,1:3)) == 1:3
@test isempty(dropwhile(_->true, 1:3))
@test collect(dropwhile(Always(false),1:3)) == 1:3
@test isempty(dropwhile(Always(true), 1:3))
@test collect(dropwhile(isodd,[1,1,2,3])) == [2,3]
@test collect(dropwhile(iseven,dropwhile(isodd,[1,1,2,3]))) == [3]
end
Expand Down
10 changes: 10 additions & 0 deletions test/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,13 @@ a = rand(3, 3)
@test transpose(a) === a'ᵀ

@test [Base.afoldl(+, 1:i...) for i = 1:40] == [i * (i + 1) ÷ 2 for i = 1:40]

@testset "Always" begin
@test @inferred(Always(1)() ) === 1
@test @inferred(Always(1)(23) ) === 1
@test @inferred(Always("a")(2,3)) == "a"
@test @inferred(Always(1)(x=1, y=2)) === 1
val = [1,2,3]
@test Always(val)(1) === val
@test sprint(show, Always(1)) == "Always(1)"
end