Re: Lambda as declarative idiom (was RE: what is lambda used for inreal code?)

Discussion in 'Python' started by Roman Suzi, Jan 3, 2005.

  1. Roman Suzi

    Roman Suzi Guest

    Hi all,

    BTW, Alex Martelli and me have created a PEP 312 some time ago (when the
    debate of inline if was hot).

    I wish lambdas will not be deprecated in Python but the key to that is
    dropping the keyword (lambda). If anybody could think of a better syntax for
    lambdas _with_ arguments, we could develop PEP 312 further.

    I DO like the idea of support for universal declaratives in Python. (This way
    SQL, Prolog, grammar, DTD, lazy expressions, decision tables (advanced switch
    statements) etc things could be added in a Pythonic way.)

    We only need brief lambdas and lets (for closures), IMHO.


    Sincerely yours, Roman Suzi
    --
    =\= My AI powered by GNU/Linux RedHat 7.3
     
    Roman Suzi, Jan 3, 2005
    #1
    1. Advertising

  2. Re: Lambda as declarative idiom (was RE: what is lambda used forin real code?)

    Roman Suzi wrote:
    > I wish lambdas will not be deprecated in Python but the key to that is
    > dropping the keyword (lambda). If anybody could think of a better syntax for
    > lambdas _with_ arguments, we could develop PEP 312 further.


    Well, my vote is still with Ruby-style codeblock syntax, but as a
    compromise, what about the following:

    fun(a, b): a + b

    as a replacement for:

    lambda a, b: a + b

    Advantages:
    - Doesn't use the l-word
    - Uses parentheses always
    - "fun" is shorter and self-describing
    - Makes Python code more "fun" ;)

    Disadvantages:
    - Requires a new keyword, breaking backward compatibility
    (I'm assuming we're still talking about Py3k here)
    - (Still) doesn't interface statements with expressions

    Dave
     
    Dave Benjamin, Jan 3, 2005
    #2
    1. Advertising

  3. Re: Lambda as declarative idiom (was RE: what is lambda used forin real code?)

    Roman Suzi wrote:
    > I wish lambdas will not be deprecated in Python but the key to that is
    > dropping the keyword (lambda). If anybody could think of a better syntax for
    > lambdas _with_ arguments, we could develop PEP 312 further.


    Some suggestions from recent lambda threads (I only considered the ones
    that keep lambda as an expression):

    ***** Args Before Expression *****

    Nick Coghlan: def-to syntax [1]
    (def (a, b, c) to f(a) + o(b) - o(c))
    (def (x) to x * x)
    (def () to x)
    (def (*a, **k) to x.bar(*a, **k))
    ((def () to x(*a, **k)) for x, a, k in funcs_and_args_list)

    Nick Coghlan: def-arrow syntax [1]
    (def (a, b, c) -> f(a) + o(b) - o(c))
    (def (x) -> x * x)
    (def () -> x)
    (def (*a, **k) -> x.bar(*a, **k))
    ((def () -> x(*a, **k)) for x, a, k in funcs_and_args_list)

    Alex Martelli: def-as syntax [2]
    (def (a, b, c) as f(a) + o(b) - o(c))
    (def (x) as x * x)
    (def () as x)
    (def (*a, **k) as x.bar(*a, **k))
    ((def () as x(*a, **k)) for x, a, k in funcs_and_args_list)

    Dave Benjamin: fun syntax [7]
    (fun(a, b, c): f(a) + o(b) - o(c))
    (fun(x): x * x)
    (fun(): x)
    (fun(*a, **k): x.bar(*a, **k))
    ((fun(): x(*a, **k)) for x, a, k in funcs_and_args_list)


    ***** Expression Before Args *****

    Robert Brewer: for (no-parens) syntax [3]
    (f(a) + o(b) - o(c) for a, b, c)
    (x * x for x)
    (x for ())
    (x.bar(*a, **k) for *a, **k)
    ((x(*a, **k) for ()) for x, a, k in funcs_and_args_list)

    Nick Coghlan: for syntax [6]
    (f(a) + o(b) - o(c) for (a, b, c))
    (x * x for (x))
    (x for ())
    (x.bar(*a, **k) for (*a, **k))
    ((x(*a, **k) for ()) for x, a, k in funcs_and_args_list)

    Nick Coghlan: def-from syntax [4]
    (def f(a) + o(b) - o(c) from (a, b, c))
    (def x * x from (x))
    (def x from ())
    (def x.bar(*a, **k) from (*a, **k))
    ((def x(*a, **k) from ()) for x, a, k in funcs_and_args_list)

    Michael Spencer: from-args syntax [5]
    (f(a) + o(b) - o(c) from args(a, b, c))
    (x * x from args(x))
    (x from args())
    (x.bar(*a, **k) from args(*a, **k))
    ((x(*a, **k) from args()) for x, a, k in funcs_and_args_list)

    Michael Spencer: for-args syntax [5]
    (f(a) + o(b) - o(c) for args(a, b, c))
    (x * x for args(x))
    (x for args())
    (x.bar(*a, **k) for args(*a, **k))
    ((x(*a, **k) for args()) for x, a, k in funcs_and_args_list)


    So there's a bunch of ideas out there. I don't know if any of them
    could be overwhelmingly preferred over lambda.

    Personally, I lean slightly towards the def-from syntax because it uses
    the 'def' keyword to bring your attention to the fact that a function is
    being defined, and it gives the expression precedence over the arglist,
    which makes sense to me for an anonymous function, where (IMHO) the
    expression is really the most important part of the declaration.

    OTOH, I think Michael Spencer's args() function, if implementable, could
    have a lot of cool uses, like getting the arguments passed to next
    within a generator. (See the thread about that[8].)


    Steve

    [1]http://mail.python.org/pipermail/python-list/2004-December/256859.html
    [2]http://mail.python.org/pipermail/python-list/2004-December/256881.html
    [3]http://mail.python.org/pipermail/python-list/2004-December/257023.html
    [4]http://boredomandlaziness.skystorm.net/2004/12/anonymous-functions-in-python.html
    [5]http://mail.python.org/pipermail/python-list/2004-December/257893.html
    [6]http://mail.python.org/pipermail/python-list/2004-December/257977.html
    [7]http://mail.python.org/pipermail/python-list/2005-January/258441.html
    [8]http://mail.python.org/pipermail/python-list/2005-January/258238.html
     
    Steven Bethard, Jan 3, 2005
    #3
  4. Roman Suzi

    Nick Coghlan Guest

    Deferred expressions (was Re: Lambda as declarative idiom)

    Steven Bethard wrote:
    > Nick Coghlan: def-from syntax [4]
    > (def f(a) + o(b) - o(c) from (a, b, c))
    > (def x * x from (x))
    > (def x from ())
    > (def x.bar(*a, **k) from (*a, **k))
    > ((def x(*a, **k) from ()) for x, a, k in funcs_and_args_list)


    After a bit more musing, this is definitely my preferred syntax. I'd call it a
    'deferred expression' rather than an anonymous function, though. The name change
    may seem minor, but it changes the emphasis of the feature from how it's
    implemented to what it is useful for (i.e. deferring evaluation of an expression
    until call time).

    It's also conducive to a clean no-argument syntax - simply make the 'from' claus
    optional when the argument list is empty.

    'def' and 'from' are already keywords, so there shouldn't be any compatibility
    problems.

    Michael Spencer's idea of using 'for' instead of 'from' was quite interesting,
    but the use of 'for' without a corresponding 'in' feels a bit misleading :)

    Cheers,
    Nick.

    --
    Nick Coghlan | | Brisbane, Australia
    ---------------------------------------------------------------
    http://boredomandlaziness.skystorm.net
     
    Nick Coghlan, Jan 4, 2005
    #4
  5. Re: Lambda as declarative idiom (was RE: what is lambda used for in real code?)

    On Mon, 03 Jan 2005 18:54:06 GMT, Steven Bethard <> wrote:

    >Roman Suzi wrote:
    >> I wish lambdas will not be deprecated in Python but the key to that is
    >> dropping the keyword (lambda). If anybody could think of a better syntax for
    >> lambdas _with_ arguments, we could develop PEP 312 further.

    >
    >Some suggestions from recent lambda threads (I only considered the ones
    >that keep lambda as an expression):
    >

    Just for reference, am I correct in assuming these are the equivalent
    uses of lambda?:

    lambda a, b, c:f(a) + o(b) - o(c)
    lambda x: x * x
    lambda : x
    lambda *a, **k: x.bar(*a, **k)
    (lambda : x(*a, **k)) for x, a, k in funcs_and_args_list)

    That last seems like it might need the default-arg-value hack: i.e.,
    (lambda x=x, a=a, k=k: x(*a, **k)) for x, a, k in funcs_and_args_list)


    >***** Args Before Expression *****
    >
    >Nick Coghlan: def-to syntax [1]
    >(def (a, b, c) to f(a) + o(b) - o(c))
    >(def (x) to x * x)
    >(def () to x)
    >(def (*a, **k) to x.bar(*a, **k))
    >((def () to x(*a, **k)) for x, a, k in funcs_and_args_list)
    >
    >Nick Coghlan: def-arrow syntax [1]
    >(def (a, b, c) -> f(a) + o(b) - o(c))
    >(def (x) -> x * x)
    >(def () -> x)
    >(def (*a, **k) -> x.bar(*a, **k))
    >((def () -> x(*a, **k)) for x, a, k in funcs_and_args_list)
    >
    >Alex Martelli: def-as syntax [2]
    >(def (a, b, c) as f(a) + o(b) - o(c))
    >(def (x) as x * x)
    >(def () as x)
    >(def (*a, **k) as x.bar(*a, **k))
    >((def () as x(*a, **k)) for x, a, k in funcs_and_args_list)
    >
    >Dave Benjamin: fun syntax [7]
    >(fun(a, b, c): f(a) + o(b) - o(c))
    >(fun(x): x * x)
    >(fun(): x)
    >(fun(*a, **k): x.bar(*a, **k))
    >((fun(): x(*a, **k)) for x, a, k in funcs_and_args_list)
    >
    >
    >***** Expression Before Args *****
    >
    >Robert Brewer: for (no-parens) syntax [3]
    >(f(a) + o(b) - o(c) for a, b, c)
    >(x * x for x)
    >(x for ())
    >(x.bar(*a, **k) for *a, **k)
    >((x(*a, **k) for ()) for x, a, k in funcs_and_args_list)
    >
    >Nick Coghlan: for syntax [6]
    >(f(a) + o(b) - o(c) for (a, b, c))
    >(x * x for (x))
    >(x for ())
    >(x.bar(*a, **k) for (*a, **k))
    >((x(*a, **k) for ()) for x, a, k in funcs_and_args_list)
    >
    >Nick Coghlan: def-from syntax [4]
    >(def f(a) + o(b) - o(c) from (a, b, c))
    >(def x * x from (x))
    >(def x from ())
    >(def x.bar(*a, **k) from (*a, **k))
    >((def x(*a, **k) from ()) for x, a, k in funcs_and_args_list)
    >
    >Michael Spencer: from-args syntax [5]
    >(f(a) + o(b) - o(c) from args(a, b, c))
    >(x * x from args(x))
    >(x from args())
    >(x.bar(*a, **k) from args(*a, **k))
    >((x(*a, **k) from args()) for x, a, k in funcs_and_args_list)
    >
    >Michael Spencer: for-args syntax [5]
    >(f(a) + o(b) - o(c) for args(a, b, c))
    >(x * x for args(x))
    >(x for args())
    >(x.bar(*a, **k) for args(*a, **k))
    >((x(*a, **k) for args()) for x, a, k in funcs_and_args_list)
    >
    >
    >So there's a bunch of ideas out there. I don't know if any of them
    >could be overwhelmingly preferred over lambda.


    Just thought of another, more concise and keywordless, expression-before-args syntax:
    :)expression)(formalparams) # equivalent to lambda formalparams:expression

    :)f(a) + o(b) - o(c))(a, b, c)
    :)x*x)(X)
    :)x)()
    :)x.bar(*a, **k))(*a, **k)
    (:)x(*a, **k)() for x, a, k in funcs_and_args_list)
    and with args default hack:
    (:)x(*a, **k)(x=x, a=a, k=k) for x, a, k in funcs_and_args_list)

    I would have proposed (expression)(formalparams), but that is already legal ;-)


    >
    >Personally, I lean slightly towards the def-from syntax because it uses
    >the 'def' keyword to bring your attention to the fact that a function is
    >being defined, and it gives the expression precedence over the arglist,
    >which makes sense to me for an anonymous function, where (IMHO) the
    >expression is really the most important part of the declaration.

    The syntax above panders to that ;-)

    >
    >OTOH, I think Michael Spencer's args() function, if implementable, could
    >have a lot of cool uses, like getting the arguments passed to next
    >within a generator. (See the thread about that[8].)
    >

    Actually, I would rather have seen the function interface itself used for that, and
    not have a scan for yields magically convert the normal function calling interface to
    a generator factory interface. But we are past that, unless we invent something new.

    E.g. if functions had an f.multicall() factory function that would return a generator
    "next" function with the same interface as f but starting code execution at the start
    the first time, and after yields on subsequent calls, then we could write

    def f(x):
    yield x+2
    yield x*2
    g = f.multicall() # not currently available
    [g(n) for n in (2,5)]

    and get (untested)
    [4, 10]

    instead of as now having to write something like

    >>> def f(x):

    ... yield x[0]+2
    ... yield x[0]*2
    ...
    >>> x = ['ignored']
    >>> g = f(x).next
    >>> [g() for x[0] in (2,5)]

    [4, 10]

    or wrapping with something more sugary.

    >
    >Steve
    >
    >[1]http://mail.python.org/pipermail/python-list/2004-December/256859.html
    >[2]http://mail.python.org/pipermail/python-list/2004-December/256881.html
    >[3]http://mail.python.org/pipermail/python-list/2004-December/257023.html
    >[4]http://boredomandlaziness.skystorm.net/2004/12/anonymous-functions-in-python.html
    >[5]http://mail.python.org/pipermail/python-list/2004-December/257893.html
    >[6]http://mail.python.org/pipermail/python-list/2004-December/257977.html
    >[7]http://mail.python.org/pipermail/python-list/2005-January/258441.html
    >[8]http://mail.python.org/pipermail/python-list/2005-January/258238.html


    Regards,
    Bengt Richter
     
    Bengt Richter, Jan 4, 2005
    #5
  6. Roman Suzi

    Roman Suzi Guest

    On Mon, 3 Jan 2005, Steven Bethard wrote:

    > Roman Suzi wrote:
    > > I wish lambdas will not be deprecated in Python but the key to that is
    > > dropping the keyword (lambda). If anybody could think of a better syntax for
    > > lambdas _with_ arguments, we could develop PEP 312 further.

    >
    > Some suggestions from recent lambda threads (I only considered the ones
    > that keep lambda as an expression):
    >
    > ***** Args Before Expression *****
    >
    > Nick Coghlan: def-to syntax [1]
    > (def (a, b, c) to f(a) + o(b) - o(c))
    > (def (x) to x * x)


    Wow! Is there any wiki-page these could be put on?

    By the way, I think to satisfy least-surprise principle, our declarative
    idiom must be compatible with type declarations GvR is planning for Python
    3.0. This way Python will have ONE style for declarations, be it
    type declarations, logical declarations or database-queries, etc.

    This means, that there is a need for a LISP's quote, when code is only
    written and parsed but may be processed not only by Python interpreter
    itself but by any user-made interpreter. For example, type-checker,
    cursor.execute, lazy-Python-subinterpreter, DOM-manipulator etc.

    I do not know how it could be done syntactically, but it could be done
    if thought about long enough.

    Lambdas is one of the ways, arguably not the most pleasant one for
    a "quote".

    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)

    if this expression is to be viewed in hypotetical syntax-highlighting
    editor, "(lambda x, y: x+ y)" need to be painted with another color
    than the rest of the expression, as it represents defining part of the
    expression, not the part which is being evaluated right away.

    What if we deprecate ` in it's repr() function and reserve it for
    inline lambdas (for Python 3.0, of course):

    d = a + (` x, y: x+y) (3, 4)

    Thus, implicit lambdas will be one more symbol, e.g.

    (`: None)

    instead of

    :) None)

    What does Guido think? ;)

    Sincerely yours, Roman A.Suzi
    --
    - Petrozavodsk - Karelia - Russia - mailto: -
     
    Roman Suzi, Jan 4, 2005
    #6
  7. Re: Lambda as declarative idiom (was RE: what is lambda used forin real code?)

    Bengt Richter wrote:
    > On Mon, 03 Jan 2005 18:54:06 GMT, Steven Bethard <> wrote:
    >
    >
    >>Roman Suzi wrote:
    >>
    >>>I wish lambdas will not be deprecated in Python but the key to that is
    >>>dropping the keyword (lambda). If anybody could think of a better syntax for
    >>>lambdas _with_ arguments, we could develop PEP 312 further.

    >>
    >>Some suggestions from recent lambda threads (I only considered the ones
    >>that keep lambda as an expression):
    >>

    >
    > Just for reference, am I correct in assuming these are the equivalent
    > uses of lambda?:
    >
    > lambda a, b, c:f(a) + o(b) - o(c)
    > lambda x: x * x
    > lambda : x
    > lambda *a, **k: x.bar(*a, **k)
    > (lambda : x(*a, **k)) for x, a, k in funcs_and_args_list)


    Yeah, I believe that was the intention, though I stole the examples from
    [1].

    > That last seems like it might need the default-arg-value hack: i.e.,
    > (lambda x=x, a=a, k=k: x(*a, **k)) for x, a, k in funcs_and_args_list)


    Good point.

    Steve
     
    Steven Bethard, Jan 4, 2005
    #7
  8. Re: Lambda as declarative idiom (was RE: what is lambda used forin real code?)

    Roman Suzi wrote:
    > On Mon, 3 Jan 2005, Steven Bethard wrote:
    >
    >
    >>Roman Suzi wrote:
    >>
    >>>I wish lambdas will not be deprecated in Python but the key to that is
    >>>dropping the keyword (lambda). If anybody could think of a better syntax for
    >>>lambdas _with_ arguments, we could develop PEP 312 further.

    >>
    >>Some suggestions from recent lambda threads (I only considered the ones
    >>that keep lambda as an expression):

    >
    > Wow! Is there any wiki-page these could be put on?


    It's now on:

    http://www.python.org/moin/AlternateLambdaSyntax

    and I added Bengt Richter's and your recent suggestions.

    Steve
     
    Steven Bethard, Jan 4, 2005
    #8
  9. Roman Suzi

    Roman Suzi Guest

    On Tue, 4 Jan 2005, Steven Bethard wrote:

    >Roman Suzi wrote:
    >> On Mon, 3 Jan 2005, Steven Bethard wrote:
    >>
    >>
    >>>Roman Suzi wrote:
    >>>
    >>>>I wish lambdas will not be deprecated in Python but the key to that is
    >>>>dropping the keyword (lambda). If anybody could think of a better syntax for
    >>>>lambdas _with_ arguments, we could develop PEP 312 further.
    >>>
    >>>Some suggestions from recent lambda threads (I only considered the ones
    >>>that keep lambda as an expression):

    >>
    >> Wow! Is there any wiki-page these could be put on?

    >
    >It's now on:
    >
    >http://www.python.org/moin/AlternateLambdaSyntax
    >
    >and I added Bengt Richter's and your recent suggestions.


    Hmmm... what if we kill two rabbits in one blow: lambda will be even
    more implicit, if we just mark parameters by a back-quote while
    using PEP 312 convention:

    :)f(`a) + o(`b) - o(`c))
    :)`x * `x)
    :)x)
    :)x.bar(*`a, **`k))

    Not sure about default args:

    ((fun(x=x, a=a, k=k): x(*a, **k)) for x, a, k in funcs_and_args_list)

    Maybe this needs to be done with closures.
    Otherwise I think Python interpreter is quite capable to determine
    which parameters the function has... Only their order become a problem.
    Probably, ","-s could be used there:

    (`a,`b,`c : f(`a) + o(`b) - o(`c))

    The whole expressions could be quoted:

    `(x, y, z)

    meaning a parameter with such structure.



    >Steve
    >


    Sincerely yours, Roman Suzi
    --
    =\= My AI powered by GNU/Linux RedHat 7.3
     
    Roman Suzi, Jan 4, 2005
    #9
  10. args (was Re: Lambda as declarative idiom (was RE: what is lambdaused for in real code?))

    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.

    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 object would contain the default values, and could contain type
    annotations, explicit, or inferred, as well as more complex assertions used in
    several contexts.

    * 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


    * 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




    Michael
     
    Michael Spencer, Jan 4, 2005
    #10
  11. Roman Suzi

    Roman Suzi Guest

    Re: args (was Re: Lambda as declarative idiom (was RE: what islambda used for in real code?))

    On Tue, 4 Jan 2005, Michael Spencer wrote:

    >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.


    Yes. I have the same understanding.

    >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.


    Very precise!

    >Meanwhile, GvR wrote (about defining Interfaces in the context of Optional
    >Static Type Checking)


    As for GvR's writing, I think he is exploring the ground. What he wrote
    is too complex for Python and he guesses it is.

    There i another thread in c.l.p where I propose generic programming
    approach for Python's "type checking": IMHO, a much simpler and more natural
    for Python than programming by contract, just interfaces and such.

    And the syntactic way to express concepts is going thru
    declarations. That is why lambdas are to be on steroids for this task.

    More than that, compile vs. evaluation/parameter dispetching must not muddy
    the waters for programmer. It must always be clear (syntactically too)
    for him what is going on in the expression at hand. (But I do not know
    how this could be elegantly done sytactically)

    Is declaration-chewing engine built into Python an overkill?
    There are at least 2 specialized ones in it: parser and re.compile +
    many for different formats, like xml.dom.


    Sincerely yours, Roman Suzi
    --
    =\= My AI powered by GNU/Linux RedHat 7.3
     
    Roman Suzi, Jan 4, 2005
    #11
  12. Re: Deferred expressions (was Re: Lambda as declarative idiom)

    On Tue, 04 Jan 2005 19:31:37 +1000, Nick Coghlan <> wrote:

    >Steven Bethard wrote:
    >> Nick Coghlan: def-from syntax [4]
    >> (def f(a) + o(b) - o(c) from (a, b, c))
    >> (def x * x from (x))
    >> (def x from ())
    >> (def x.bar(*a, **k) from (*a, **k))
    >> ((def x(*a, **k) from ()) for x, a, k in funcs_and_args_list)

    >
    >After a bit more musing, this is definitely my preferred syntax. I'd call it a
    >'deferred expression' rather than an anonymous function, though. The name change
    >may seem minor, but it changes the emphasis of the feature from how it's
    >implemented to what it is useful for (i.e. deferring evaluation of an expression
    >until call time).

    I like the fact that 'def' can serve as a mnemonic for 'defer' or 'deferred' ;-)

    OTOH, I like concise notation for expressions, and the def and from aren't
    really necessary if you can tag the first expression with some syntax marker.
    I suggested :) rather than (def since :) is illegal now and won't break anything.

    But all this is just a rewrite of lambda params:expr as (def expr from params).
    What is the point again? (Not that my rewrite to :)expr)(params) is any more
    than a lambda rewrite either). If backticks could be used, `(expr:params)
    might be an interesting spelling of lambda params:expr.

    I do like being able to leave out the from clause. `(expr) would let you do that too,
    just as well as :)expr).
    >
    >It's also conducive to a clean no-argument syntax - simply make the 'from' claus
    >optional when the argument list is empty.

    That is an advantage of having it inside the outer parens, which my :)expr)(params)
    couldn't benefit from -- unless I just take your format and substitute ':' for
    both def and from:

    :) f(a) + o(b) - o(c) : (a, b, c))
    :) x * x : (x))
    :) x) # empty arg list
    :) x.bar(*a, **k) : (*a, **k))
    (:) x(*a, **k) : (x=x, a=a, k=k) for x, a, k in funcs_and_args_list)


    >
    >'def' and 'from' are already keywords, so there shouldn't be any compatibility
    >problems.
    >
    >Michael Spencer's idea of using 'for' instead of 'from' was quite interesting,
    >but the use of 'for' without a corresponding 'in' feels a bit misleading :)

    What was the point of all this again? Pretending lambda goes away without really killing it? ;-)

    Regards,
    Bengt Richter
     
    Bengt Richter, Jan 5, 2005
    #12
  13. Roman Suzi

    Nick Coghlan Guest

    Re: Deferred expressions (was Re: Lambda as declarative idiom)

    Bengt Richter wrote:
    > I like the fact that 'def' can serve as a mnemonic for 'defer' or 'deferred' ;-)


    Yeah, me too. I didn't actually notice that until after I'd thought of the phrase.

    > OTOH, I like concise notation for expressions, and the def and from aren't
    > really necessary if you can tag the first expression with some syntax marker.
    > I suggested :) rather than (def since :) is illegal now and won't break anything.


    True, but I've always liked Python's preference for keywords over punctuation.
    And 'def' is only 2 characters longer than ':', too.

    > That is an advantage of having it inside the outer parens, which my :)expr)(params)
    > couldn't benefit from -- unless I just take your format and substitute ':' for
    > both def and from:


    But where does that leave "Python is executable pseudocode"?

    Compare:
    (lambda (a, b, c) : f(a) + o(b) - o(c))
    :) f(a) + o(b) - o(c) : (a, b, c))
    (def f(a) + o(b) - o(c) from (a, b, c))

    Which of the above most clearly expresses "defer a functional expression taking
    arguments a, b, and c"?

    For comparison, named syntax requires 3 lines, since Guido also wants to remove
    suite one-liners in Py3k:

    def f1(a, b, c):
    return f(a) + o(b) - o(c)
    f1

    Not so bad for a single deferred expression (particularly a
    not-completely-trivial one like this), but fares significantly worse for simple
    zero-argument functions, or if you are just setting up a couple of deferred
    expressions in a function call. There's no more virtue in completely squandering
    vertical screen real estate than there is in being overly conservative with it.

    > What was the point of all this again? Pretending lambda goes away without really killing it? ;-)


    Actually, it was started by the "please don't take our lamdbas!" comments
    regarding Python 3k. I suggested that one of the problems with lambda is that it
    is an expression but looks like a one-liner statement ("it's ugly as sin" may
    have been closer to my actual phrasing), that the syntax would be deservedly
    rejected if proposed as a new addition to the language, and a more productive
    response might be to consider nicer alternative syntax that Guido would consider
    retaining in Python 3k (since it would make sense to try out such a syntax in
    the Python 2.x series before committing to it for 3.0).

    Of course, after making that suggestion, my brain decided to start working on
    its *own* ideas for a more Pythonic syntax (trying to learn from generator
    expressions), which seemed to set off a few other people :)

    The name 'deferred expression' is intended to emphasise what I see as the most
    appropriate application for anonymous functions - using an entire named function
    statement to defer a simple expression is serious overkill. Recognising this use
    case was what switched me from "I won't miss lambdas" to "You know, I'd really
    regret it if they disappeared completely".

    Basically, I think lambda has a PR problem - its usefulness as a way to defer
    expression evaluation is obscured by its ugly syntax and its current explanation
    as "a neutered form of function definition, but at least you can use it in an
    expression".

    On backticks, they have a major problem in that many fonts make ` and '
    virtually indistinguishable. A secondary problem is that printed text often
    renders an opening single quote like a backtick. Guido has already mentioned
    this in one of Python Regrets talks (in the context of the backtick repr
    syntax). So I don't expect any syntax involving backticks to even be looked at
    by the BDFL.

    Cheers,
    Nick.

    --
    Nick Coghlan | | Brisbane, Australia
    ---------------------------------------------------------------
    http://boredomandlaziness.skystorm.net
     
    Nick Coghlan, Jan 6, 2005
    #13
  14. Re: args (was Re: Lambda as declarative idiom (was RE: what is lambda used for in real code?))

    On Tue, 04 Jan 2005 14:11:51 -0800, Michael Spencer <> 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
     
    Bengt Richter, Jan 7, 2005
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. MS Newsgroups

    Declarative Security in ASP .net

    MS Newsgroups, Oct 17, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    470
    Natty Gur
    Oct 19, 2003
  2. Steven Bethard

    what is lambda used for in real code?

    Steven Bethard, Dec 31, 2004, in forum: Python
    Replies:
    26
    Views:
    701
    Steven Bethard
    Jan 7, 2005
  3. Steve Dogers

    lambda vs non-lambda proc

    Steve Dogers, Mar 30, 2009, in forum: Ruby
    Replies:
    1
    Views:
    203
    Sean O'Halpin
    Mar 30, 2009
  4. Replies:
    27
    Views:
    538
    Robert Klemme
    Jan 7, 2013
  5. Haochen Xie
    Replies:
    4
    Views:
    266
    Haochen Xie
    Mar 17, 2013
Loading...

Share This Page