So I actually implemented this. You can check TestBuilinInvoker for some examples, but generally the syntax is as such:
a = foreach @ generate invoke(x)concat(x);
in the case of a function on another type and
a = foreach @ generate invoke&Integer.valueOf(x);
in the case of static types.
Currently it should support any function taking 0+ PigType arguments and returning a PigType argument...in the future we could allow people to cast Object, or to chain together non-PigTypes but that was a bit out of the scope of what I wanted to work on for this.
I actually don't love the syntax and would love to evolve it, but that portion of the parser is really hairy and it is really difficult not to introduce ambiguities...after about 10 hours of banging my head on it I went with the above. I'd love to have some eyes on this for technical merit etc.
Essentially, this turns any PigType->PigType method into a UDF without having to have a builtin, which I think is cool. This means people can have an arbitrary method on their classpath and don't have to go through the annoyance of wrapping it in a UDF. Ideally this cuts down on the number of lame builtin functions we need to add as people can just use this (it uses bytecode generation so is as performant as any code we'd write, though there are a couple of bytecode optimizations I could do down the line).