Constructors for structs with NamedTuple fields

One more thing. You can define your own “catch-all” method and do what you want with everything that is not an Integer (I think is better to do this instead of deleting methods):

@kwdef struct A
    x::Integer = 0
end

A(x) = error("I really don't want to convert stuff.")
A(x) = error("I really don't want to convert stuff (overriding).")

A('a')
# ERROR: I really don't want to convert stuff (overriding).
# Stacktrace:
#  [1] error(s::String)
#    @ Base ./error.jl:35
#  [2] A(x::Char)
#    @ Main ~/code/playtest/innerconstr.jl:23
#  [3] top-level scope
#    @ ~/code/playtest/innerconstr.jl:25

A(1) # works

Regardless of what was generated by @kwdef as A(x) method, the most recent one is in effect (you can see that I also generated two of them - but only the last one counts).

1 Like

@Benny, I think we (or at least, I) need someone with internals knowledge.

After some more digging, I reached this stage - and, well, that is a pretty large code base to be able to derive any non-speculative conclusions (also, my C knowledge ends at a now forgotten page number from K&R book - no real-world project whatsoever).

However, this becomes time-consuming with no real progress for me (unless the permalink above can be considered progress), and I am not even sure I am on the right path. Should we tag somebody? Or open an issue?

1 Like

If you’re referring to the new mystery, maybe a new discourse thread tagged Internals and Design since this has gone beyond the specific use case here. As for an issue I wouldn’t even know what it should be, maybe some people on that thread could help narrow that down.

1 Like

I see 4 issues. All of these seem concerning enough to me to escalate, but I am not qualified enough to be certain. And I don’t know who to raise these with.

  1. convert has strange behavior here:
instance = (a=NaN,)
type1 = NamedTuple{(:a,), Tuple{A}} where A<:Real # abstract type

instance::type1 # confirms that instance is of type1
convert(type1, instance) # ERROR: UndefVarError: `T` not defined
  1. internal type constructor tries to apply convert even when the type assertion already holds:
struct F
    x::type1
    F(x::type1=instance) = new(x)
end
F() # UndefVarError: `T` not defined
  1. The default struct constructor has a method that accepts arguments without type restrictions, even though the struct field is type-annotated:
julia> struct A
       a::Int64
       end

julia> methods(A)
# 2 methods for type constructor:
 [1] A(a::Int64)
     @ REPL[7]:2
 [2] A(a)
     @ REPL[7]:2
  1. function definitions allow default values of improper types:
f(x::Integer="Not Integer") = "Why is this allowed?" # does not throw error
f() # throws an error

Edit: I’ve opened two issues on github:

1 Like