[julia-users] Re: Help understanding ASCIIString vs String
Thank you, Avik. I appreciate your help. On Wednesday, April 22, 2015 at 1:34:51 PM UTC-4, Avik Sengupta wrote: The answer to your first question is easy. subtypes() only display the direct subtypes. ASCIIString is a subtype of DirectIndexString, which in turn is a subtype of String julia subtypes(String) 8-element Array{Any,1}: Base.GenericString DirectIndexString RepString RevString{T:AbstractString} RopeString SubString{T:AbstractString} UTF16String UTF8String julia subtypes(DirectIndexString) 2-element Array{Any,1}: ASCIIString UTF32String The answer to your second question is more contentious, though a valid answer might be that this is simply a design choice. A generic discussion is here: http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29 and there are various discussions in the mailing list about why this choice has been made in Julia. Regards - Avik On Wednesday, 22 April 2015 18:20:46 UTC+1, Test This wrote: Avik and Patrick, Thanks to both of you for clarifying this and for the alternative. I have a couple of related questions: - Why is ASCIIString not listed when I do subtypes(String)? - Why is Dict{ASCIIString, Int} not a subtype of Dict{String, Int}, if ASCIIString is a subtype of String? Anyhow, for now, your answers and links are very helpful. On Wednesday, April 22, 2015 at 10:38:27 AM UTC-4, Patrick O'Leary wrote: (The crusade continues) Never fear though, this doesn't mean you have to write more code! Julia supports the use of type variables to express generics. So in your case, instead of: function func(a::Params, b::String, c::Dict{String, Array{Int, 1}}, d::Dict{String, Array{Int, 1}}) ... end which has the aforementioned invariance problem, you can write function func{T:String}(a::Params, b::T, c::Dict{T, Array{Int, 1}}, d::Dict{T, Array{Int, 1}}) ... end which defines a family of methods for any subtype of String. These methods are called, in Julia terms, parametric methods, and are discussed in the manual here: http://docs.julialang.org/en/release-0.3/manual/methods/#parametric-methods Hope this helps, Patrick On Wednesday, April 22, 2015 at 8:54:12 AM UTC-5, Avik Sengupta wrote: So a one line answer to this is julia container types are invariant. Lets take this step by step julia f(x::String) = I am $x f (generic function with 2 methods) julia f(abc) I am abc julia g(x::Dict) = I am a dict of type: $(typeof(x)) g (generic function with 1 method) julia g(Dict(abc=1)) I am a dict of type: Dict{ASCIIString,Int64} julia h(x::Dict{String, Int}) = I am a dict of {String=Int} h (generic function with 1 method) julia h(Dict(abc=1)) ERROR: MethodError: `h` has no method matching h(::Dict{ASCIIString,Int64}) Basically, while an ASCIIString is a subtype of the abstract type String , a Dict{ASCIIString, Int} is not a subtype of Dict{String, Int} See here for more: http://docs.julialang.org/en/release-0.3/manual/types/?highlight=contravariant#man-parametric-types Regards - Avik On Wednesday, 22 April 2015 14:14:06 UTC+1, Test This wrote: I defined a function function func(a::Params, b::String, c::Dict{String, Array{Int, 1}}, d::Dict{String, Array{Int, 1}}) ... end When I run the program, calling this function with func(paramvalue, H, d1, d2), I get an error saying func has no method matching (::Params, ::ASCIIString, ::Dict{ASCIIString,Array{Int64,1}}, ::Dict{ASCIIString,Array{Int64,1}}) The code works if I change String to ASCIIString in the function definition. But I thought (and the REPL seems to agree) that any value of type ASCIIString is also of type String. Then, why am I getting this error. Thanks in advance for your help.
[julia-users] Re: Help understanding ASCIIString vs String
(The crusade continues) Never fear though, this doesn't mean you have to write more code! Julia supports the use of type variables to express generics. So in your case, instead of: function func(a::Params, b::String, c::Dict{String, Array{Int, 1}}, d::Dict{String, Array{Int, 1}}) ... end which has the aforementioned invariance problem, you can write function func{T:String}(a::Params, b::T, c::Dict{T, Array{Int, 1}}, d::Dict{T, Array{Int, 1}}) ... end which defines a family of methods for any subtype of String. These methods are called, in Julia terms, parametric methods, and are discussed in the manual here: http://docs.julialang.org/en/release-0.3/manual/methods/#parametric-methods Hope this helps, Patrick On Wednesday, April 22, 2015 at 8:54:12 AM UTC-5, Avik Sengupta wrote: So a one line answer to this is julia container types are invariant. Lets take this step by step julia f(x::String) = I am $x f (generic function with 2 methods) julia f(abc) I am abc julia g(x::Dict) = I am a dict of type: $(typeof(x)) g (generic function with 1 method) julia g(Dict(abc=1)) I am a dict of type: Dict{ASCIIString,Int64} julia h(x::Dict{String, Int}) = I am a dict of {String=Int} h (generic function with 1 method) julia h(Dict(abc=1)) ERROR: MethodError: `h` has no method matching h(::Dict{ASCIIString,Int64}) Basically, while an ASCIIString is a subtype of the abstract type String , a Dict{ASCIIString, Int} is not a subtype of Dict{String, Int} See here for more: http://docs.julialang.org/en/release-0.3/manual/types/?highlight=contravariant#man-parametric-types Regards - Avik On Wednesday, 22 April 2015 14:14:06 UTC+1, Test This wrote: I defined a function function func(a::Params, b::String, c::Dict{String, Array{Int, 1}}, d::Dict{String, Array{Int, 1}}) ... end When I run the program, calling this function with func(paramvalue, H, d1, d2), I get an error saying func has no method matching (::Params, ::ASCIIString, ::Dict{ASCIIString,Array{Int64,1}}, ::Dict{ASCIIString,Array{Int64,1}}) The code works if I change String to ASCIIString in the function definition. But I thought (and the REPL seems to agree) that any value of type ASCIIString is also of type String. Then, why am I getting this error. Thanks in advance for your help.
[julia-users] Re: Help understanding ASCIIString vs String
Avik and Patrick, Thanks to both of you for clarifying this and for the alternative. I have a couple of related questions: - Why is ASCIIString not listed when I do subtypes(String)? - Why is Dict{ASCIIString, Int} not a subtype of Dict{String, Int}, if ASCIIString is a subtype of String? Anyhow, for now, your answers and links are very helpful. On Wednesday, April 22, 2015 at 10:38:27 AM UTC-4, Patrick O'Leary wrote: (The crusade continues) Never fear though, this doesn't mean you have to write more code! Julia supports the use of type variables to express generics. So in your case, instead of: function func(a::Params, b::String, c::Dict{String, Array{Int, 1}}, d::Dict{String, Array{Int, 1}}) ... end which has the aforementioned invariance problem, you can write function func{T:String}(a::Params, b::T, c::Dict{T, Array{Int, 1}}, d::Dict{T, Array{Int, 1}}) ... end which defines a family of methods for any subtype of String. These methods are called, in Julia terms, parametric methods, and are discussed in the manual here: http://docs.julialang.org/en/release-0.3/manual/methods/#parametric-methods Hope this helps, Patrick On Wednesday, April 22, 2015 at 8:54:12 AM UTC-5, Avik Sengupta wrote: So a one line answer to this is julia container types are invariant. Lets take this step by step julia f(x::String) = I am $x f (generic function with 2 methods) julia f(abc) I am abc julia g(x::Dict) = I am a dict of type: $(typeof(x)) g (generic function with 1 method) julia g(Dict(abc=1)) I am a dict of type: Dict{ASCIIString,Int64} julia h(x::Dict{String, Int}) = I am a dict of {String=Int} h (generic function with 1 method) julia h(Dict(abc=1)) ERROR: MethodError: `h` has no method matching h(::Dict{ASCIIString,Int64}) Basically, while an ASCIIString is a subtype of the abstract type String , a Dict{ASCIIString, Int} is not a subtype of Dict{String, Int} See here for more: http://docs.julialang.org/en/release-0.3/manual/types/?highlight=contravariant#man-parametric-types Regards - Avik On Wednesday, 22 April 2015 14:14:06 UTC+1, Test This wrote: I defined a function function func(a::Params, b::String, c::Dict{String, Array{Int, 1}}, d::Dict{String, Array{Int, 1}}) ... end When I run the program, calling this function with func(paramvalue, H, d1, d2), I get an error saying func has no method matching (::Params, ::ASCIIString, ::Dict{ASCIIString,Array{Int64,1}}, ::Dict{ASCIIString,Array{Int64,1}}) The code works if I change String to ASCIIString in the function definition. But I thought (and the REPL seems to agree) that any value of type ASCIIString is also of type String. Then, why am I getting this error. Thanks in advance for your help.