Interpolating function arguments

metaprogramming

#1

Say I have

args = :(x,y)

and I’d like to build

goal = :(function(x,y) 0 end)

The closest I’ve been able to get is

:(function($args...) 0 end)

but that simplifies to

:(function ((x, y)...,)
        0
    end)

Anyone know a way to do this?


#2

Nevermind, I got it!

Main> Expr(:function, args, 0)
:(function (x, y)
        0
    end)

#3

Here’s one way. dump is useful to figure out what needs to go in the Expr() call.

julia> args = :(x, y)
julia> Expr(:function, args, :(0))
:(function (x, y)
      0
  end)

#4

You beat me to it! I need to learn to refresh.


#5

Shouldn’t this work, though?

julia> args = [:x, :y]

2-element Array{Symbol,1}:
 :x
 :y

julia> :(function($(args...)) 0 end)
       ERROR: syntax: expected "(" in function definition

#6

Yep, good advice - this is how I figured it out too :slight_smile:


#7

Finding a lot of weird corner cases with this. Another is that quote x end and :(x) are not the same:

Main> args = (:x, :y)
(:x, :y)

Main> :($args)
(:x, :y)

Main> quote $args end
quote  # none, line 1:
    (:x, :y)
end

#8

I got it; it failed because without a comma, the parentheses were ignored:

julia> :(function ($(args...),) 0 end)
:(function (x, y) # REPL[4], line 1:
        0
    end)

#9

There was another one that was tricky: Turn [:a,:b] into :((a,b)). I found a solution but it’s not at all elegant. I’ll add it to Simple metaprogramming exercises/challenges .