JuliaPhysics / JuliaPhysics/Unitful.jl

Unable to create `range` with `°C` unit

Open
#550 2 comments 0 reactions 0 assignees View on GitHub
affine ranges
Dominant language
Julia
Stars
675
Forks
124
Avg merge
3h 38m
Merged PRs (30d)
1

Description

I'm having issues creating a `range` defined with `°C` unit (and `K` for step unit). After trying different approaches, the only working solution was to directly create one using `StepRange` or `StepRangeLen` with explicit types. But then it still had an issue with printing.

Is there a better known approach for this? I may open up a PR for at least taking care of the printing issue for now.

1. `StepRange`
```
julia> (1:3)*u"°C"
ERROR: AffineError: an invalid operation was attempted with affine quantities: rem(2 K, 1 °C)
Stacktrace:
[1] _affineerror(::Function, ::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}, ::Vararg{Any})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:98
[2] rem(x::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}, y::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:115
[3] steprange_last
@ ./range.jl:346 [inlined]
[4] StepRange
@ ./range.jl:316 [inlined]
[5] StepRange
@ ./range.jl:369 [inlined]
[6] *(r::UnitRange{Int64}, y::Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/range.jl:141
[7] top-level scope
@ REPL[27]:1
```

2. `StepRangeLen`
```
julia> (1:1.0:3)*u"°C"
Error showing value of type StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64}:
ERROR: AffineError: an invalid operation was attempted with affine quantities: 1.0 °C*0
Stacktrace:
[1] *(x::Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, y::Int64)
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:34
[2] *(y::Int64, x::Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:32
[3] unsafe_getindex
@ ./twiceprecision.jl:500 [inlined]
[4] first(r::StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64})
@ Base ./range.jl:818
[5] show(io::IOContext{Base.TTY}, r::StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/display.jl:149
[6] show(io::IOContext{Base.TTY}, #unused#::MIME{Symbol("text/plain")}, r::StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64})
@ Base ./show.jl:11
[7] (::REPL.var"#43#44"{REPL.REPLDisplay{REPL.LineEditREPL}, MIME{Symbol("text/plain")}, Base.RefValue{Any}})(io::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:267
[8] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:521
[9] display(d::REPL.REPLDisplay, mime::MIME{Symbol("text/plain")}, x::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:260
[10] display(d::REPL.REPLDisplay, x::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:272
[11] display(x::Any)
@ Base.Multimedia ./multimedia.jl:328
[12] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[13] invokelatest
@ ./essentials.jl:726 [inlined]
[14] print_response(errio::IO, response::Any, show_value::Bool, have_color::Bool, specialdisplay::Union{Nothing, AbstractDisplay})
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:296
[15] (::REPL.var"#45#46"{REPL.LineEditREPL, Pair{Any, Bool}, Bool, Bool})(io::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:278
[16] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:521
[17] print_response(repl::REPL.AbstractREPL, response::Any, show_value::Bool, have_color::Bool)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:276
[18] (::REPL.var"#do_respond#66"{Bool, Bool, REPL.var"#77#87"{REPL.LineEditREPL, REPL.REPLHistoryProvider}, REPL.LineEditREPL, REPL.LineEdit.Prompt})(s::REPL.LineEdit.MIState, buf::Any, ok::Bool)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:857
[19] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[20] invokelatest
@ ./essentials.jl:726 [inlined]
[21] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
@ REPL.LineEdit /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/LineEdit.jl:2510
[22] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:1248
[23] (::REPL.var"#49#54"{REPL.LineEditREPL, REPL.REPLBackendRef})()
@ REPL ./task.jl:484
```

In this case, an instance of `StepRangeLen` is actually created, but cannot be printed, collected, etc.

