Wrapper Macros?

154 views
Skip to first unread message

John Myles White

unread,
Jan 20, 2013, 11:44:41 AM1/20/13
to julia...@googlegroups.com
I've mentioned before that it would be nice to have macros that could quickly define functions for new composite types by redirecting those functions to specific fields of the composite type. I'm about half-done, but wanted to see what people thought of the following approach:

importall Base

macro redirect(t, comp, fname)
t = esc(t)
comp = esc(comp)
fname = esc(fname)
quote
($fname)(a::($t), args...) = ($fname)(a.($comp), args...)
end
end

type MyContainer
elems::Array
end

x = MyContainer([1, 2, 3, 4])

@redirect MyContainer :elems size

size(x)

I would ultimately want to write this sort of thing like the example below, which contains no quoting and can redefine arbitrarily many functions in a single call:

@redirect MyContainer elems size length ndims endof

What do people think of this idea?

-- John

Patrick O'Leary

unread,
Jan 20, 2013, 12:46:39 PM1/20/13
to julia...@googlegroups.com

Sounds handy! Makes me wish we had Scala-like implicits, though, despite the difficulty in reasoning with them.

I'm not sure that I care about the quoting; I could live with it.

I'd prefer the list of functions to be a list, just to set it off and allow the use of multiline syntax.

Stefan Karpinski

unread,
Jan 20, 2013, 12:55:29 PM1/20/13
to Julia Users
I like it a lot – especially the latter form. This pattern is more commonly known as delegation. I would prefer to express it like this:

@delegate MyContainer.elems size length ndims endof

It would be nice if the RHS could be an expression that evaluates to an iterable that produces symbols so that you could use predefined collections of symbols (like the ones used for operators in DataFrames). However, that conflicts with this form since something like `size` could either be the name of a function that you want to delegate or a variable containing a bunch of symbols.

You also may want to delegate things besides the first slot of a function. In particular, you may want to delegate every slot of any function that applies to some other type to MyContainer.elems. That's a pretty tricky problem though. We may need some language-level support for delegation.



 -- John

--



Stefan Karpinski

unread,
Jan 20, 2013, 12:59:53 PM1/20/13
to Julia Users
On Sun, Jan 20, 2013 at 12:46 PM, Patrick O'Leary <patrick...@gmail.com> wrote:

I'd prefer the list of functions to be a list, just to set it off and allow the use of multiline syntax.

That would jive better with allowing the list of functions to be generated by an expression too.

Toivo Henningsson

unread,
Jan 20, 2013, 2:38:01 PM1/20/13
to julia...@googlegroups.com
The quotation is easily disposed of: just change comp = esc(comp) into comp = esc(expr(:quote, comp)) above.
I also think that a list of some kind would make for nicer syntax, e.g.

    @delegate_first MyContainer elems [size, length, ndims, endof]

What do people think of this idea?

 -- John

I also think that it could come in handy. Not sure about the patterns of delegation though, I suppose common patterns should be supported.
Then the macro name should probably describe the pattern of delegation, e.g. @delegate_first for the macro above.

Also, if we ever get to Stefan's idea of overloading apply, unifying functions and types, I guess that your example could instead be expressed something like

    apply(f::Union(Type{size},Type{length},Type{ndims},Type{endof}), x::MyContainer,args...) = f(x.elems,args...)

which seems like a more general and perhaps more transparent format. At least the delegation pattern is obvious.

One idea could be to mimic this kind of syntax for the macro. If the main purpose is to be able to overload several functions in a similar manner,
perhaps something in the spirit of

    @template (f<:Union(size, length, ndims, endof))(x::MyType, args...) = f(x.elems, args...)

This would repeat the function definition once with f bound to each of the four functions. I could write it if it would be desired.

Reply all
Reply to author
Forward
0 new messages