Reverse Chaining macro: @macro f x to be equivalent to f(x)

macros

#1

Is there a way that is the backwards version of Lazy’s @>?

Is there a macro called, say, @x such that @x f x evaluates to f(x).

My use case is that I have a long plot code and I want to display it when it is done. I could do

display (
plot(...
lots
of
code)
)

But I would rather avoid parentheses. So I defined a macro

macro display(x)
esc(:display($x))
end

@display plot(...)

But I feel like there should be a more general way of doing this.


#2

Something like this?

macro run(f, x)
         esc(:($f($x)))
end

Or for any number of args:

macro run(f, x...)
         esc(:($f($x...)))
end

#3

You could also use a pipe x |> f but its depreciated.


#4

A macro with one set of arguments is pretty easy to make.

An extensible function that allows you to do, say,

f(x) = x  + 1
g(x) = x + 1

@run f g 1

Seems harder, since I think you have to know that g is callable and construct a new syntax tree for those functions.


#5

Here’s a solution, assuming everything is a single-variable function until the last term

macro run(x...)
    ex = Expr(:call, x[1])
    push!(ex.args, Expr(:call, x[2],1))
    t = ex
    for i in 3:(length(x)-1)
        t = t.args[2]
        t.args[2] =  Expr(:call, x[i],x[end])
        println(ex)
    end
    ex
end

function xx(x) x + 1 end
function yy(x) x + 1 end
function zz(x) x + 1 end
function gg(x) x + 1 end

print(@run xx yy zz gg 1)
> 5

#6

is |> deprecated? I hope not because I use it quite a lot.


#7

Yeah I’m wrong. Turns out I only read half the depreciation thread.

So just use a pipe! Macros kill revise, and make everything weird.

plot(
  blah,
  blah
) |> display

and youre done