Get an anonymous function as a string

string returns the name of a function as a string:

julia> string(sqrt)
“sqrt”

but that does not work the same for an anonymous function:

julia> string(x->x^3)
“getfield(Main, Symbol("##9#10"))()”

How can i get an anonymous function as a string, i.e., “x->x^3” in the example above?

P.S. i need to do it within a function to which the anonymous function is passed as an argument.

My understanding is that Julia is showing you the same thing in each case, only the “name” of the anonymous function is an automatically generated symbol (to give it a unique name). To try to get the behavior you want, maybe try https://github.com/MasonProtter/LegibleLambdas.jl (but you have to define the anonymous functions with a macro).

Sorry, just saw that you want to get the string representation from an anonymous function that was passed as an argument. Then I guess you need to do some kind of introspection to see how it was defined or what code it executes. Maybe https://github.com/timholy/CodeTracking.jl/ can help?

1 Like

Indeed LegibleLambdas does not do what i need:

julia> using LegibleLambdas

julia> f=x->x^3
#9 (generic function with 1 method)

julia> g=@λ(f)
ERROR: LoadError: MethodError: no method matching parse_lambda(::Symbol)
Closest candidates are: parse_lambda(::Expr) at C:\Users\congedom.julia\packages\LegibleLambdas\kpxjE\src\local.jl:11
Stacktrace: [1] @λ(::LineNumberNode, ::Module, ::Any) at C:\Users\congedom.julia\packages\LegibleLambdas\kpxjE\src\local.jl:2
in expression starting at none:1

I will check CodeTracking. Thanks!

1 Like

The julia language has no real distinction between anonymous and named generic functions.

Especially, functions don’t have source code, methods have:

julia> a=x->x^3;

julia> (::typeof(a))(x,y)=x+y;

julia> a
#3 (generic function with 2 methods)

There are many ways of defining methods. What would you want to do with the string? What if the thing was defined by a macro or a generated function? Do you want the generator or the generated AST / Expr? Oh, but generated functions can also return IR, so the string could also be printed IR instead of printed AST.

2 Likes

I have a constructor of a struct taking (among other things) a function as an argument. All i need is a string to fill a field of the struct so that the user may know what function has been applied on construction.

The natural way of doing that would be to store a julia object instead of a string:

struct foo{#= type params =#}
#other_fields
constructor_fun
end

and plug in either the constructor function (fun) or its type (typeof(fun)). The two behave different for closures: If your constructor function is a closure, then one version will store just what kind of closure was passed, and the other will store the closed over variables as well (with corresponding memory cost).

Note that constructor_fun is intentionally untyped, instead of parametric. This allows you to store the objects in homogeneous arrays, and only code that actually uses constructor_fun will be slowed down (which should be rare).

What are you trying to do? If you are trying to manipulate functions as strings then you should probably re-think your approach.

There has been some discussion of keeping the function source AST around, at least in interactive code, for display purposes if nothing else:

1 Like

Thank you guys for pointing me to these posts.

This seems to answer my question:
4089/2,