subroutine prototypes

statico on 2005-05-23T04:29:04

I'm working on a new module that exports some interesting functions. These functions describe other functions or variables with a closure, so naturally I'd assume the syntax to be something as light and snazzy as this:

somefunction foo { $bar++ };
sub foo { ... };

Or, if describing a variable:

somefunction $foo { $bar++ };

Turns out that you can't do this, as the documentation clearly states: An & requires an anonymous subroutine, which, if passed as the first argument, does not require the "sub" keyword or a subsequent comma.

Hopefully, my final syntax will appear like the following:

# for subroutines
somefunction foo => sub { $bar++}

# for lvalues
somefunction $foo => sub { $bar++ }

It's a little repetitive with the equal-arrows and sub keyword, but at least I've used prototypes (specifically, *&) to save the typing of excess parenthesis.


Semicolon

bart on 2005-05-23T21:46:15

Don't forget about the semicolon. You still need it, even after emulating the Perl syntax as close as possible. For example:
somefunction foo => sub { $bar++ };

There's no escaping it, except maybe via source filtering. (Did I just hear something heavy falling onto the floor?)

Yes, I admit it, I've been thinking along the same lines a long time ago.

Re:Semicolon

statico on 2005-05-23T22:24:44

Ah, yes. I meant to include it.

And no, no source filtering. (The axe that fell missed you by a few inches. Whew!)

Re:

Aristotle on 2005-05-24T11:39:14

You can omit the sub keyword only when the closure is the first thing in the parameter list.

The usual workaround is a do-nothing function with only the closure as prototyped parameter:

sub as(&;*) { @_ }

Then you can say

describe $foo as { $bar + $baz };

or whatever. Though this is questionable in the sense that it has to be looked up in the documentation, whereas the not-so-pretty solution is plainly obvious to anyone who knows enough Perl.