# \[ANN\] About.jl

**URL:** https://discourse.julialang.org/t/ann-about-jl/118547
**Category:** Package Announcements
**Tags:** package, announcement
**Created:** [August 24, 2024, 3:03am UTC](https://discourse.julialang.org/t/ann-about-jl/118547 "2024-08-24T03:03:54Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [August 24, 2024, 3:03am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/1 "2024-08-24T03:03:54Z")

</div>

# [About.jl](https://github.com/tecosaur/About.jl)

I’d like to announce a package that I’ve been tinkering on for the past few months. It’s a response to frequently wanting to know more _about_ the structure or nature of objects in Julia, whether that be:

- How a `struct` is represented in-memory
- How large an object is
- How the bits of a number relate to its value
- What the compiler knows about a function
- and more.

The **About** package exports a single function `about`, that tells you _about_ any object you pass to it. This makes heavy use of **StyledStrings** and **JuliaSyntaxHighlighting** to produce (what I consider to be) pretty outputs designed for human consumption (as opposed to the functions like `fieldoffset` that aren’t terribly informative at a glance).

The use of StyledStrings also makes the formatting used customisable, in that you can configure elements of the styling through the file `~/.julia/config/faces.toml` (see: [StyledStrings · Styled Strings](https://julialang.github.io/StyledStrings.jl/dev/#stdlib-styledstrings-face-toml)).

It’s designed to be easily extendable by packages, which I invite to (when sensible) create package extensions that implement specialised `memorylayout` and `elaboration` methods 🙂

There’s a bit more I’d like it to do in due course, but I’m pretty happy with what it does now.

# Sample screenshots

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/6/16b16547829da8655032382ffeaf4c82a8d18b2f.png)

 ![image](https://global.discourse-cdn.com/julialang/original/3X/8/3/832a2a97a3dcd27f6fa4967218c2a3bc65625107.png)

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/7/d7df58ff747a5c11c48f245196e694a4367cfe4d.png)

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/3/033e60f001f4c82582014f6a080ea0cc50825d47.png)

 ![image](https://global.discourse-cdn.com/julialang/original/3X/f/5/f5f284d1374e74d0eac1302de53af41c28a58c3d.png)

Take it for a spin —the module and function(s) all have decent docstrings— and let me know if you’ve got any ideas 😀

---

<div class="post-metadata">

### Author: ![hz-xiaxz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hz-xiaxz/32/209585_2.png) [@hz-xiaxz](https://discourse.julialang.org/u/hz-xiaxz)
#### Post date: [August 24, 2024, 7:09am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/3 "2024-08-24T07:09:17Z")

</div>

This package is fantastic! I’m wondering if it’s positioned as a superior replacement and enhancement for Julia REPL’s built-in `help?>` .

---

<div class="post-metadata">

### Author: ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)
#### Post date: [August 26, 2024, 3:46pm UTC](https://discourse.julialang.org/t/ann-about-jl/118547/4 "2024-08-26T15:46:59Z")

</div>

This is great, I’ll be using it all the time! I was briefly a bit confused when trying to compare the outputs of `sum([1,2,3])` and `sum((1,2,3))`. If you want to about the tuple version, it seems you need to write:

```julia
about(sum, Tuple{Tuple{Int64, Int64, Int64}})

```

or you’ll get the (nonexistant) information for `sum(1,2,3)`.

---

<div class="post-metadata">

### Author: ![bremez](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bremez/32/38777_2.png) [@bremez](https://discourse.julialang.org/u/bremez)
#### Post date: [August 26, 2024, 4:40pm UTC](https://discourse.julialang.org/t/ann-about-jl/118547/5 "2024-08-26T16:40:59Z")

</div>

This looks great! Perhaps it would be appropriate for it to implement a hotkey similar to `]`, `?`, and `;` for quick access?

---

<div class="post-metadata">

### Author: ![jbytecode](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbytecode/32/17719_2.png) [@jbytecode](https://discourse.julialang.org/u/jbytecode)
#### Post date: [August 26, 2024, 7:14pm UTC](https://discourse.julialang.org/t/ann-about-jl/118547/6 "2024-08-26T19:14:09Z")

</div>

Looks great! Thank you for doing this! Just promoted:

[Twitter](https://x.com/mhsatman/status/1828145763593134183)

[mastodon](https://fosstodon.org/@mhsatman/113029863835443773)

---

<div class="post-metadata">

### Author: ![visr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/visr/32/17204_2.png) [@visr](https://discourse.julialang.org/u/visr)
#### Post date: [August 26, 2024, 8:55pm UTC](https://discourse.julialang.org/t/ann-about-jl/118547/7 "2024-08-26T20:55:45Z")

</div>

I agree it looks fantastic. Though I think About.jl’s MPL-2.0 license would make it difficult to be adopted like that. Don’t want to derail this thread though, this was discussed recently in a different thread, specifically this post addresses adoption:

> [@Package licenses: Contemplations and considerations](https://discourse.julialang.org/t/package-licenses-contemplations-and-considerations/117922/14):
>
> I’ve probably thought more about open source licensing than most people. You can certainly try non-MIT licenses if you want, but there is dangers to engaging in license innovations. Everybody knows what the industry consensus is on how MIT works (which may or may not match what the licenses says exactly, but there is some legal relevance to the common understanding also) and that makes it easy for people to use, contribute to, etc. The key thing I would say is that you have to be clear in your m…

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [August 27, 2024, 12:38am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/8 "2024-08-27T00:38:33Z")

</div>

> [@hz-xiaxz](#):
>
> This package is fantastic! I’m wondering if it’s positioned as a superior replacement and enhancement for Julia REPL’s built-in `help?>` .

Not really, `help?>` is all about docstrings, and this is more about introspection.

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [August 27, 2024, 12:42am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/9 "2024-08-27T00:42:13Z")

</div>

> [@JonasWickman](#):
>
> This is great, I’ll be using it all the time! I was briefly a bit confused when trying to compare the outputs of `sum([1,2,3])` and `sum((1,2,3))`. If you want to about the tuple version, it seems you need to write:
> 
> ```julia
> about(sum, Tuple{Tuple{Int64, Int64, Int64}})
> 
> ```
> 
> or you’ll get the (nonexistant) information for `sum(1,2,3)`.

This is a little tricky, this seems annoying but I wrote this so it could also be used with the same signature as functions like `methods` and `return_types` in `Base`, as well as the “more convenient” form I demonstrated above.

Hmmm, I’m not sure what would be best to do here.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [August 27, 2024, 6:40am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/10 "2024-08-27T06:40:55Z")

</div>

> [@tecosaur](#):
>
> Hmmm, I’m not sure what would be best to do here.

Could you do

```julia
@about sum((1, 2, 3))

```

?

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [August 27, 2024, 6:45am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/11 "2024-08-27T06:45:23Z")

</div>

Possibly, I’ve been thinking of adding an `@about` macro for fun, but the main roadblock is resolving whether an `@about <func call>` invocation should give information on the function called, or the result.

Thinking of cases like `@about Float16(1.234)` makes this harder to me.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [August 27, 2024, 6:47am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/12 "2024-08-27T06:47:19Z")

</div>

> [@tecosaur](#):
>
> ```julia
> @about Float16(1.234)
> 
> ```

My first instinct is that the above should report on the function called, and

```julia
about(Float16(1.234))

```

should handle the result.

---

<div class="post-metadata">

### Author: ![screw\_dog](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/screw_dog/32/48119_2.png) [@screw\_dog](https://discourse.julialang.org/u/screw_dog)
#### Post date: [August 27, 2024, 7:56am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/13 "2024-08-27T07:56:27Z")

</div>

Really loving this, thank you very much!

Have just filed a couple of issues… 😸

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [August 27, 2024, 8:54am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/14 "2024-08-27T08:54:20Z")

</div>

To everyone filing issues and PRs, they’re much appreciated 😍.

It’s great to see people taking me up on the request to help me make About.jl even more useful (and less buggy 😝).

I might take a bit to get around to them though, I’m in a rather busy spell currently.

---

<div class="post-metadata">

### Author: ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)
#### Post date: [August 27, 2024, 9:19am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/15 "2024-08-27T09:19:30Z")

</div>

Very nice idea and UI!

Unfortunately this seems to fail when it is most needed, i.e. when datatypes have nontrivial (non C-compatible) layout.

This is especially unfortunate since, to my knowledge, the beyond-C layout rules in julialang are not documented, and there is no built-in introspection facility. Can someone from the core team correct me if I’m wrong on that?

Two examples on 1.10.4:

```julia
julia> using About
julia> mutable struct UnionTags
       x::Union{Int,UInt}
       end
julia> about(UnionTags(1))
UnionTags (mutable) (<: Any), occupies 16B directly (referencing 24B in total)
 x::Union{Int64, UInt6… 16B Ptr? 1

 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                                   *                                   

 * = Pointer (8B)
julia> mutable struct AtomicHiddenLock
       @atomic x::Tuple{Int,Int,Int}
       end
julia> about(AtomicHiddenLock((1,2,3)))
AtomicHiddenLock (mutable) (<: Any), occupies 40B.
 x::Tuple{Int64, Int64… 24B «struct» (1, 2, 3)

 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                    24B      

```

The desired behavior should be to exhibit the true memory layout that is otherwise hard to figure out. This includes:

- For every piece of information, we want to know where it is stored (“data of field X is here; a union-tag for X is there; a hidden implicit lock protecting protecting field xyz there”)
- For every byte in the memory layout, we want to know where it belongs to (e.g. “structure padding”, “hidden implicit lock for field xyz”, “small-union-tag”)
- If we can’t figure that out, it would be nice to have sanity checks. Then one can at least print a warning that the layout is likely imprecise.

(ceterum censeo, hidden locks for atomics suck – if it’s too large for `lock cmpxchg16b` then it should be boxed!)

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [August 27, 2024, 1:50pm UTC](https://discourse.julialang.org/t/ann-about-jl/118547/16 "2024-08-27T13:50:40Z")

</div>

> [@foobar\_lv2](#):
>
> Unfortunately this seems to fail when it is most needed, i.e. when datatypes have nontrivial (non C-compatible) layout.

This is a consequence of what I get out of the introspection tools available

```julia-repl
# Julia 1.10.4
julia> mutable struct UnionTags
       x::Union{Int,UInt}
       end

julia> u = UnionTags(1)
UnionTags(1)

julia> Base.summarysize(u)
24

julia> sizeof(u)
16

```

> [@foobar\_lv2](#):
>
> The desired behavior should be to exhibit the true memory layout that is otherwise hard to figure out. This includes:
> 
> - For every piece of information, we want to know where it is stored (“data of field X is here; a union-tag for X is there; a hidden implicit lock protecting protecting field xyz there”)
> - For every byte in the memory layout, we want to know where it belongs to (e.g. “structure padding”, “hidden implicit lock for field xyz”, “small-union-tag”)
> - If we can’t figure that out, it would be nice to have sanity checks. Then one can at least print a warning that the layout is likely imprecise.

That would be great! If somebody would be willing to help implement this, or just work out how this can be determined within About I’d be thrilled.

---

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [August 27, 2024, 8:09pm UTC](https://discourse.julialang.org/t/ann-about-jl/118547/17 "2024-08-27T20:09:53Z")

</div>

This looks really good. It would be nice if some api existed to extract information instead of having it printed to the standard output.

At the moment I use this function to collect the number of bytes used by a reasonably complex data structure:

```julia
function allbytes(a)
    T = typeof(a)
    return if isbitstype(T)
        sizeof(a)
    else
        return if fieldcount(T) == 0
            if length(a) > 0
                sum(allbytes(a[i]) for i in eachindex(a))
            else
                sizeof(a)
            end
        else
            sum(allbytes(getfield(a, fieldname(T, i))) for i in 1:fieldcount(T))
        end
    end
end

```

Compared to `About`, `allbytes` simplifies by not considering the size of the record that represents the structure, only the size of the fields (arrays and vectors and such) , which is where most of the storage really is.

Also, I couldn’t get `About` to work with a sparse matrix. Or with a simpler case:

```julia
julia> struct A
       v::Vector{Float64}
       end

julia> A([1.0, 2.0])
A([1.00000e+00, 2.00000e+00])

julia> a = A([1.0, 2.0])
A([1.00000e+00, 2.00000e+00])

julia> about(a)
A (<: Any), occupies 8B directly (referencing 64B in total)
T = A
(fieldname(T, i), fieldtype(T, i), hassizeof(fieldtype(T, i))) = (:v, Vector{Float64}, true)
ERROR: Type Array does not have a definite size.
Stacktrace:
  [1] sizeof(x::Type)

```

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [October 18, 2024, 6:23pm UTC](https://discourse.julialang.org/t/ann-about-jl/118547/18 "2024-10-18T18:23:24Z")

</div>

**Version 1.0.1 is out** (imminently), with 14 bugfixes and the first contribution 😀

Slipped into the bugfix release is one technically non-bug change, we now show a preview of the memory layout of Arrays on 1.11+. Previously you had to explicitly inspect the underlying `Memory`.

---

<div class="post-metadata">

### Author: ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)
#### Post date: [March 12, 2025, 10:32pm UTC](https://discourse.julialang.org/t/ann-about-jl/118547/19 "2025-03-12T22:32:18Z")

</div>

Is this available for Julia 1.11.4? It does not work for me atleast.

Kind regards

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [March 13, 2025, 3:18am UTC](https://discourse.julialang.org/t/ann-about-jl/118547/20 "2025-03-13T03:18:56Z")

</div>

> [@Ahmed\_Salih](#):
>
> Is this available for Julia 1.11.4? It does not work for me atleast.

There’s a transient issue with a dep needing to be updated, see [Stopgap 1.11 support by disabling highlighting by palday · Pull Request #44 · tecosaur/About.jl · GitHub](https://github.com/tecosaur/About.jl/pull/44).

It’s been long enough that I’ll probably just merge the stopgap instead of thinking I’ll be able to quickly put the time in to fix/update the dep’s dep and the dep (all three packages are my responsibility, and among the many things fighting for my time).

---

<div class="post-metadata">

### Author: ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)
#### Post date: [March 13, 2025, 9:29pm UTC](https://discourse.julialang.org/t/ann-about-jl/118547/21 "2025-03-13T21:29:57Z")

</div>

Ah okay, I would like to use it, so would be nice, else I guess I will wait!

Seems like a cool package

[Next page](https://discourse.julialang.org/t/ann-about-jl/118547.md?page=2)
