Stream: helpdesk (published)

Topic: Confusing subtyping


view this post on Zulip Timothy (Nov 26 2021 at 07:48):

I'm a bit confused about why the expected function method isn't being dispatched in my code, and it seems it comes down to this confusing result:

julia> Dict{Char, Vector{Type}} <: Dict{Char, Vector{Type}}
true

julia> Dict{Char, Vector{Type}} <: Dict{Char, Vector{<:Type}}
false

julia> Dict{Char, Vector{DataType}} <: Dict{Char, Vector{Type}}
false

julia> Dict{Char, Vector{DataType}} <: Dict{Char, Vector{<:Type}}
false

If we could work out how to attain the result I'm expecting, that would be great.

For reference, this is the issue I'm having

MethodError: no method matching parseorg(::String, ::Dict{Char, Vector{Type}}, ::Vector{DataType}; debug=false, pointonfail=false)
Closest candidates are:
  parseorg(::AbstractString, ::Dict{Char, Vector{var"#s40"} where var"#s40"<:Type}, ::Vector{var"#s33"} where var"#s33"<:Type; debug, pointonfail)

view this post on Zulip Sukera (Nov 26 2021 at 07:54):

types in julia are invariant

view this post on Zulip Sukera (Nov 26 2021 at 07:54):

(except tuples)

view this post on Zulip Sukera (Nov 26 2021 at 07:55):

see https://docs.julialang.org/en/v1/manual/types/#man-parametric-composite-types

view this post on Zulip Sukera (Nov 26 2021 at 07:58):

I'm guessing you declared your function like parseorg(s::AbstractString, d::Dict{Char, Vector{T}}, v::Vector{U}) where {T <: Type, U <: Type}? To get the dispatch you want, you'd write that as parseorg(s::AbstractString, d::AbstractDict{Char, <:AbstractVector{T}}, v::AbstractVector{U}) where {T, U}, though that feels overly typed to me

view this post on Zulip Timothy (Nov 26 2021 at 07:59):

I've written

 parseorg(content::AbstractString, typematchers::Dict{Char, Vector{<:Type}},
                  typefallbacks::Vector{<:Type}; debug=false, pointonfail=false)

view this post on Zulip Sukera (Nov 26 2021 at 07:59):

yeah, same thing, just without the where

view this post on Zulip Timothy (Nov 26 2021 at 08:00):

So basically going from a concrete to abstract type should do the trick?

view this post on Zulip Sukera (Nov 26 2021 at 08:00):

no, acknowledging that types are invariant does the trick ;)

view this post on Zulip Sukera (Nov 26 2021 at 08:01):

what you've written is asking for a Dict taking a Char as key and pointing to _a_ vector that holds a subtype of Type though

view this post on Zulip Sukera (Nov 26 2021 at 08:01):

note the <: AbstractVector part

view this post on Zulip Timothy (Nov 26 2021 at 08:01):

Ah right, thanks for pointing out that it's that bit

view this post on Zulip Sukera (Nov 26 2021 at 08:02):

do you have to distinguish between different parseorg? if not, I wouldn't necessarily use type annotations at all here

view this post on Zulip Timothy (Nov 26 2021 at 08:02):

I have two forms, yes. I also like typing function arguments when to let myself know what I'm expecting.

view this post on Zulip Sukera (Nov 26 2021 at 08:03):

does that form have the same signature/number & order of arguments?

view this post on Zulip Timothy (Nov 26 2021 at 08:04):

The signature doesn't match. I could get away without typing any of it but then I come back to "I also like typing function arguments when to let myself know what I'm expecting."

view this post on Zulip Sukera (Nov 26 2021 at 08:04):

Yeah, for documentation purposes it's not a bad idea, though be aware that you don't necessarily want to use concrete types in the signature

view this post on Zulip Timothy (Nov 26 2021 at 08:04):

On that note, is there a particular reason why I'd want to go for AbstractDict / AbstractVec ?

view this post on Zulip Sukera (Nov 26 2021 at 08:05):

a view is an AbstractVector :)

view this post on Zulip Sukera (Nov 26 2021 at 08:05):

no need to copy arrays around when slicing after all

view this post on Zulip Sukera (Nov 26 2021 at 08:06):

As for AbstractDict- you could switch to Dictionaries.jl or an OrderedDict from DataStructures.jl if you need a different interface or some ordering in your dict

view this post on Zulip Sukera (Nov 26 2021 at 08:06):

if you have AbstractDict, you don't get MethodError all over the place, since they all satisfy that API

view this post on Zulip Timothy (Nov 26 2021 at 08:07):

Thanks for elaborating. I've got AbstractString here for exactly the reason you mention with vectors (I'm taking lots of substrings).

view this post on Zulip Sukera (Nov 26 2021 at 08:08):

but other than that - I usually don't type things and rather document in comments/docstrings what I expect to hold interface-wise, since apart from dispatch, type annotations in function signatures do not improve performance or help inference

view this post on Zulip Sukera (Nov 26 2021 at 08:09):

the only things I do type religiously is when I have a custom struct internal to my package and I want to make sure to require that struct as an input

view this post on Zulip Timothy (Nov 26 2021 at 08:09):

I do have more info in docstrings, however for er, somewhat unique reasons, I'm not putting the docstrings next to the functions here.

view this post on Zulip Timothy (Nov 26 2021 at 08:10):

( if I do I get load order errors, since the docstrings use a macro which uses the code I'm documenting )

view this post on Zulip Sukera (Nov 26 2021 at 08:12):

:thinking:

view this post on Zulip Sukera (Nov 26 2021 at 08:13):

are you using @doc?

view this post on Zulip Timothy (Nov 26 2021 at 08:14):

I am

view this post on Zulip Sukera (Nov 26 2021 at 08:14):

I'm very curious about how that breaks :o

view this post on Zulip Timothy (Nov 26 2021 at 08:16):

Well, for the sake of your curiosity, this is what I've got going on:

@doc org"""
some lovely documentation
""" parseorg

and as you may imagine, the @org_str macro definition involves calling parseorg :smile:.

view this post on Zulip Sukera (Nov 26 2021 at 08:20):

well, I'm sure you have your reasons for that :sweat_smile:

view this post on Zulip Timothy (Nov 26 2021 at 08:22):

Well, if I'm writing a package to provide nice support for a certain markup language, it would basically be heretical not to write the docs using that markup language wouldn't it? :stuck_out_tongue:

view this post on Zulip Timothy (Nov 26 2021 at 08:46):

Anyway, thanks for the help!


Last updated: Oct 02 2023 at 04:34 UTC