Ron_Adam wrote:
This would be the same without the nesting:

def foo(xx):
    global x
    x = xx
    return fee

def fee(y):
    global x
    return y*x

z = foo(2)(6)

Actually, it wouldn't.


>>> def foo(xx): ... global x ... x = xx ... return fee ... >>> def fee(y): ... global x ... return y*x ... >>> z=foo(2) >>> x=8 >>> z(6) 48

So the global variable can be changed between the time foo returns
and the time fee is invoked. This is not the same in the nested function
case: the value of x would be bound at the time foo is called. It can
be modified inside foo, but freezes once foo returns.

So if you are seeing (2)(6) as something to pass, as opposed to a sequence of 
operations, I think there's
a misconception involved. Perhaps I am taking your words askew ;-)


It's not entirely a misconception. Lets see where this goes...


dis.dis(compiler.compile('foo(2)(6)','','eval'))

1 0 LOAD_NAME 0 (foo) 3 LOAD_CONST 1 (2) 6 CALL_FUNCTION 1 9 LOAD_CONST 2 (6) 12 CALL_FUNCTION 1 15 RETURN_VALUE

Hmm. If you think that this proves that (2)(6) is being *passed*, you still might have a misconception. What this really does is:

0. Put foo on the stack. Stack is [value of foo]
3. Put 2 on the stack -> [value of foo, 2]
6. Call a function with one arg; invoking foo(2)
   Put the result of this call back on the stack ->
   [result of foo(2)]
9. Put 6 on the stack -> [result of foo(2), 6]
12. Call it, computing (result of foo(2))(6)
    Put the result on the stack ->
    [result of (result of foo(2))(6)]
13. Return top-of-stack, yielding foo(2)(6)

So at no point in time, (2)(6) actually exists. Instead,
when the 6 is being put onto the stack, the 2 is already gone.
It computes it one by one, instead of passing multiple sets
of arguments.

While all of this isn't relevant, it's knowledge in my mind, and
effects my view of programming sometimes.

There is nothing wrong with that. However, you really should try to see what the interpreter actually does, instead of speculation (of course, asking in a newsgroup is fine).

The calling routine, puts (passes) the second set of arguments onto
the stack before calling the function returned on the stack by the
previous call.

Sure - you need the arguments to a function before being able to call the function. So there is always a set of arguments on the stack, which internally indeed gets converted into a tuple right before calling the function. However, at no point in time, there are *two* sets of arguments.

Or it could be said equally the functions (objects) are passed with
the stack. So both view are correct depending on the view point that
is chosen.

Maybe I don't understand your view, when you said

# No, I did not know that you could pass multiple sets of arguments to
# nested defined functions in that manner.

However, they way I understood it, it seemed incorrect - there are
no multiple sets of arguments being passed, atleast not simultaneously.
It is, of course, possible to pass multiple sets of arguments
sequentially to multiple functions, eg.

a = len(x)
b = len(y)

Regards,
Martin
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to