What is going on here? Why is this not allowed, and given that it is not allowed, why is there not an error?
julia> a,b = 1,2
(1, 2)
julia> [a+b for (a=>b) in [3=>4, 5=>6]]
2-element Vector{Int64}:
3
3
What is going on here? Why is this not allowed, and given that it is not allowed, why is there not an error?
julia> a,b = 1,2
(1, 2)
julia> [a+b for (a=>b) in [3=>4, 5=>6]]
2-element Vector{Int64}:
3
3
Invalid unpacking syntax:
julia> (a, b) = 3 => 4
3 => 4
julia> (a => b) = 3 => 4
Error showing value of type UnionAll:
ERROR:
SYSTEM (REPL): showing an error caused an error
ERROR:
SYSTEM (REPL): caught exception of type StackOverflowError while trying to handle a nested exception; giving up
edit: that two-line demo is a remarkably innocuous-looking way to create an irrecoverable, unkillable state.
Try
julia> [a+b for (a, b) in [3=>4, 5=>6]]
2-element Vector{Int64}:
7
11
Thanks! I realize now that my initial question was a bit lacking. Iβve edited it to be more specific.
where did you see this? Julia is not Haskell/Clojure (I donβt know what language has this pattern matching just guessing here). This is simply not a thing in Julia
If itβs invalid syntax or simply not a thing Iβd like to get ERROR: syntax: invalid iteration specification
. Similarly, does [8 for f(x) in 1:3]
have any sensical meaning? It evaluates without error to [8,8,8]
, but [8 for f(5) in 1:3]
gives an ERROR: syntax: "5" is not a valid function argument name
.
I feel like your demo is getting at a deeper issue.
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _' | |
| | |_| | | | (_| | | Version 1.7.0 (2021-11-30)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> a => b = error("Hi!") # Let's define a new function
=> (generic function with 1 method) # Only 1 method
julia> 1 => 2 # Oh look, the new method throws an error :)
ERROR: Hi!
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:33
[2] =>(a::Int64, b::Int64)
@ Main ./REPL[1]:1
[3] top-level scope
@ REPL[2]:1
julia> 1+1 # At least this still works
2
julia> Pair(1, 2) # Wow, Julia internals don't break when I define a new function Main.=>
1 => 2
julia>
whereas
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _' | |
| | |_| | | | (_| | | Version 1.7.0 (2021-11-30)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> 3 => 4 # This line is the only difference between this example and the last. It should have no side effects but...
3 => 4
julia> a => b = error("Hi!") # We try to define a new function but...
Error showing value of type UnionAll:
ERROR:
SYSTEM (REPL): showing an error caused an error
ERROR:
SYSTEM (REPL): caught exception of type ErrorException while trying to handle a nested exception; giving up
julia> 1+1 # Wow, this is bad...
β Error: Error in the keymap
β exception =
β Hi!
β Stacktrace:
β [1] error(s::String)
β @ Base ./error.jl:33
β [2] Pair(a::Int64, b::Int64)
β @ Main ./REPL[2]:1
β [3] _region(s::Union{REPL.LineEdit.MIState, REPL.LineEdit.ModeState, IOBuffer})
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:131
β [4] region(s::Union{REPL.LineEdit.MIState, REPL.LineEdit.ModeState, IOBuffer})
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:132
β [5] refresh_multi_line(termbuf::REPL.Terminals.TerminalBuffer, terminal::REPL.Terminals.UnixTerminal, buf::IOBuffer, state::REPL.LineEdit.InputAreaState, prompt::Any; indent::Int64, region_active::Bool)
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:430
β [6] refresh_multi_line(termbuf::REPL.Terminals.TerminalBuffer, terminal::REPL.Terminals.UnixTerminal, s::Union{REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PromptState}; beeping::Bool)
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:1840
β [7] refresh_multi_line(termbuf::REPL.Terminals.TerminalBuffer, terminal::REPL.Terminals.UnixTerminal, s::Union{REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PromptState})
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:1839
β [8] refresh_multi_line(terminal::REPL.Terminals.UnixTerminal, args::Any; kwargs::Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}})
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:533
β [9] refresh_multi_line(terminal::REPL.Terminals.UnixTerminal, args::Any)
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:531
β [10] refresh_multi_line(s::REPL.LineEdit.PromptState; kw::Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}})
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:412
β [11] refresh_multi_line(s::REPL.LineEdit.PromptState)
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:408
β [12] refresh_multi_line(::REPL.LineEdit.MIState)
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:227
β [13] refresh_line(s::Union{REPL.LineEdit.MIState, REPL.LineEdit.ModeState, IOBuffer})
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:1327
β [14] commit_line(s::REPL.LineEdit.MIState)
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:2131
β [15] (::REPL.LineEdit.var"#113#166")(::REPL.LineEdit.MIState, ::Any, ::Vararg{Any})
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:2215
β [16] #invokelatest#2
β @ ./essentials.jl:716 [inlined]
β [17] invokelatest
β @ ./essentials.jl:714 [inlined]
β [18] (::REPL.LineEdit.var"#25#26"{REPL.LineEdit.var"#113#166", String})(s::Any, p::Any)
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:1466
β [19] prompt!(term::REPL.Terminals.TextTerminal, prompt::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:2586
β [20] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
β @ REPL.LineEdit /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:2488
β [21] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
β @ REPL /Applications/Julia-1.7.0.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/REPL.jl:1230
β [22] (::REPL.var"#49#54"{REPL.LineEditREPL, REPL.REPLBackendRef})()
β @ REPL ./task.jl:423
β @ REPL.LineEdit /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.7/REPL/src/LineEdit.jl:2588
julia>
SYSTEM: caught exception of type :ErrorException while trying to print a failed Task notice; giving up
ERROR: fatal: error thrown and no exception handler available.
ErrorException("Hi!")
error at ./error.jl:33
Pair at ./REPL[2]:1
display_error at ./client.jl:104
unknown function (ip: 0x1297f9448)
jl_apply_generic at /Applications/Julia-1.7.0.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.7.dylib (unknown line)
display_error at ./client.jl:107
unknown function (ip: 0x1297f9044)
jl_apply_generic at /Applications/Julia-1.7.0.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.7.dylib (unknown line)
jl_f__call_latest at /Applications/Julia-1.7.0.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.7.dylib (unknown line)
#invokelatest#2 at ./essentials.jl:716 [inlined]
invokelatest at ./essentials.jl:714 [inlined]
_start at ./client.jl:497
jfptr__start_28060.clone_1 at /Applications/Julia-1.7.0.app/Contents/Resources/julia/lib/julia/sys.dylib (unknown line)
jl_apply_generic at /Applications/Julia-1.7.0.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.7.dylib (unknown line)
true_main at /Applications/Julia-1.7.0.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.7.dylib (unknown line)
jl_repl_entrypoint at /Applications/Julia-1.7.0.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.7.dylib (unknown line)
This is either a Julia bug or extremely counterintuitive behavior.
Please file an issue - we should throw sensible errors instead of leaving users in the dark. See:
julia> 3 + 4
7
julia> a + b = error("Hi!")
ERROR: error in method definition: function Base.+ must be explicitly imported to be extended
Stacktrace:
[1] top-level scope
@ none:0
[2] top-level scope
@ REPL[5]:1
Right! Thanks. This is exactly the warning/error we should have. That (and its presumable fix in Julia) settles your unfortunate demo.
We still have the original questions, though.
Try this in a fresh Julia session:
julia> a + b = error("Hi!")
+ (generic function with 1 method)
In your case it fails only because you previously used +
from Base
in the same session. Thatβs how it works for all functions, to enable backward compatibility: if the user defines a function and a later version of Julia defines the same function in Base, the user code continues to work.
The error @stillyslalom produces with +
is great. We donβt want to accidentally pirate functions from other modules. The bug is that the error is lacking for constructors (e.g. =>
) so we end up accidentally redefining Base.=>
which breaks the REPL.