```
julia> r = (1:1.0:3)*u"°C";

julia> typeof(r)
StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64}

julia> r
Error showing value of type StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64}:
ERROR: AffineError: an invalid operation was attempted with affine quantities: 1.0 °C*0
Stacktrace:
[1] *(x::Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, y::Int64)
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:34
[2] *(y::Int64, x::Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:32
[3] unsafe_getindex
@ ./twiceprecision.jl:500 [inlined]
[4] first(r::StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64})
@ Base ./range.jl:818
[5] show(io::IOContext{Base.TTY}, r::StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/display.jl:149
[6] show(io::IOContext{Base.TTY}, #unused#::MIME{Symbol("text/plain")}, r::StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64})
@ Base ./show.jl:11
[7] (::REPL.var"#43#44"{REPL.REPLDisplay{REPL.LineEditREPL}, MIME{Symbol("text/plain")}, Base.RefValue{Any}})(io::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:267
[8] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:521
[9] display(d::REPL.REPLDisplay, mime::MIME{Symbol("text/plain")}, x::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:260
[10] display(d::REPL.REPLDisplay, x::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:272
[11] display(x::Any)
@ Base.Multimedia ./multimedia.jl:328
[12] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[13] invokelatest
@ ./essentials.jl:726 [inlined]
[14] print_response(errio::IO, response::Any, show_value::Bool, have_color::Bool, specialdisplay::Union{Nothing, AbstractDisplay})
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:296
[15] (::REPL.var"#45#46"{REPL.LineEditREPL, Pair{Any, Bool}, Bool, Bool})(io::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:278
[16] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:521
[17] print_response(repl::REPL.AbstractREPL, response::Any, show_value::Bool, have_color::Bool)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:276
[18] (::REPL.var"#do_respond#66"{Bool, Bool, REPL.var"#77#87"{REPL.LineEditREPL, REPL.REPLHistoryProvider}, REPL.LineEditREPL, REPL.LineEdit.Prompt})(s::REPL.LineEdit.MIState, buf::Any, ok::Bool)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:857
[19] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[20] invokelatest
@ ./essentials.jl:726 [inlined]
[21] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
@ REPL.LineEdit /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/LineEdit.jl:2510
[22] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:1248
[23] (::REPL.var"#49#54"{REPL.LineEditREPL, REPL.REPLBackendRef})()
@ REPL ./task.jl:484

julia> collect(r)
ERROR: AffineError: an invalid operation was attempted with affine quantities: 1.0 °C*0
Stacktrace:
[1] *(x::Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, y::Int64)
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:34
[2] *(y::Int64, x::Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:32
[3] unsafe_getindex
@ ./twiceprecision.jl:500 [inlined]
[4] iterate
@ ./range.jl:876 [inlined]
[5] iterate
@ ./range.jl:874 [inlined]
[6] vcat
@ ./range.jl:1354 [inlined]
[7] collect(r::StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64})
@ Base ./range.jl:1362
[8] top-level scope
@ REPL[33]:1
```

3. `range()`
```
julia> range(1u"°C", step = 1u"K", length = 3)
ERROR: AffineError: an invalid operation was attempted with affine quantities: -5443//20 °C*2
Stacktrace:
[1] *(x::Quantity{Rational{Int64}, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, y::Int64)
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:34
[2] range_start_step_length(a::Quantity{Rational{Int64}, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, step::Quantity{Rational{Int64}, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, len::Int64)
@ Base ./range.jl:204
[3] _range(a::Quantity{Rational{Int64}, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, step::Quantity{Rational{Int64}, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, #unused#::Nothing, len::Int64)
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/range.jl:36
[4] _unitful_start_step_length(start::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, step::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}, len::Int64)
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/range.jl:54
[5] _range(a::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, step::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}, #unused#::Nothing, len::Int64)
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/range.jl:50
[6] range(start::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}; stop::Nothing, length::Int64, step::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}})
@ Base ./range.jl:138
[7] top-level scope
@ REPL[51]:1

julia> range(1.0u"°C", step = 1u"K", length = 3);

julia> range(1.0u"°C", step = 1u"K", length = 3)
Error showing value of type StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64}:
ERROR: AffineError: an invalid operation was attempted with affine quantities: -272.14999999999986 °C*0
Stacktrace:
[1] *(x::Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, y::Int64)
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:34
[2] *(y::Int64, x::Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:32
[3] unsafe_getindex
@ ./twiceprecision.jl:500 [inlined]
[4] first(r::StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64})
@ Base ./range.jl:818
[5] show(io::IOContext{Base.TTY}, r::StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/display.jl:149
[6] show(io::IOContext{Base.TTY}, #unused#::MIME{Symbol("text/plain")}, r::StepRangeLen{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Base.TwicePrecision{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}, Int64})
@ Base ./show.jl:11
[7] (::REPL.var"#43#44"{REPL.REPLDisplay{REPL.LineEditREPL}, MIME{Symbol("text/plain")}, Base.RefValue{Any}})(io::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:267
[8] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:521
[9] display(d::REPL.REPLDisplay, mime::MIME{Symbol("text/plain")}, x::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:260
[10] display(d::REPL.REPLDisplay, x::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:272
[11] display(x::Any)
@ Base.Multimedia ./multimedia.jl:328
[12] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[13] invokelatest
@ ./essentials.jl:726 [inlined]
[14] print_response(errio::IO, response::Any, show_value::Bool, have_color::Bool, specialdisplay::Union{Nothing, AbstractDisplay})
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:296
[15] (::REPL.var"#45#46"{REPL.LineEditREPL, Pair{Any, Bool}, Bool, Bool})(io::Any)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:278
[16] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:521
[17] print_response(repl::REPL.AbstractREPL, response::Any, show_value::Bool, have_color::Bool)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:276
[18] (::REPL.var"#do_respond#66"{Bool, Bool, REPL.var"#77#87"{REPL.LineEditREPL, REPL.REPLHistoryProvider}, REPL.LineEditREPL, REPL.LineEdit.Prompt})(s::REPL.LineEdit.MIState, buf::Any, ok::Bool)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:857
[19] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[20] invokelatest
@ ./essentials.jl:726 [inlined]
[21] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
@ REPL.LineEdit /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/LineEdit.jl:2510
[22] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
@ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:1248
[23] (::REPL.var"#49#54"{REPL.LineEditREPL, REPL.REPLBackendRef})()
@ REPL ./task.jl:484
```

