Quote with a list of kwargs

The following code is a MWE of what I’m trying to do; I’d like to write the inside of the foo function as a quote if possible (in order to make the code in my use case more readable and maintainable).

function foo(fname, pnames, pvals)
    Expr(:function, Expr(:call, fname, Expr(:parameters, (Expr(:kw, p, v) for (p, v) in zip(pnames, pvals))...)),
        Expr(:block,
            :(return nothing)
            )
        )
end

the output of the function is what I want, i.e. if eval(foo(:bar, (:a1, :a2), (0, 1))) we get a bar function with two kwargs a1=0 and a2=1

I’d like to write it more like the following code but I don’t know what I should write in ...

function foo2(fname, pnames, pvals)
    quote
        function $fname(...)
            return nothing
        end
    end
end

Thanks

This, at least, is an improvement over the first version:

function foo2(fname, pnames, pvals)
    params = [Expr(:kw, p, v) for (p, v) in zip(pnames, pvals)]
    quote
        function $fname($(params...))
            return nothing
        end
    end
end

I don’t know how make params nicer though.

1 Like

Thanks Mateusz, I had played with things like that but putting the comprehension inside the quote and that wasn’t working, this is simple and does the job :slight_smile: :medal_military:

Edit, for people who may have been looking for something similar this works: (Mateusz version doesn’t create keyword args)


function foo2(fname, pnames, pvals)
    kw = (Expr(:kw, p, v) for (p, v) in zip(pnames, pvals))
    quote
        function $fname(;$(kw...))
            return nothing
        end
    end
end
1 Like

I think the problem is that parsing of a = b is context dependent, either Expr(:=, ...) in normal cases or Expr(:kw, ...) after ; in function definitions and named tuples. And AFAIK there is no easy way to create a list of Expr(:kw) to splat after the ; except with the literal syntax :((; a = b, c = d)) but here we want to do it programmatically.

1 Like