Giter VIP home page Giter VIP logo

Comments (8)

nsajko avatar nsajko commented on May 11, 2024

julia/base/essentials.jl

Lines 568 to 585 in cb9b00d

_tuple_error(T::Type, x) = (@noinline; throw(MethodError(convert, (T, x))))
convert(::Type{T}, x::T) where {T<:Tuple} = x
function convert(::Type{T}, x::NTuple{N,Any}) where {N, T<:Tuple}
# First see if there could be any conversion of the input type that'd be a subtype of the output.
# If not, we'll throw an explicit MethodError (otherwise, it might throw a typeassert).
if typeintersect(NTuple{N,Any}, T) === Union{}
_tuple_error(T, x)
end
function cvt1(n)
@inline
Tn = fieldtype(T, n)
xn = getfield(x, n, #=boundscheck=#false)
xn isa Tn && return xn
return convert(Tn, xn)
end
return ntuple(cvt1, Val(N))::NTuple{N,Any}
end

from julia.

vtjnash avatar vtjnash commented on May 11, 2024

I believe (but you can try testing this) taht the design and implementation of NamedTuple required that there was no type-assert here, as it relies on Type{T} elements being ignored. But there is not really a bug with it returning a value when it could have errored, and certainly not a correctness issue.

from julia.

nsajko avatar nsajko commented on May 11, 2024

Could you explain a bit more why the current behavior is correct? I'd usually expect that a call like T(x) or convert(T, x) would return a value of type T (or throw), which doesn't happen in this case.

I'm interested in this problem because I'm looking into fixing #52993, so there I hit the exact same problem of what to do with UnionAll types which subtype Tuple. I think that maybe we could just throw if the type is UnionAll?

from julia.

vtjnash avatar vtjnash commented on May 11, 2024

Some users want to write convert(Tuple{Type{T}}, (T,)). That is somewhat badly written, but actually fairly reasonable to want to work. I don't see how that is related to the performance of the current implementation for _totuple(::Type{Tuple{Vararg{E}}}, itr, s...). And we cannot just start adding breaking errors in v1.x for cases that are not previously broken.

from julia.

nsajko avatar nsajko commented on May 11, 2024

I notice that the behavior when constructing a tuple from a tuple is inconsistent with the behavior when constructing a tuple from other iterators (xref #44179, where it was concluded that a type assertion is desirable):

julia> NTuple{2}((1, nothing))
(1, nothing)

julia> NTuple{2}([1, nothing])
ERROR: TypeError: in typeassert, expected Tuple{T, T} where T, got a value of type Tuple{Int64, Nothing}
Stacktrace:
 [1] _totuple
   @ ./tuple.jl:474 [inlined]
 [2] (Tuple{T, T} where T)(itr::Vector{Union{Nothing, Int64}})
   @ Base ./tuple.jl:455
 [3] top-level scope
   @ REPL[4]:1

julia> versioninfo()
Julia Version 1.11.0-DEV.1451
Commit f117a500ca9 (2024-02-01 15:38 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, znver2)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)

I hope we could even out this inconsistency, in either direction?

from julia.

nsajko avatar nsajko commented on May 11, 2024

Would it be OK if we made the <:Tuple constructors always assert the return type, but leave convert as it is?

from julia.

vtjnash avatar vtjnash commented on May 11, 2024

Probably not. The inverse is possibly okay: convert already uses type-assert afterwards so would probably be unimpacted, but NamedTuple and similar codes already assume the constructor does not type-assert

from julia.

vtjnash avatar vtjnash commented on May 11, 2024

And to be clear, a type-assert would probably be welcome for both, but needs to be done such that it doesn't break other code

from julia.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.