Greg Ewing wrote:
Steven Bethard wrote:
Of course, even with the unpack list, you still have to know what kind of arguments the function calls your block with. And because these only appear within the code, e.g. block(openfile) you can't rely on easily accessible things like the function's signature.
You can't rely on a function's signature alone to tell you much in any case. A distressingly large number of functions found in third-party extension modules have a help() string that just says something like
There's really no substitute for a good docstring!
But the point still stands. Currently, if we describe a function's input (parameters) and output (return value), we can basically fully document the function (given a thorough enough description of course). Functions that accept thunks/blocks require documentation for an additional piece of information that is not part of the input or output of the function: the parameters with which the thunk/block is called.
So while: fooble(arg) is pretty nasty, documentation that tells me that 'arg' is a string is probably enough to set me on the right track. But if the documentation tells me that arg is a thunk/block, that's almost certainly not enough to get me going. I also need to know how that thunk/block will be called.
True, if arg is not a thunk/block, but another type of callable, I may still need to know how it will be called. But I think with non thunks/blocks, there are a lot of cases where this is not necessary. Consider the variety of decorator recipes. Most don't document what parameters the wrapped function will be called with because they simply pass all arguments on through with *args and **kwargs. Thus the wrapped function will take the same parameters as the original function did. Or if they're different, they're often a relatively simple modification of the original function's parameters, ala classmethod or staticmethod.
But thunks/blocks don't work this way. They're not wrapping a function that already takes arguments. They're wrapping a code block that doesn't. So they certainly can't omit the parameter description entirely, and they can't even describe it in terms of a modification to an already existing set of parameters. Because the parameters passed from a thunk/block-accepting function to a thunk are generated by the function itself, all the parameter documentation must be contained within the thunk/block-accepting function.
It's not like it's the end of the world of course. ;-) I can certainly learn to document my thunks/blocks thoroughly. I just think it's worth noting that there *would* be a learning process because there are additional pieces of information I'm not used to having to document.
 I'm ignoring the issue of functions that modify parameters or globals, but this would also be required for thunks/blocks, so I don't think it detracts from the argument.
 Probably worth noting that a very large portion of the functions I've written that accepted other functions as parameters were decorators. I lean towards a fairly OO style of programming, so I don't pass around a lot of callbacks. Presumably someone who relies heavily on callbacks would be much more used to documenting the parameters with which a function is called. Still, I think there is probably a large enough group that has similar style to mine that my argument is still valid.