A. Pagaltzis wrote:

* Ofer Nave <[EMAIL PROTECTED]> [2005-03-01 23:45]:


I realize that since I can tell listrefs apart from strings and
code refs, I could allow this:

prun(
$coderef1,
$coderef2 => [ $arg1, $arg2, $arg3 ],
);

Which would run $coderef1 once, but run $coderef2 three times,
once for each arg. If you wanted to pass more than one arg at
a time, you could create sublists:



Leave it out.

It looks like a great idea to you right now with the one or two
examples you developed this on, but you'll get sick of it very
quickly if you start to use it on a larger scale. Don't try to be
too clever, it will bite you once in maintenance mode.

I've done things like that several times in the past and they
always end up obfuscating the code more than they help. This is
really something that must be solved on the language level, à la
currying and compositing operators, not on the level of
individual APIs by overloading the semantics of various data
types.

If you feel it is really important to make this particular use
case easier, use an API like this:

   prun(
       $coderef1,
       [ $coderef2, $arg1 ],
       [ $coderef2, $arg2 ],
       [ $coderef2, $arg3 ],
   );

whose meaning is reasonably easy to guess without having to study
the documentation too closely.

For reducing redundancy, this allows you to fall back on regular
Perl idioms:

   prun(
       $coderef1,
       map( [ $coderef2, $_ ], $arg1, $arg2, $arg3, ),
   );

Now the prun() function has one fewer interface conventions, and
I can understand half of what's going on with my regular Perl
knowledge before I've even read your docs.

There is also precedent in taking an anonymous array with a
coderef in the first slot as a shortcut for "call this code with
these parameters"; offhand I remember that Tk does it this way
but there were other places I saw it. I believe that is because
it is a pretty natural notation.

And your code also has less to guess, because the number of
arguments doesn't change depending on whether I pass arguments to
some coderefs or not.



That seems reasonable.

For similar reasons, I would suggest that you don't allow named
subs as in

   prun(
       foo => $coderef1,
       bar => $coderef2,
   );

but rather require

   prun( {
       foo => $coderef1,
       bar => $coderef2,
   } );

so that you only have to check one easily expressed condition.



I hate to force people to create an anonymous hash when it can be implied. Plus I'm already checking for hashref as the first param to allow options to be specified, so I'd have to change that... to what, I don't know.

-ofer



Reply via email to