Help making a literal function type

So I’m working on a bit of a pet project which involves rolling my own computer algebra system. So far its really fun but I’m getting stuck with trying to define a special type of function called a literal_function. The idea with literal functions is to make a procedure that represents a function of one argument that has no known properties other than the given symbolic name.

Ie. I would like to be able to say

julia> f = literal_function(:f)
julia> f(:t)
:(f(t))

ie. a literal_function is constructed with a Symbol as its name and when given a symbolic input it just returns an expression that looks like
and unevaluated function call. This is easy to do, I did it simply with

function literal_function(name)
    function (t)
        :($name($t))
    end
end

However, I would like to be able to dispatch differently on literal_functions than I would with normal functions in certain circumstances, ie. I would like to have a type Literal_Function <: Function such that I can do some_other_function(f::Literal_Function) = stuff.

so I adapted some advice I got on Slack for another question I had and tried to make a type Literal_Function which does what I want.

struct Literal_Function <: Function end

function literal_function(name)
    function Literal_Function(t)
        :($name($t))
    end
end

but unfortunately the object this returns is not of type Literal_Function, its of type #Literal_Function#1{Symbol} .
Does anyone know how I can make my constructor literal_function return a function like object of type Literal_Function?

Maybe something like this:

julia> struct LiteralFunction
           name::Symbol
       end

julia> x = LiteralFunction(:x)
LiteralFunction(:x)

julia> (f::LiteralFunction)(t) = :($(f.name)($t))    # **

julia> x(:t)
:(x(t))

Here LiteralFunction becomes a function-like object by defining how to call it in the line marked with **.

2 Likes

I see, that’s a nice solution! thanks a bunch.