# Finding \`Expr\`s with docstrings

**URL:** <https://discourse.julialang.org/t/finding-expr-s-with-docstrings/130214>\
**Category:** General Usage\
**Tags:** metaprogramming\
**Created:** [June 25, 2025, 8:30pm UTC](https://discourse.julialang.org/t/finding-expr-s-with-docstrings/130214 "2025-06-25T20:30:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![moble](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moble/32/23535_2.png) [@moble](https://discourse.julialang.org/u/moble)\
**Post date:** [June 25, 2025, 8:30pm UTC](https://discourse.julialang.org/t/finding-expr-s-with-docstrings/130214/1 "2025-06-25T20:30:42Z")

</div>

How do I detect when an `Expr` has a docstring?

For example, if

```julia
expr = quote
    """Here's a docstring!"""
    const a=1
end

```

I can look at the result to see that it is translated into a macrocall of `@doc` (after skipping the first, blank line:

```julia
julia> expr2 = expr.args[2]
:(#= REPL[1]:2 =# Core.@doc "Here's a docstring!" const a = 1)

julia> expr2.head
:macrocall

julia> expr2.args
4-element Vector{Any}:
 :(Core.var"@doc")
 :(#= REPL[1]:2 =#)
 "Here's a docstring!"
 :(const a = 1)

```

All this makes sense.

But now, suppose I want to detect that some `Expr` with `:macrocall` head is a call to `@doc`. The obvious thing to try, given the above, is to test the first element of `expr2.args`:

```julia
julia> expr2.args[1] == :(Core.var"@doc")
false

```

I literally just copied the expression, but it’s not that?!

* * *

Okay, `dump`ing it shows me that `expr2.args[1]` is actually a `GlobalRef` with `name` field `Symbol("@doc")`. So I could do

```julia
julia> expr2.args[1] isa GlobalRef && expr2.args[1].name==Symbol("@doc")
true

```

This seems really ugly. Is this the best way? Will I miss some possibilities?

---

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [June 25, 2025, 9:05pm UTC](https://discourse.julialang.org/t/finding-expr-s-with-docstrings/130214/2 "2025-06-25T21:05:01Z")

</div>

You could use `inexpr` from MacroTools.jl:

```julia
julia> inexpr(expr, Core.GlobalRef(Core, Symbol("@doc")))
true

```

---

<div class="post-metadata">

**Author:** ![moble](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moble/32/23535_2.png) [@moble](https://discourse.julialang.org/u/moble)\
**Post date:** [June 25, 2025, 9:19pm UTC](https://discourse.julialang.org/t/finding-expr-s-with-docstrings/130214/3 "2025-06-25T21:19:44Z")

</div>

It looks like `inexpr` will find such an expression anywhere inside a larger expression, but other than that is this different in any significant way from testing for equality like I did? In particular, I’m worried about how minor changes in syntax always seem to drastically change an `Expr`.

* * *

On that note, I found a similar expression that would fail this test and mine:

```julia
julia> expr = quote
           @doc """Here's a docstring!"""
           const a=1
       end;

julia> inexpr(expr, Core.GlobalRef(Core, Symbol("@doc")))
false

```

All I did was add `@doc`. 🙄

---

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [June 25, 2025, 9:30pm UTC](https://discourse.julialang.org/t/finding-expr-s-with-docstrings/130214/4 "2025-06-25T21:30:49Z")

</div>

> [@moble](#):
>
> I’m worried about how minor changes in syntax always seem to drastically change an `Expr`.

I think there is no way around it. In your second example you would have to say

```julia
julia> inexpr(expr, Symbol("@doc"))
true

```

But that doesn’t work for

```julia
expr = quote
    Base.@doc """Here's a docstring!"""
    const a=1
end

```

I doubt that there is a universal solution.
