[SciPy-Dev] usage of inspect.getargspec ?

Robert Kern robert.kern at gmail.com
Fri Jan 6 10:11:26 EST 2012


On Fri, Jan 6, 2012 at 14:41, Travis Oliphant <travis at continuum.io> wrote:
>
>
> --
> Travis Oliphant
> (on a mobile)
> 512-826-7480
>
>
> On Jan 6, 2012, at 12:34 AM, Nathaniel Smith <njs at pobox.com> wrote:
>
>> On Thu, Jan 5, 2012 at 9:15 PM, Travis Oliphant <travis at continuum.io> wrote:
>>> What is an isn't Pythonic seems to be a matter of some debate.     I *really* like the idea of unifying those arguments.   That simplifies the interface considerably.
>>
>> Yes, I try not to throw around "Pythonic" as an argument, since it
>> tends to turn into a slur rather than an argument. But this just
>> strikes me as so fundamentally at odds with Python's conventions that
>> I'm not sure what else to say.
>>
>>> I can understand the argument that it would be better to be explicit about it however.    I see a couple of options:
>>>
>>>        1) add a property to the function to indicate what kind of function it is --- a simple 'kind' attribute on the function
>>>        2) wrap up the function as the callable of a Singleton Class --- one kind for each "type" of function call.
>>
>> I'm honestly baffled at how any of this would simplify the interface
>> at all. We have two types of callbacks that might optionally be
>> passed, and they have totally different calling semantics. The
>> simplest way to represent that is to have two optional arguments. If
>> we shove them both into one argument but still have two types of
>> callbacks and then add some extra (possibly unreliable) machinery to
>> disambiguate them, then isn't that more complicated, not less?
>>
>> The original API:
>>  behavior 1: optimize(f, hess=f_hess)
>>  behavior 2: optimize(f, hessp=f_hessp)
>> The getargspec API:
>>  behavior 1: optimize(f, hess=f_hess)
>>  behavior 2: optimize(f, hess=f_hessp) # don't worry, we'll always guess right!
>> The property API:
>>  behavior 1 : optimize(f, hess=f_hess)
>>  behavior 2: f_hessp.kind = "hessp"; optimize(f, hess=f_hessp)
>> The class API:
>>  behavior 1: optimize(f, hess=f_hess)
>>  behavior 2: optimize(f, hess=this_is_really_a_hessp(f_hessp))
>>
>> How are the other options simpler than the first?
>
> This would be done most easily with a decorator when the function is defined, of course.   Also, the automatic discovery mechanism will work in most simple cases.  The decorator could be used in more complicated situations.

You can't add attributes to C- or Cython-implemented functions, by
decorator or otherwise, and getargspec doesn't work for them either.

> Also it should be emphasized that this change is in the context of optimization unification.  Giving the main interface 2 Hessian arguments makes that function more confusing to new users who mostly won't need to deal with Hessians at all.

I don't really see why. The original docstring describes both at the
same time in the same block of text. I can't imagine any serious
additional cognitive overhead if you don't need Hessians. But I don't
have access to enough new users to really test this claim.

> So, I like this change because it simplifies things mentally for more than 99.9% of the users while all the concerns are about possible complexity or confusion are for less than .1% of the users of the main function. Confusion which can be alleviated with decorators.
>
> My view is that simple things should be simple --- especially for the occasional user.

My main problem with this view is that I don't think that whether you
need a Hessian or not is the reasonable line to draw between "simple
things" and "not so simple things". The problem with using
getargspec() is that it is unreliable. It doesn't work for many
reasonable inputs (like say a wrapper function that wraps the real
function with one that takes *args,**kwds or extension functions or
bound methods or objects with __call__). Knowing that you have one of
these cases requires some rather deep experience with Python. I'm sure
I've missed a few in my list. So yes, if you have a problem that
involves computing the Hessian, you do have a more complicated problem
than one which does not involve Hessians, and you should expect to
have to implement a somewhat more complicated solution. You should not
be expected to know deep details about Python's implementation to
understand why your function failed mysteriously.

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco



More information about the SciPy-Dev mailing list