4. Direct Instantiation
```
julia> StepRangeLen(1u"°C", 1u"K", 3, 1)
(5483//20:1:5523//20) K
```

Above works in a way, but the final unit is fixed to K, not °C.

```
julia> U = typeof(1u"°C"); S = typeof(1u"K");

julia> r2 = StepRangeLen{U,U,S}(1u"°C", 1u"K", 3, 1)
(1//1:-5443//20:-5433//10) °C

julia> r2 |> collect
3-element Vector{Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}:
1 °C
2 °C
3 °C
```

This now works as intended, but printing is incorrect. The following example is more easy to see what happens when two units are mixed.

```
julia> U2 = typeof(1.0u"°C"); S = typeof(1u"K");

julia> r3 = StepRangeLen{U2,U2,S}(1.0u"°C", 1u"K", 3, 1)
(1.0:-272.15:-543.3) °C
```

It is rather supposed to be `(1.0:1.0:3.0) °C`. `collect()` still works fine though. It's more like a printing issue.

```
julia> r3 |> collect
3-element Vector{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}:
1.0 °C
2.0 °C
3.0 °C
```

The same goes for the case of `StepRange`.

```
julia> StepRange(1u"°C", 1u"°C", 3u"°C")
ERROR: AffineError: an invalid operation was attempted with affine quantities: rem(2 K, 1 °C)
Stacktrace:
[1] _affineerror(::Function, ::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}, ::Vararg{Any})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:98
[2] rem(x::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}, y::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:115
[3] steprange_last
@ ./range.jl:346 [inlined]
[4] StepRange
@ ./range.jl:316 [inlined]
[5] StepRange(start::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, step::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, stop::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Base ./range.jl:369
[6] top-level scope
@ REPL[46]:1

julia> StepRange(1u"°C", 1u"K", 3u"°C")
(1//1:-5443//20:3//1) °C

julia> StepRange(1u"°C", 1u"K", 3u"°C") |> collect
3-element Vector{Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}:
1 °C
2 °C
3 °C

julia> StepRange(1u"°C", 1.0u"K", 3u"°C")
(1.0:-272.15:273.15) °C

julia> StepRange(1u"°C", 1.0u"K", 3u"°C") |> collect
3-element Vector{Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}}:
1 °C
2 °C
3 °C
```

5. Alternative Syntax
```
julia> 1u"°C":10u"°C"
ERROR: AffineError: no multiplicative identity for affine quantity 1 °C.
Stacktrace:
[1] one(x::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:416
[2] (::Colon)(start::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, stop::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/range.jl:131
[3] top-level scope
@ REPL[5]:1

julia> 1u"°C":1u"°C":10u"°C"
ERROR: AffineError: an invalid operation was attempted with affine quantities: rem(9 K, 1 °C)
Stacktrace:
[1] _affineerror(::Function, ::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}, ::Vararg{Any})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:98
[2] rem(x::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}, y::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/quantities.jl:115
[3] steprange_last
@ ./range.jl:346 [inlined]
[4] StepRange
@ ./range.jl:316 [inlined]
[5] StepRange
@ ./range.jl:369 [inlined]
[6] _colon
@ ~/.julia/packages/Unitful/SUQzL/src/range.jl:108 [inlined]
[7] (::Colon)(start::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, step::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}}, stop::Quantity{Int64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}})
@ Unitful ~/.julia/packages/Unitful/SUQzL/src/range.jl:106
[8] top-level scope
@ REPL[14]:1

julia> 1u"°C":1u"K":10u"°C"
(5483//20:5663//20) K

julia> 1u"°C":1.0u"K":10u"°C"
(274.15:1.0:283.15) K
```

~None of them works and this is more likely a limitation of Julia parser.~
Range notations with `:` only work when step values are explicitly provided in `K` unit, but then they always result into `K` even start/stop values are `°C`.

Contributor guide

No contributing guide indexed for this repository

Research direction

Reproduce the °C range cases and start by reading src/range.jl, src/quantities.jl, and src/display.jl, especially the paths shown in the stack traces. Determine the intended behavior for creating, printing, and collecting StepRange and StepRangeLen values with affine quantities, then verify that these operations no longer raise AffineError.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.