Tracing Functions: Problem printing parameter values

I’m trying to implement a function tracing facility in Julia. Each time the designated function is called I want to log the parameters and return values.

I have something partially working that is checked in at

@trace is defined at

It has two problems:

  • it prints the parameter names rather than their values
  • I’m using println because when I use Logging.@info I get the error “ERROR: LoadError: LoadError: MethodError: no method matching logmsg_code(::Module, ::String, ::Int64, ::Symbol)”.
using Pkg
Pkg.add(url="https://github.com/MarkNahabedian/NahaJuliaLib.jl")
using NahaJuliaLib
using MacroTools
@trace(trace_hanoi, function hanoi(from, to, other, count)
    if count == 1
        println("move 1 from $from to $to")
        return
    else
        hanoi(from, other, to, count - 1)
        println("move 1 from $from to $to")
        hanoi(other, to, from, count - 1)
        return (from, to)   # arbitrary result to show
    end
end)
hanoi (generic function with 1 method)
trace_hanoi = true
true
hanoi(:a, :b, :c, 2)
Trace Enter hanoi(from, to, other, count)
Trace Enter hanoi(from, to, other, count)
move 1 from a to c
Trace Exit nothing
move 1 from a to b
Trace Enter hanoi(from, to, other, count)
move 1 from c to b
Trace Exit nothing
Trace Exit (:a, :b)

Note the “Trace Enter” lines. I’d like the first one to say

Trace Enter hanoi(:a, :b, :c, 2)

instead but can’t get the code right.

I don’t see how I can “unquote” the expressions further than they’ve been quoted. Can someone sugguest how I can get the values rather than the names of the parameters printed? The values are available at runtime, so that is when the expression needs to be constructed.

Note that I will also need to make this work for functions that take keyword arguments as well. That is why I’m constructing a :call Expr and then serializing it, rather than constructing a String directly.

Here’s the macroexpansion

striplines(@macroexpand(@trace(trace_hanoi, function hanoi(from, to, other, count)
    if count == 1
        println("move 1 from $from to $to")
        return
    else
        hanoi(from, other, to, count - 1)
        println("move 1 from $from to $to")
        hanoi(other, to, from, count - 1)
        return (from, to)   # arbitrary result to show
    end
end)))
:($(Expr(:function, :(hanoi(from, to, other, count)), quote
    function var"##bodyfunction#274"()
        if count == 1
            println("move 1 from $(from) to $(to)")
            return
        else
            hanoi(from, other, to, count - 1)
            println("move 1 from $(from) to $(to)")
            hanoi(other, to, from, count - 1)
            return (from, to)
        end
    end
    if trace_hanoi
        (println)("Trace Enter ", (string)($(Expr(:copyast, :($(QuoteNode(:(hanoi(from, to, other, count)))))))))
    end
    var"##result#273" = var"##bodyfunction#274"()
    if trace_hanoi
        (println)("Trace Exit ", var"##result#273")
    end
end, Symbol("##result#273"))))

My problem is readily observable in the "Trace Enter " line. I don’t see how to get the values of the parameters rather than their names, given that their names are the result of calling map at macroexpansion time.

Thanks.