On Tue, 04 Jan 2005 14:11:51 -0800, Michael Spencer <[EMAIL PROTECTED]> wrote:
[Hm, this didn't go out for some reason. I'll just send it now.]

>Roman Suzi wrote:
>
>> Maybe this is too outlandish, but I see lambdas as a "quote" mechanism,
>> which presents a possibility to postpone (precisely control, delegate)
>> evaluation. That is, an ovehead for lambda must be much lower but at the
>> same time visible to the programmer:
>> 
>>  d = a + (lambda x, y: x+ y)(3, 4)
>[...]
>
>I believe that this "possibility to postpone" divides into two related but 
>separate concepts: controlling the moment of evaluation, and assembling the 
>arguments required at that moment.  They are both species of 'eval', but 
>managing arguments is more specialized, because it includes possibly renaming 
>parameters, assigning default values, processing positional and keyword 
>arguments, and, perhaps in the future dealing with argument types.
>
I imagine that you should be able to identify bytecode substrings in current 
code
that would have to be part of an implementation of what you are proposing.
But ISTM mabe there's three concepts: 1) defining the formal parameter list,
which is like a template for unpacking and binding an actual arglist produced by
2) the source code for a call of some named function with expression for actual
arguments, and 3) the run time excution of the code compiled from (2).

AFAICS, currently there is no linkage between the called function and the 
calling code
except that the first thing put on the stack is just the result of an 
expression that
_should_ put a reference to a compatible callable on the stack. What follows is 
a sequence
of argument expressions which stack the arg values, and then finally the byte 
code is executed
to make one of several kinds of specialized function calls to use the stack 
contents.
At that point the 'callable' could be None, or another function with the wrong 
signature.

What I see as the deferred-args-evaluation part is the code between pushing the 
callable
reference and making the specialized call. But that can't be what your args 
function is,
since UIAM the 'arguments' to that are not run time calling arguments, but a 
particular
formal parameter signature. That's a guide for unpacking and binding a call's 
arguments
at an associated function's entry, to create a _part_ of the local bindings, 
which has
nothing to do with deferring the evaluation of the call args.


>Meanwhile, GvR wrote (about defining Interfaces in the context of Optional 
>Static Type Checking)
>> Method declarations can be inspected to find out their signature. I propose a
>> __signature__ attribute (also for methods defined in classes!) which might 
>> be an
>> object whose attributes make the signature easily inspectable. This might 
>> take 
>> the form of a list of argument declaration objects giving the name, type and 
>> default
>> (if any) for each argument, and a separate argument for the return type. For 
>> signatures that include *args and/or **kwds, the type of the additional 
>> arguments 
>> should also be given (so you can write for example a varargs method whose 
>> arguments
>> are all strings).
>
>GvR's method.__signature__ object might be related to the args object I 
>proposed 
>  as part of the syntax for anonymous functions without 'lambda'. i.e.,
>
>     args(a,*b,**kw) --> an object that specifies but does not evaluate its 
>parameters until it is supplied to a callable, possibly with calling parameters
This is the part I don't understand. To me, that expression doesn't have 
anything to
do with evaluating parameters, it has to do with unpacking a particular call's 
parameters
after they have been evaluated.  If it could "evaluate ist parameters" it would 
have
to have code in it to do that, but the code for evaluation of parameters is 
generated
from the translation of the calling code. And there might be dozens of lines 
calling
the same function. I.e., args(a,*b,**kw) specifies formal parameter names and 
structural
information for dealing with callers' post-evaluation actual args.

The only way it could have the ability to control evaluation of args is if it 
had a reference
to a deferred-arg-eval byte code snippet. IOw, maybe the function should be 
called argsig instead
of args and args could deal with deferred actual arg evaluation. Then the tuple
    argsig(x, y), args(1, 2)
could conceptually be like a bound method for deferred evaluation or args _and_ 
binding to
names in some namespace like a function's local namespace, but maybe not 
necessarily. Maybe
it could be applied to other namspaces as well. ... just musing ;-)

>
>This object would contain the default values, and could contain type 
>annotations, explicit, or inferred, as well as more complex assertions used in 
>several contexts.
But it has to be clear that until a particular calling-args list (deferred or 
not) is
selected by being the "current one" of possibly many, the object doesn't have 
arg values
to mess with.
>
>* Current function syntax:
>       def func(a,*b,**c) : pass
>
>       creates func with func.__signature__ = args(a,*b,**c)
>       and when func is called, the args are evaluated using a mechanism in
>       args.__call__
>       so, roughly, eval(func.__signature__) --> func.locals
Again, see above for argsig vs argeval. Or what am I missing?
>
>
>  * Anonymous functions
>       Syntax alternatives at http://www.python.org/moin/AlternateLambdaSyntax
>       e.g., (f(a) + o(b) - o(c) for args(a, b, c))
>       
>       args would evaluated with the calling parameters and made available in  
>                 the 
>local scope defined by ()
>       
>  * A stricter alternative to keyword arguments:
>       argspec = args(arg1, arg2, arg3)
>       def func(**argspec): pass
>       
>       is equivalent to def func(arg1, arg2, arg3): pass
>
>       
>       args["arg1"]
>       
>       (i.e., only args defined in argspec are accepted)
>
>  * Useful infrastructure for user-supplied type-based dispatch/lightweight 
>multimethods:
>       
>       argspec = args([(a:int, b:int),(a:str,b:str)])
>       
>       then a framework can provide a custom args.__call__ method that does
>       conformance-checking, adaptation or whatever
>

BTW, if argseval(arg1, etc) pushes arg1 and etc when "called"
sort of like (*lambda arg,etc:arg,etc) without packing/unpacking
then maybe they could be added, so argseval(a,b)+argseval(c) == argseval(a,b,c).
Don't know what that would be good for. Maybe in currying or such?

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

Reply via email to