tecosaur / about.jl Goto Github PK
View Code? Open in Web Editor NEWMirror of https://code.tecosaur.net/tec/About.jl
License: Mozilla Public License 2.0
Mirror of https://code.tecosaur.net/tec/About.jl
License: Mozilla Public License 2.0
The following gives an error with About v0.1.0
on Julia 1.11.0-beta1
julia> Returns(3) |> about
ERROR: "Returns{Int64}(3)" is not defined in module Base
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] which
@ ./reflection.jl:2237 [inlined]
[3] about(io::Base.TTY, fn::Function)
@ About ~/.julia/packages/About/wwaGm/src/functions.jl:2
[4] about(x::Function)
@ About ~/.julia/packages/About/wwaGm/src/About.jl:28
[5] |>(x::Function, f::typeof(about))
@ Base ./operators.jl:926
[6] top-level scope
@ REPL[8]:1
Any reason this isn't registered in General yet?
julia> about(Vector)
UnionAllERROR: type UnionAll has no field name
Stacktrace:
[1] getproperty
@ ./Base.jl:43 [inlined]
[2] about(io::Base.TTY, type::Type)
@ About ~/.julia/packages/About/XPN7V/src/types.jl:48
[3] about(x::Type)
@ About ~/.julia/packages/About/XPN7V/src/About.jl:24
[4] top-level scope
@ REPL[12]:1
I had been hoping it would tell me what type parameters it had and what restrictions are on them.
We have code that does something like that in
https://github.com/invenia/ExprTools.jl/blob/bcc7765a177f39363dfcc9d9310c97ca26530a78/src/method.jl#L163-L174
The illustrations of floating point numbers are amazing but some of the shown arithmetic doesn't make sense.
julia> about(0.0)
Float64 (<: AbstractFloat <: Real <: Number <: Any), occupies 8B.
0000000000000000000000000000000000000000000000000000000000000000
╨└────┬────┘└────────────────────────┬─────────────────────────┘
+ 2^-1023 × 1.000000000000000000
= 0.0000000000000000e+00
0000000000000000000000000000000000000000000000000000000000000001
╨└────┬────┘└────────────────────────┬─────────────────────────┘
+ 2^-1023 × 1.000000000000000222
= 4.9406564584124654e-324
With an all zeros exponent, the mantissa doesn't have a hidden leading one bit and the exponent value stays at the smallest normal exponent, so it would make more sense to explain these as
+ 2^-1022 × 0
and + 2^-1022 × 0.000000000000000222
respectively.
Note also that Float32
and Float16
behave differently and are off on the zero exponent.
julia> about(0.0f0)
Float32 (<: AbstractFloat <: Real <: Number <: Any), occupies 4B.
00000000000000000000000000000000
╨└──┬───┘└──────────┬──────────┘
+2^-1023× 1.000000000
= 0.0000000e+00
julia> about(nextfloat(0.0f0))
Float32 (<: AbstractFloat <: Real <: Number <: Any), occupies 4B.
00000000000000000000000000000001
╨└──┬───┘└──────────┬──────────┘
+ 2^-149× 1.000000000
= 1.4012985e-45
julia> using About
julia> using SparseArrays
julia> about(spzeros(5, 5))
5×5 SparseMatrixCSC{Float64, Int64} with 0 stored entries (<: SparseArrays.AbstractSparseMatrixCSC{Float64, Int64} <: AbstractSparseMatrix{Float64, Int64} <: AbstractMatrix{Float64} <: Any), occupies 40B directly (referencing 208B in total)
ERROR: Type Array does not have a definite size.
Stacktrace:
[1] sizeof(x::Type)
@ Base .\essentials.jl:631
[2] (::About.var"#11#12"{DataType})(i::Int64)
@ About C:\Users\pkonl\VSCode_Julia_portable\assets\.julia-1.10.4-depot\packages\About\52iMk\src\types.jl:22
[3] iterate
@ .\generator.jl:47 [inlined]
[4] collect_to!
@ .\array.jl:892 [inlined]
[5] collect_to_with_first!
@ .\array.jl:870 [inlined]
[6] _collect(c::UnitRange{…}, itr::Base.Generator{…}, ::Base.EltypeUnknown, isz::Base.HasShape{…})
@ Base .\array.jl:864
[7] collect_similar
@ .\array.jl:763 [inlined]
[8] map
@ .\abstractarray.jl:3285 [inlined]
[9] structinfo
@ C:\Users\pkonl\VSCode_Julia_portable\assets\.julia-1.10.4-depot\packages\About\52iMk\src\types.jl:13 [inlined]
[10] memorylayout(io::Base.TTY, value::SparseMatrixCSC{Float64, Int64})
@ About C:\Users\pkonl\VSCode_Julia_portable\assets\.julia-1.10.4-depot\packages\About\52iMk\src\values.jl:63
[11] about(io::Base.TTY, value::SparseMatrixCSC{Float64, Int64})
@ About C:\Users\pkonl\VSCode_Julia_portable\assets\.julia-1.10.4-depot\packages\About\52iMk\src\values.jl:43
[12] about(x::SparseMatrixCSC{Float64, Int64})
@ About C:\Users\pkonl\VSCode_Julia_portable\assets\.julia-1.10.4-depot\packages\About\52iMk\src\About.jl:201
[13] top-level scope
@ REPL[4]:1
Some type information was truncated. Use `show(err)` to see complete types.
julia>
so here it is 😄
Hey there, thanks for this excellent package!
Do you plan on supporting uninitialized struct
s ? I'm thinking specifically of the non-isbits
ones, which can contain #undef
values such as :
julia> about(Ref{String}())
Base.RefValue{String} (mutable) (<: Ref{String} <: Any), occupies 8B.
ERROR: UndefRefError: access to undefined reference
Stacktrace:
[1] memorylayout(io::Base.TTY, value::Base.RefValue{String})
@ About ~/.julia/packages/About/52iMk/src/values.jl:78
[2] about(io::Base.TTY, value::Base.RefValue{String})
@ About ~/.julia/packages/About/52iMk/src/values.jl:43
[3] about(x::Base.RefValue{String})
@ About ~/.julia/packages/About/52iMk/src/About.jl:201
[4] top-level scope
@ REPL[12]:1
Similarly, for Memory
:
julia> about(Memory{Any}(undef, 3))
3-element Memory{Any} (mutable) (<: DenseVector{Any} <: AbstractVector{Any} <: Any)
Memory footprint: 24B directly (referencing 40B in total)
ERROR: Abstract type Any does not have a definite size.
Stacktrace:
[1] sizeof(x::Type)
@ Base ./essentials.jl:768
[2] memorylayout(io::Base.TTY, mem::Memory{Any})
@ About ~/.julia/packages/About/52iMk/src/values.jl:385
[3] about(io::Base.TTY, value::Memory{Any})
@ About ~/.julia/packages/About/52iMk/src/values.jl:43
[4] about(x::Memory{Any})
@ About ~/.julia/packages/About/52iMk/src/About.jl:201
[5] top-level scope
@ REPL[10]:1
Currently, about
seems to be defined for strings, but isn't able to compute the memory layout.
julia> str = "Hello, I am writing some text."
"Hello, I am wrinting some text."
julia> about(str)
51-codeunit String (mutable), 51B referencing 59B (<: AbstractString <: Any)
ERROR: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
Stacktrace:
[1] _empty_reduce_error()
@ Base ./reduce.jl:319
[2] mapreduce_empty(f::Function, op::Function, T::Type)
@ Base ./reduce.jl:321
[...]
[10] maximum
@ ./reducedim.jl:981 [inlined]
[11] memorylayout(io::Base.TTY, value::String)
@ About ~/.julia/packages/About/XPN7V/src/values.jl:60
[12] about(io::Base.TTY, value::String)
@ About ~/.julia/packages/About/XPN7V/src/values.jl:18
[13] about(x::String)
@ About ~/.julia/packages/About/XPN7V/src/About.jl:24
[14] top-level scope
@ REPL[13]:1
On About v0.1.0
, julia 1.11
.
Lines 454 and 455 of values.jl
in src holds what seems to be two extraneous end
keywords.
This causes About.jl to fail during precompilation on julia 1.12
Removing these fixes the problem.
Definitely helps attract eyeballs and help people decide if this is the package they're looking for.
julia> about(-1)
Int64, 8B (<: Signed <: Integer <: Real <: Number <: Any)
1111111111111111111111111111111111111111111111111111111111111111
= --1
Calling about
on a module with an undefined exported name results in an exception.
julia> module Temp
export notdefined
end
Main.Temp
julia> about(Temp)
Module Main.Temp
ERROR: UndefVarError: `notdefined` not defined
Stacktrace:
[1] (::About.var"#classify#24"{Module})(m::Module, name::Symbol)
@ About ~/.julia/packages/About/52iMk/src/values.jl:136
[...]
Version info:
Julia Version 1.10.4
Commit 48d4fd48430 (2024-06-04 10:41 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 32 × 13th Gen Intel(R) Core(TM) i9-13900KF
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-15.0.7 (ORCJIT, goldmont)
Threads: 32 default, 0 interactive, 16 GC (on 32 virtual cores)
Environment:
JULIA_NUM_THREADS = auto
JULIA_EDITOR = code
I've tried out About.jl on my package LinearCombinations.jl. The output of about(LinearCombinations)
contains the lines
Re-exports 1 name (from Core):
• swap
The package does indeed export swap
. However, as far as I can tell, there is no Core.swap
. Is this a bug?
I'm using About v1.0.0, LinearCombinations v0.4.1, Julia v1.10.4.
Awesome package!! For SpeedyWeather.jl I recently implemented the tree
function, which is similar to dump, but stays within a specified module by checking parentmodule
. Otherwise you ending with base/stdlib Julia types that aren't necessarily of interest if you want to understand what a struct defined in a given package contains. I also found it super useful to print the size of objects with Base.summarysize
, e.g. here.
Maybe it's helpful for this package or if this package starts to implement this functionality I'd be happy to piggy back on it.
(originally implemented here SpeedyWeather/SpeedyWeather.jl#492 and here SpeedyWeather/SpeedyWeather.jl#495)
Compatibility is restricted to InteractiveUtils 1.11
and therefore Julia 1.11. Is there a reason for this?
Great job on this package!
If I can make a suggestion, here's a screenshot you shared on Slack:
When consistent
has a X
next to it, I can mentally parse it as not consistent
- consistent - might not return or terminate consistently
- terminates - guaranteed to always terminate
Should it should be the same for no undefined behaviour
? When there's a X
next to no undefined behaviour
, I'm reading this as no no undefined behaviour
.
- no undefined behaviour - may execute undefined behaviour
Is there alternative naming that would help? Maybe safe
instead of no undefined
? It would read like so:
- safe behaviour - may execute undefined behaviour
I believe you are choosing the property name to always remain the same across different invocations of this function, and checkbox and the description change based on the value of the property. Is there a way to make that more obvious? Perhaps the checkbox and description should be closer to each other? The checkbox in the middle of the property and the description? Color the description the same as the checkbox but leave the property names gray in color? fwiw, red and green are not so great for people with red green color blindness.
I like that you've chosen formatting and colors that are copy paste friendly, and would like to preserve that feature. I'm just wondering about more effective ways to communicate the same information.
julia> about(Memory{Int})
Concrete (padded) DataTypeERROR: Type GenericMemory does not have a definite size.
[...]
julia> about(Memory{Int}(undef, 0))
0-element Memory{Int64} (mutable), 0B referencing 16B (<: DenseVector{Int64} <: AbstractVector{Int64} <: Any)
ERROR: Type GenericMemory does not have a definite size.
[...]
Memory
has a specific display which is great for isbits
types:
julia> about(Memory{Int8}(undef, 7))
7-element Memory{Int8} (mutable) (<: DenseVector{Int8} <: AbstractVector{Int8} <: Any)
Memory footprint: 7B directly (referencing 23B in total)
Memory block (CPU-addressed) from 0x00007fa94ea01ba0 to 0x00007fa94ea01ba7.
┌─╴97╶─┐┌╴110╶─┐┌╴100╶─┐┌─╴0╶──┐┌─╴0╶──┐┌─╴0╶──┐┌─╴0╶──┐ 7 items
01100001011011100110010000000000000000000000000000000000 in
└─0x61─┘└─0x6e─┘└─0x64─┘└─0x00─┘└─0x00─┘└─0x00─┘└─0x00─┘ 7 bytes
However it errors on non-isbits
types:
julia> about(Memory{String}(["foo", "bar"]))
2-element Memory{String} (mutable) (<: DenseVector{String} <: AbstractVector{String} <: Any)
Memory footprint: 16B directly (referencing 54B in total)
ERROR: Type String does not have a definite size.
Stacktrace:
[1] sizeof(x::Type)
@ Base ./essentials.jl:768
[2] memorylayout(io::Base.TTY, mem::Memory{String})
@ About ~/.julia/packages/About/52iMk/src/values.jl:385
[3] about(io::Base.TTY, value::Memory{String})
@ About ~/.julia/packages/About/52iMk/src/values.jl:43
[4] about(x::Memory{String})
@ About ~/.julia/packages/About/52iMk/src/About.jl:201
[5] top-level scope
@ REPL[36]:1
I noticed that while writing #19, but it is an independent issue since the error occurs even on well-defined data.
julia> x = Base.infer_effects(round, Tuple{Type{Float64}, Int})
(+c,+e,+n,+t,+s,+m,+u)
julia> x.nothrow
true
julia> about(x)
Method effects:
✔ consistent guaranteed to return or terminate consistently
✔ effect free guaranteed to be free from externally semantically visible side effects
✔ no throw may throw an exception # Nope! It's "will not throw an exception".
✔ terminates might not always terminate
✔ no task state may access task state (preventing migration between tasks)
✔ inaccessible memory only guaranteed to never access or modify externally accessible mutable memory
✔ no undefined behaviour guaranteed to never execute undefined behaviour
✔ non-overlayed never calls any methods from an overlayed method table
I wonder if here about
should treat cos ∘ sin
as a function or as a struct or as some combination thereof 😅
julia> about(cos ∘ sin)
ERROR: "cos ∘ sin" is not defined in module Base
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] which
@ ./reflection.jl:2246 [inlined]
[3] about(io::Base.TTY, fn::Function)
@ About ~/About.jl/src/functions.jl:2
[4] about(x::Function)
@ About ~/About.jl/src/About.jl:24
[5] top-level scope
@ REPL[27]:1
For example the GMTgrid
using GMT
G = peaks();
about(G)
49×49 GMTgrid{Float32, 2} (mutable) (<: AbstractMatrix{Float32} <: Any), occupies 232B directly (referencing 11kB in total)
ERROR: Type Array does not have a definite size.
Stacktrace:
[1] sizeof(x::Type)
@ Base .\essentials.jl:631
[2] (::About.var"#11#12"{DataType})(i::Int64)
@ About C:\Users\j\.julia\packages\About\52iMk\src\types.jl:22
...
Currently, calling about(somestruct)
is broken for fields that are functions:
julia> struct Foo
a::Int
b::Matrix{Float32}
c::typeof(identity)
end
julia> f = Foo(1, rand(3, 4), identity)
Foo(1, Float32[0.8633268 0.40085334 0.27201754 0.60436267; 0.34008977 0.2632495 0.82902575 0.6264377; 0.32734197 0.008732563 0.8294697 0.10690562], identity)
julia> about(f)
Foo, 16B referencing 128B (<: Any)
a::Int64 8B 000000000000000000000000 … 00000000000000000000001 1
b::Matrix{Float32} 8B Ptr{Float32} @0x000000010cbac5c0 Float32[0.8 … 7 0.106906]
c::typeof(identity) 0B Ptr? identity
ERROR: InexactError: Int64(NaN)
Stacktrace:
[1] Int64
@ ./float.jl:981 [inlined]
[2] convert
@ ./number.jl:7 [inlined]
[3] round
@ ./rounding.jl:469 [inlined]
[4] round
@ ./rounding.jl:467 [inlined]
[5] memorylayout(io::Base.TTY, type::DataType)
@ About ~/.julia/packages/About/9q1TE/src/types.jl:102
[6] memorylayout(io::Base.TTY, value::Foo)
@ About ~/.julia/packages/About/9q1TE/src/values.jl:72
[7] about(io::Base.TTY, value::Foo)
@ About ~/.julia/packages/About/9q1TE/src/values.jl:18
[8] about(x::Foo)
@ About ~/.julia/packages/About/9q1TE/src/About.jl:24
[9] top-level scope
@ REPL[12]:1
It seems that the issue is that functions have a "size" of zero.
julia> About.structinfo(typeof(f))
3-element Vector{About.FieldInfo}:
About.FieldInfo(1, :bright_green, 0, 8, 8, false, :a, Int64)
About.FieldInfo(2, :bright_yellow, 8, 8, 0, true, :b, Matrix{Float32})
About.FieldInfo(3, :bright_magenta, 16, 0, 0, true, :c, typeof(identity))
Julia 1.10
julia> about(1)
Int64 (<: Signed <: Integer <: Real <: Number <: Any), occupies 8B.
0000000000000000000000000000000000000000000000000000000000000001
= +1
julia> about(2)
Int64 (<: Signed <: Integer <: Real <: Number <: Any), occupies 8B.
ERROR: MethodError: no method matching face!(::SubString{String}, ::Symbol)
Closest candidates are:
face!(::Union{StyledStrings.AnnotatedStrings.AnnotatedString, SubString{<:StyledStrings.AnnotatedStrings.AnnotatedString}}, ::Union{Symbol, StyledStrings.Face, Vector{<:Union{Symbol, StyledStrings.Face}}})
@ StyledStrings ~/.julia/packages/StyledStrings/4f63t/src/faces.jl:607
Stacktrace:
[1] memorylayout(io::Base.TTY, value::Int64)
@ About ~/.julia/packages/About/Y5VLD/src/values.jl:231
[2] about(io::Base.TTY, value::Int64)
@ About ~/.julia/packages/About/Y5VLD/src/values.jl:43
[3] about(x::Int64)
@ About ~/.julia/packages/About/Y5VLD/src/About.jl:76
[4] top-level scope
@ REPL[15]:1
On Julia 1.10 an exception occurs when using About on BigInt values.
julia> about(BigInt(1))
BigInt (mutable) (<: Signed <: Integer <: Real <: Number <: Any), occupies 16B directly (referencing 24B in total)
alloc::Int32 4B 000000 … 00001 1
size::Int32 4B 000000 … 00001 1
ERROR: MethodError: no method matching face!(::String, ::Symbol)
Closest candidates are:
face!(::Union{StyledStrings.AnnotatedStrings.AnnotatedString, SubString{<:StyledStrings.AnnotatedStrings.AnnotatedString}}, ::Union{Symbol, StyledStrings.Face, Vector{<:Union{Symbol, StyledStrings.Face}}})
@ StyledStrings ~/.julia/packages/StyledStrings/rd5VN/src/faces.jl:622
Stacktrace:
[1] memorylayout(io::Base.TTY, value::BigInt)
@ About ~/.julia/packages/About/52iMk/src/values.jl:106
[2] about(io::Base.TTY, value::BigInt)
@ About ~/.julia/packages/About/52iMk/src/values.jl:43
[...]
Version info:
Julia Version 1.10.4
Commit 48d4fd48430 (2024-06-04 10:41 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 32 × 13th Gen Intel(R) Core(TM) i9-13900KF
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-15.0.7 (ORCJIT, goldmont)
Threads: 32 default, 0 interactive, 16 GC (on 32 virtual cores)
Environment:
JULIA_NUM_THREADS = auto
JULIA_EDITOR = code
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.