Optional positional arguments NOT occur at end?

we know that optional positional arguments must occur at end, however, functions like zeros() and ones() seems to violate the rule:

zeros([T=Float64,] dims...)
ones([T=Float64,] dims...)

I tried to understand how it works, but the source tells me nothing:

function zeros end
function ones end

what’s the trick? thanks

what I could imagine is to define two functions:

function ones(T::Type, dims...)
   # some code depends on T
end

function ones(dims...)
    # some code with the knowledge of "T == Float64"
end

is it the way to do?

I think that is correct.

for (fname, felt) in ((:zeros, :zero), (:ones, :one))
    @eval begin
        $fname(dims::DimOrInd...) = $fname(dims)
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
        $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N} = fill!(Array{T,N}(undef, map(to_dim, dims)), $felt(T))
        $fname(::Type{T}, dims::Tuple{}) where {T} = fill!(Array{T}(undef), $felt(T))
    end
end
1 Like

Yes, pretty much.

ones(dims...) = ones(Float64, dims...)
1 Like

thanks