# Macro: quote versus colon

**URL:** https://discourse.julialang.org/t/macro-quote-versus-colon/36041
**Category:** New to Julia
**Tags:** macros
**Created:** [March 16, 2020, 1:00pm UTC](https://discourse.julialang.org/t/macro-quote-versus-colon/36041 "2020-03-16T13:00:41Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)
#### Post date: [March 16, 2020, 1:00pm UTC](https://discourse.julialang.org/t/macro-quote-versus-colon/36041/1 "2020-03-16T13:00:41Z")

</div>

I am going over macros, and decided to test whether quote and colon were identical. See the code below. Apparently they are not. And if not, it means that there likely side effects in rare instances. What am I missing? Thanks.

```julia
julia> e = quote 2+3 end
quote
    #= none:1 =#
    2 + 3
end

julia> dump(e)
Expr
  head: Symbol block
  args: Array{Any}((2,))
    1: LineNumberNode
      line: Int64 1
      file: Symbol none
    2: Expr
      head: Symbol call
      args: Array{Any}((3,))
        1: Symbol +
        2: Int64 2
        3: Int64 3

julia> dump(:(2+3))
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol +
    2: Int64 2
    3: Int64 3

```

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [March 16, 2020, 1:16pm UTC](https://discourse.julialang.org/t/macro-quote-versus-colon/36041/2 "2020-03-16T13:16:02Z")

</div>

```julia
quote 2+3 end

```

is equivalent to

```julia
:( begin 2+3 end )

```

Edit: The documentation (from typing `?quote` at the REPL) also says: “Unlike the other means of quoting, `:( ... )`, this form introduces `QuoteNode` elements to the expression tree, which must be considered when directly manipulating the tree. For other purposes, `:( ... )` and `quote .. end `blocks are treated identically.” (I’m not sure exactly when that happens.)

---

<div class="post-metadata">

### Author: ![xor0110](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xor0110/32/7926_2.png) [@xor0110](https://discourse.julialang.org/u/xor0110)
#### Post date: [November 30, 2021, 9:27am UTC](https://discourse.julialang.org/t/macro-quote-versus-colon/36041/3 "2021-11-30T09:27:02Z")

</div>

I’ve stumbled on this while creating a variation of the assert macro, and it’s pretty significant for that use case. Apparently the `LineNumberNode` gets in the way of the system error message showing you the point in the code where the macro is used, and what you get is the macro definition line instead:

Example with colon, showing the code line where the macro is used:

```julia
macro assertcolon(ex)
    msg = Main.Base.string(ex)
    :(
        $(esc(ex)) ? $(nothing) : throw(AssertionError($msg))
    )
end

function mytestcolon(xx)
    @assertcolon 0 == 2 - xx
end
mytestcolon(2)
mytestcolon(1)

```

Resulting error message:

```julia
LoadError: AssertionError: 0 == 2 - xx
in expression starting at /home/nic/src/myassert.jl:12

mytestcolon(xx::Int64) at myassert.jl:9
top-level scope at myassert.jl:12

```

Now using quote:

```julia
macro assertquote(ex)
    msg = Main.Base.string(ex)
    quote
        $(esc(ex)) ? $(nothing) : throw(AssertionError($msg))
    end
end

function mytestquote(xx)
    @assertquote 0 == 2 - xx
end
mytestquote(2)
mytestquote(1)

```

The resulting message:

```julia
LoadError: AssertionError: 0 == 2 - xx
in expression starting at /home/nic/src/myassert.jl:12

mytestquote(xx::Int64) at myassert.jl:4
top-level scope at myassert.jl:12

```

As you can see, the message now points straight to the macro line, and retains the top function call, but the actual code line where the macro was called is gone… Gotta use colon to do sneaky code changes, and quote to leave traces. Add this to the list of meta-programming gotchas, I guess!

---

<div class="post-metadata">

### Author: ![yha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yha/32/3502_2.png) [@yha](https://discourse.julialang.org/u/yha)
#### Post date: [November 30, 2021, 12:14pm UTC](https://discourse.julialang.org/t/macro-quote-versus-colon/36041/4 "2021-11-30T12:14:09Z")

</div>

> [@xor0110](#):
>
> As you can see, the message now points straight to the macro line, and retains the top function call, but the actual code line where the macro was called is gone…

Relevant issue:

> <https://github.com/JuliaLang/julia/issues/31197>
>
> Methods have a couple of fields, \`.file\` and \`.line\`, that document their origin…. But when a method is defined via a macro, it gets a little ambiguous: do you attribute the definition to the macro or to the caller of the macro? There's nothing really new here: the various complaints about figuring out where a \`@deprecate ...\` command was issued from have a long and storied history. Perhaps the most important thing here is that there \*is\* a viable (but insane) strategy for finding it, see below.
> 
> Let's consider the following example:
> 
> \`\`\`julia
> julia\> m = @which Float32(π)
> Float32(::Irrational{:π}) in Base.MathConstants at irrationals.jl:167
> \`\`\`
> 
> There are a couple of interesting features here:
> \- \`m.module\` is \`Base.MathConstants\`, which is the caller
> \- \`m.file\` is \`irrationals.jl\`, the file in which the \`@irrational\` macro is defined. This is loaded into \`Base\`, not \`Base.MathConstants\`. \`m.line\` is likewise associated with the macro.
> \- Figuring out the macro-caller's source location is tricky. For example,
> 
> \`\`\`julia
> julia\> code = Base.uncompressed\_ast(m)
> CodeInfo(
> 1 ─ return 3.1415927f0
> )
> 
> julia\> code.linetable
> 1-element Array{Any,1}:
> Core.LineInfoNode(Base.MathConstants, :Type, Symbol("irrationals.jl"), 167, 0)
> \`\`\`
> so again there doesn't seem to be any way of figuring out the caller's file.
> 
> I've found one viable strategy to find these methods:
> \- Figure out which specific macro was responsible for the definition. For example, here that means parsing \`irrationals.jl\` and looking to see which top-level expression contains line 167.
> \- Grab \`m.module\`'s \`eval\` or \`include\` method and ask which file it's from. This is the file in which the module was created.
> \- Parse that file and see if the module contains any additional \`include\` directives, so that you get a complete list of all files that were used to define that module.
> \- Then for each file:
> + parse the file and look for \`:macrocall\` expressions to that particular macro
> + lower those calls and compute the method signature
> + when you find a match, return the caller LineNumberNode.
> 
> Obviously this is not a small amount of work; it would make life easier if \`Method\` contained enough information to figure this out more directly. To achieve that, it seems that \`CodeInfo\` needs some enhancements so that it can store the macro-caller's \`LineNumberNode\`. For example, allowing \`Vector{LineInfoNode}\` entries in \`code.linetable\` would be sufficient to document the origin. (Or make \`LineInfoNode\` a linked-list?)
