Let’s say you have a bunch of coefficients, i.e.
function K_PC(cur_blah::AbstractBlah)
cur_K = K_law(cur_blah)
cur_K *= K_G(cur_blah) ^ 2
cur_K *= 1.273
cur_K /= cur_blah.eta_T
cur_K
end
However, you’re using SymPy
and want to enable some sort of symbolic mode
// that doesn’t evaluate any of the values (i.e. leaves the output pretty)
Is there a way to know the name of K_PC
inside itself?
This would allow you to short-circuit the function at the top with:
return SymPy.symbols(<name_of_function>)
// where <name_of_function>
would be K_PC
in this example
jw3126
April 17, 2018, 9:45am
2
You could write a macro
@name function K_PC(cur_blah::AbstractBlah)
...
end
That expands to something like
function K_PC(cur_blah::AbstractBlah)
__FUNCTION_NAME__ = :K_PC
...
end
2 Likes
I think string(stacktrace()[1].func)
will return the function’s own name (and [2]
the function calling it, etc).
An alternative solution if you merely need it for DRY and want to avoid macros is to define your operations as types, then make them callable:
abstract type AbstractOp end
struct Op1 <: AbstractOp end
function (op::Op1)(arg)
Symbol(typeof(op))
end
Also, you can define a
sympyname(::Op1) = :op1
and thus decouple the two namespaces.
3 Likes
Pretty cool solutions across the board! Thanks for your help.
The code I ended up on is:
macro symbol_func(cur_expr::Expr)
@assert cur_expr.head == :function
cur_call = cur_expr.args[1]
cur_func_name = cur_call.args[1]
cur_main_var = cur_call.args[2].args[1]
cur_param = Expr(:kw, Expr(:(::), :is_direct_call, :Bool), false)
cur_sub_expr = parse("""
$(cur_main_var).is_symbolic && !is_direct_call &&
return symbols("$(cur_func_name)")
""")
push!(cur_expr.args[1].args, cur_param)
unshift!(cur_expr.args[2].args, cur_sub_expr)
cur_expr
end
With the initial code now being:
@symbol_func function K_PC(cur_blah::AbstractBlah)
cur_K = K_law(cur_blah)
cur_K *= K_G(cur_blah) ^ 2
cur_K *= 1.273
cur_K /= cur_blah.eta_T
cur_K
end
I was using this approach for a precondition marco that wants to use the function name in an error message. It turned out not to be generally reliable . Possibly because issue #19979 means that stack traces sometimes get corrupted when try/catch
is used? Possibly due to inlining?
(Another variation of a precondition macro that needs the function name: https://github.com/JuliaLang/julia/pull/15495 )
@srp asked for @__FUNCTION__
a while back.
This issue should be re-opened because none of the referenced issues have implemented anything like @__FUNCTION__
https://github.com/JuliaLang/julia/issues/6733
2 Likes
Forgot to post a picture of the use case!
(left is a paper. right is code. and they match!)
update: already found 2 bugs in some code using this
1 Like
I’d also love to see @__FUNCTION__
added.