Tried something that I knew wouldn't work, but got an error message that I didn't expect. Not sure if this is just an uninformative error message or something more devious.
julia> using LinearAlgebra
julia> di = Dict("a" => 1, "b" => 2,"c"=>3.0)
Dict{String,Real} with 3 entries:
"c" => 3.0
"b" => 2
"a" => 1
julia> dot(di,rand(3))
ERROR: StackOverflowError:
Stacktrace:
[1] dot(::Char, ::Float64) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/LinearAlgebra/src/generic.jl:869 (repeats 79984 times)
julia> versioninfo()
Julia Version 1.4.1
Commit 381693d3df* (2020-04-14 17:20 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-8.0.1 (ORCJIT, skylake)
The error is right evaluation error.
Please look this a part of dot code.
dot function in dot calls dot(vx, vy).
If vx, vy are not equal Abstract type, it calls itself.
julia> di = Dict("a" => 1, "b" => 2,"c"=>3.0)
Dict{String,Real} with 3 entries:
"c" => 3.0
"b" => 2
"a" => 1
julia> vx, vs = iterate(di)
(Pair{String,Real}("c", 3.0), 5)
julia> vx2, vs = iterate(vx)
("c", 2)
julia> vx3, vs = iterate(vx2)
('c', 2)
and
julia> vx4, vs = iterate(vx3)
('c', true)
iterate of Char type returns Tuple{Char,Bool}.
So I think the error is right.
Not sure I agree. For a comparable scenario you get
julia> 'a' * 2.0
ERROR: MethodError: no method matching *(::Char, ::Float64)
Closest candidates are:
*(::Any, ::Any, ::Any, ::Any...) at operators.jl:529
*(::Bool, ::T) where T<:AbstractFloat at bool.jl:110
*(::Float64, ::Float64) at float.jl:405
...
Stacktrace:
[1] top-level scope at REPL[78]:1
Right, the fallback dot(x, y) method is circular when x or y is a non-Number that iterates itself, e.g. a Char. Not sure what the best fix is; maybe we could throw a better error if vx === x?
Allowing
julia> dot([[Set([[1]])], 2], [1, [(2,)]])
5
in the first place does not sound right to me. Is it intentional?
maybe we could throw a better error if
vx === x?
I agree this is the least breaking and user-friendly fix.
LinearAlgebra operates Number, so this code to calculate dot of numbers is defined in LinearAlgebra module.
A way solving this problem is to define like
dot(s1::AbstractChar, s2::AbstractChar) = s1 * s2
dot(s1::AbstractChar, s2) = s1 * s2
dot(s1, s2::AbstractChar) = s1 * s2
However it can't solve other iteratable not collection types.
We need to defined it in each type.
And I don't think it is a good design to define other type (not Number type) in LinearAlgebra.
So if we define it, we define it in base/char.jl.
Sorry the code conflicts with other dot (ex. dot(s1::Foo, s2) = s1 * s2).
It doesn't run.
Most helpful comment
Right, the fallback
dot(x, y)method is circular when x or y is a non-Number that iterates itself, e.g. aChar. Not sure what the best fix is; maybe we could throw a better error ifvx === x?