FAQ
In ruby, we can add a lambda function into a function call. but it's a
little ugly:

[1,2,3,4].each { |x|
print x
}


but, it really convenient. current lambda only support single line
syntax. it's not very good. maybe we can add a new syntax:
call: primary "(" argument-list ")" [ "lambda" parameter-list ":" suite ]

the postfix lambda will translate to a single "function" object, and
pass to the &arg parameter of function. so the function call will become
func(*arg1, **arg2, &arg3)

for example, we can write this:

def print_list(*lists, &func = lambda x: true):
for item in lists:
map(a) lambda x:
if func(x):
print x


call with:
print_list([1,2,3], [1,2]) lambda x:
if x % 2: return True
else return False

Search Discussions

  • Masklinn at Oct 19, 2009 at 1:43 pm

    On 19 Oct 2009, at 15:33 , starwing wrote:
    In ruby, we can add a lambda function into a function call. but it's a
    little ugly:

    [1,2,3,4].each { |x|
    print x
    }


    but, it really convenient. current lambda only support single line
    syntax. it's not very good. maybe we can add a new syntax:
    call: primary "(" argument-list ")" [ "lambda" parameter-list ":"
    suite ]

    the postfix lambda will translate to a single "function" object, and
    pass to the &arg parameter of function. so the function call will
    become
    func(*arg1, **arg2, &arg3)

    for example, we can write this:

    def print_list(*lists, &func = lambda x: true):
    for item in lists:
    map(a) lambda x:
    if func(x):
    print x


    call with:
    print_list([1,2,3], [1,2]) lambda x:
    if x % 2: return True
    else return False
    This is not going to end well.

    Also,
    http://mail.python.org/pipermail/python-ideas/2007-December/001279.html
    http://mail.python.org/pipermail/python-ideas/2008-April/001522.html
    http://mail.python.org/pipermail/python-ideas/2008-November/002340.html

    The BDFL has disliked every proposal so far, and due to the Ruby-
    inspired weirdness and magic of this one I really don't see him liking
    it any better than the ones that came before.

    -m
  • Oleg Broytman at Oct 19, 2009 at 2:04 pm

    On Mon, Oct 19, 2009 at 09:33:06PM +0800, starwing wrote:
    current lambda only support single line
    syntax. it's not very good.
    This is where you've made an error. Single-line lambdas are good enough,
    and if you need more - just create a named function.

    Oleg.
    --
    Oleg Broytman http://phd.pp.ru/ phd at phd.pp.ru
    Programmers don't die, they just GOSUB without RETURN.
  • Starwing at Oct 19, 2009 at 2:28 pm

    Oleg Broytman ??:
    On Mon, Oct 19, 2009 at 09:33:06PM +0800, starwing wrote:

    current lambda only support single line
    syntax. it's not very good.
    This is where you've made an error. Single-line lambdas are good enough,
    and if you need more - just create a named function.

    Oleg.
    BUT, why we need a name? just to process something or make decide,
    sometimes code itself is enough.

    and, is there performance problems when you define a inner function in
    another function? (that's, that function will define every time you call
    the function or not?)
  • Oleg Broytman at Oct 19, 2009 at 2:39 pm

    On Mon, Oct 19, 2009 at 10:28:58PM +0800, starwing wrote:
    Oleg Broytman ??????:
    Single-line lambdas are good enough,
    and if you need more - just create a named function.
    BUT, why we need a name? just to process something or make decide,
    sometimes code itself is enough.
    A multiline function is certainly not a simple piece of code; it
    requires documentation - docstring, comments - and the name is a part of
    the documentation.
    and, is there performance problems when you define a inner function in
    another function? (that's, that function will define every time you call
    the function or not?)
    A lambda, like an inner function, is recreated every time, so it's
    certainly no better than a named function.
    You should profile your program to prove there is really a performance
    degradation. And if there is - create a global function instead.

    Oleg.
    --
    Oleg Broytman http://phd.pp.ru/ phd at phd.pp.ru
    Programmers don't die, they just GOSUB without RETURN.
  • Masklinn at Oct 19, 2009 at 3:13 pm

    On 19 Oct 2009, at 16:39 , Oleg Broytman wrote:
    On Mon, Oct 19, 2009 at 10:28:58PM +0800, starwing wrote:
    Oleg Broytman ??????:
    Single-line lambdas are good enough,
    and if you need more - just create a named function.
    BUT, why we need a name? just to process something or make decide,
    sometimes code itself is enough.
    A multiline function is certainly not a simple piece of code; it
    requires documentation - docstring, comments - and the name is a
    part of
    the documentation.
    Why would grouping two statements require such an overhead? Do you
    write a comment for each line of Python code you produce?

    A function, named or not, is nothing more than a bloc of code (in fact
    that's exactly how they're called in Smalltalk), and not all blocs of
    code require a name, a docstring and comments.
  • Michael Foord at Oct 19, 2009 at 10:33 pm
    2009/10/19 Oleg Broytman <phd at phd.pp.ru>
    On Mon, Oct 19, 2009 at 10:28:58PM +0800, starwing wrote:
    Oleg Broytman ??????:
    Single-line lambdas are good enough,
    and if you need more - just create a named function.
    BUT, why we need a name? just to process something or make decide,
    sometimes code itself is enough.
    A multiline function is certainly not a simple piece of code; it
    requires documentation - docstring, comments - and the name is a part of
    the documentation.
    Having used languages that allow multiline anonymous functions (C#,
    Javascript) I have to say that they *can* improve the readability of code.
    Being forced to define functions ahead of where they belong in the logical
    flow of the program is not a feature of Python but a restriction.

    To dogmatically assert that multiline anonymous functions are *necessarily*
    less clear simply does the reputation of Python damage to those who use them
    already in other languages and know that this isn't true.

    I accept that it is a necessary restriction in Python (basically impossible
    to find a clean syntax that fits in with indentation for block structure)
    but to pretend that it is anything other than a restriction insults the
    intelligence of your audience.

    Michael


    and, is there performance problems when you define a inner function in
    another function? (that's, that function will define every time you call
    the function or not?)
    A lambda, like an inner function, is recreated every time, so it's
    certainly no better than a named function.
    You should profile your program to prove there is really a performance
    degradation. And if there is - create a global function instead.

    Oleg.
    --
    Oleg Broytman http://phd.pp.ru/ phd at phd.pp.ru
    Programmers don't die, they just GOSUB without RETURN.
    _______________________________________________
    Python-ideas mailing list
    Python-ideas at python.org
    http://mail.python.org/mailman/listinfo/python-ideas


    --
    http://www.ironpythoninaction.com/
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: <http://mail.python.org/pipermail/python-ideas/attachments/20091019/b557962e/attachment.htm>
  • Steven D'Aprano at Oct 19, 2009 at 11:30 pm

    On Tue, 20 Oct 2009 09:33:48 am Michael Foord wrote:
    2009/10/19 Oleg Broytman <phd at phd.pp.ru>
    On Mon, Oct 19, 2009 at 10:28:58PM +0800, starwing wrote:
    Oleg Broytman ??????:
    Single-line lambdas are good enough,
    and if you need more - just create a named function.
    BUT, why we need a name? just to process something or make
    decide, sometimes code itself is enough.
    A multiline function is certainly not a simple piece of code; it
    requires documentation - docstring, comments - and the name is a
    part of the documentation.
    Having used languages that allow multiline anonymous functions (C#,
    Javascript) I have to say that they *can* improve the readability of
    code.
    Given the difficulty in testing such anonymous functions, what do they
    do to the correctness of programs?


    Being forced to define functions ahead of where they belong in
    the logical flow of the program is not a feature of Python but a
    restriction.
    I don't see that this restriction is worth the hours and hours people
    have spent on it. If I have code like this:


    function(1, None, True, { # define an anonymous dict
    'a': set([1, 2, 4, 8, ...],
    'b': set([2, 4, 6, 9, 12, 16, 20, ...],
    'c': set([1234, 1342, 1432, ...],
    ...
    'z': set([12, 99, 151, 153, 745, ...])
    }, flag, count=4, parrot='red')

    with a complicated data argument, then I can write it as an anonymous
    variable, but it actually hurts readability to do so. There's no
    problem with creating an anonymous dict of any complexity I like, but
    for readability and correctness I'm better off pulling it out of the
    function call and giving it a name:

    d = {
    'a': set([1, 2, 4, 16, 128, ...],
    'b': set([2, 4, 6, 9, 12, 16, 20, ...],
    'c': set([1234, 1342, 1432, ...],
    ...
    'z': set([12, 99, 151, 153, 745, ...])
    }
    # print d
    function(1, None, True, d, flag, count=4, parrot='red')

    In fact, if it's that complicated, I'm better off creating a function to
    generate it, so I can test it:

    function(1, None, True, d_factory(), flag, count=4, parrot='red')


    My point is that when it comes to data, we have anonymous data that is
    easy and straightforward to define, and yet we *still* prefer to give
    data names and define it ahead of where we use it. So why is code
    different? Why does defining code ahead of where you use it such a bad
    thing that the lambda restriction generates so much attention?



    --
    Steven D'Aprano
  • Masklinn at Oct 20, 2009 at 8:42 am

    On 20 Oct 2009, at 01:30 , Steven D'Aprano wrote:
    Given the difficulty in testing such anonymous functions, what do they
    do to the correctness of programs?
    Nothing different than what `with` or `while` statements do.
    My point is that when it comes to data, we have anonymous data that is
    easy and straightforward to define, and yet we *still* prefer to give
    data names and define it ahead of where we use it.
    Not in every case.
    So why is code different?
    Why indeed? As you said above, we have anonymous data that is easy and
    straightforward to define, why treat code differently and prevent this
    even when that code is just as easy and straightforward to define?
  • Jim Jewett at Oct 22, 2009 at 12:28 am

    On Mon, Oct 19, 2009 at 7:30 PM, Steven D'Aprano wrote:
    On Tue, 20 Oct 2009 09:33:48 am Michael Foord wrote:

    Having used languages that allow multiline anonymous functions (C#,
    Javascript) I have to say that they *can* improve the readability of
    code.
    Could you provide some examples? I've seen plenty of usage in
    Javascript, but none that I would personally judge as improving
    readability -- and many that hurt badly. Even if this turns out to be
    a personal preference thing (some people think it is better, others
    just don't happen to agree), the advantage is likely small enough that
    it is outweighed by the advantages of standardization. (I've seen
    many people claim that the advantages are huge, but the people making
    such claims often turn out not to be familiar with nested functions.)
    Given the difficulty in testing such anonymous functions, what do they
    do to the correctness of programs?
    Anonymity of functions is generally not the biggest source of problems
    in Javascript. With C compilers, there is pressure to conform to the
    standard; with Javascript interpreters there is pressure to support
    existing broken content without any manual intervention (so no
    compiler switches).

    The major goal of HTML5 is to at least document and standardize the
    idiotic workarounds that are required to do that when parsing a web
    page labeled as HTML; there are similar, less advanced, plans for
    Javascript and the Browser Object Model, but ... I suspect "untested
    environment" will continue to be a much bigger issue for at least half
    a decade.
    Being forced to define functions ahead of where they belong in
    the logical flow of the program is not a feature of Python but a
    restriction.
    Agreed.

    But I have never felt the urge to read (as opposed to write) a full
    definition in the middle of call. (And if you aren't in the middle of
    a call, then the previous line isn't really that far ahead.)

    I have wished to just pass a name, and define the function later; the
    fact that I can't always do that is a quirk of python's execution
    model, but adding anonymous functions wouldn't help. And any syntax
    heavier than a single keyword would probably add so much noise that it
    would be worse than the out-of-order effect.

    In other words, I could understand the value of

    f(a, 5, delay g, "asdf")
    def g(x): return x

    But the cost is already high enough to make me unsure that it would be
    a worthwhile feature.

    My point is that when it comes to data, we have anonymous data that is
    easy and straightforward to define, and yet we *still* prefer to give
    data names and define it ahead of where we use it. So why is code
    different? Why does defining code ahead of where you use it such a bad
    thing that the lambda restriction generates so much attention?
    Data is static -- it just sits there. A name makes it shrink (in
    mental cost) but has no other effect -- it is like putting physical
    objects in a suitcase and zipping the thing shut.

    A function is part of the instructions; defining it somewhere else is
    like setting a bookmark to follow a footnote -- and then having to
    come back.

    That said, I suspect that much of the actual attention is from
    misunderstandings.

    -jJ
  • Stephen J. Turnbull at Oct 20, 2009 at 5:14 am
    Michael Foord writes:
    I accept that it is a necessary restriction in Python
    I agree with your point that it is a restriction. But the connotation
    of "necessary" that it would be desirable to relax it if there were a
    good syntax, I don't know about that.

    Up to about ten years ago, I used lambda in Lisp code a lot. Since
    then I've found that use cases are being pried from my grasp one by
    one. I find nowadays that even one-liners that are simply currying a
    multiargument function are more readable when defined as named
    functions.
  • Ben Finney at Oct 19, 2009 at 8:50 pm

    starwing <weasley_wx at qq.com> writes:

    Oleg Broytman ??:
    Single-line lambdas are good enough, and if you need more - just
    create a named function.
    BUT, why we need a name? just to process something or make decide,
    sometimes code itself is enough.
    When the code is more complex than a single expression, it's already
    complex enough that defining it first and then referring to it makes for
    clearer code.
    and, is there performance problems when you define a inner function in
    another function? (that's, that function will define every time you
    call the function or not?)
    Measure the performance difference in your specific code base and decide
    on that basis.

    If there are such problems, then the lambda form won't help you: it
    defines a function of exactly the same type as what ?def? defines.

    --
    \ ?I don't like country music, but I don't mean to denigrate |
    `\ those who do. And for the people who like country music, |
    _o__) denigrate means ?put down?.? ?Bob Newhart |
    Ben Finney
  • Masklinn at Oct 19, 2009 at 9:04 pm

    On 19 Oct 2009, at 22:50 , Ben Finney wrote:
    starwing <weasley_wx at qq.com> writes:
    Oleg Broytman ??:
    Single-line lambdas are good enough, and if you need more - just
    create a named function.
    BUT, why we need a name? just to process something or make decide,
    sometimes code itself is enough.
    When the code is more complex than a single expression, it's already
    complex enough that defining it first and then referring to it makes
    for
    clearer code.
    That sounds quite recursive. Is it a hard rule or are you allowed to
    write three consecutive statements or expressions in some cases?
  • Nick Coghlan at Oct 19, 2009 at 10:00 pm

    Masklinn wrote:
    On 19 Oct 2009, at 22:50 , Ben Finney wrote:
    starwing <weasley_wx at qq.com> writes:
    Oleg Broytman ??:
    Single-line lambdas are good enough, and if you need more - just
    create a named function.
    BUT, why we need a name? just to process something or make decide,
    sometimes code itself is enough.
    When the code is more complex than a single expression, it's already
    complex enough that defining it first and then referring to it makes for
    clearer code.
    That sounds quite recursive. Is it a hard rule or are you allowed to
    write three consecutive statements or expressions in some cases?
    The difference lies largely in whether or not you are bundling up that
    code and giving it to another piece of code to use.

    For myself, I don't actually agree it's a valid design rule - I think
    anonymous blocks have legitimate use cases (see Ars Technica's writeup
    of the Apple's new Grand Central Dispatch and C-level anonymous block
    system in OS X 10.6).

    However, for Python, the idea of having anonymous blocks runs headlong
    into the use of indentation for block delineation. You have to either
    come up with a non-indentation based syntax for the statements inside
    the anonymous blocks, essentially inventing a whole new language, or you
    have to embed significant whitespace inside an expression rather than
    only having it between statements.

    Nobody has come up with a solution to that mismatch which is superior to
    just naming the block and using a normal def statement to create it.

    Cheers,
    Nick.

    --
    Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
    ---------------------------------------------------------------
  • Stephen J. Turnbull at Oct 20, 2009 at 5:37 am
    Nick Coghlan writes:
    For myself, I don't actually agree it's a valid design rule - I think
    anonymous blocks have legitimate use cases (see Ars Technica's writeup
    of the Apple's new Grand Central Dispatch and C-level anonymous block
    system in OS X 10.6).
    That doesn't look like what "anonymous block" means to me. It looks
    like a lambda.

    The difference is that an block resolves all its non-argument
    references in the calling context, eg, as a C macro without arguments
    would. But I don't see how you can assign a C macro to a variable and
    call it at runtime....

    Now, the cases that Ruby programmers I know always propose to me as
    use cases for anonymous blocks rely on conventions for naming certain
    objects used by their blocks (typically iteration variables), thus
    avoiding the need to specify arguments for them. So a block seems to
    be a conventional way of currying a more general function to the
    context of a specific suite.
  • Masklinn at Oct 20, 2009 at 8:46 am

    On 20 Oct 2009, at 07:37 , Stephen J. Turnbull wrote:
    Nick Coghlan writes:
    For myself, I don't actually agree it's a valid design rule - I think
    anonymous blocks have legitimate use cases (see Ars Technica's
    writeup
    of the Apple's new Grand Central Dispatch and C-level anonymous block
    system in OS X 10.6).
    That doesn't look like what "anonymous block" means to me. It looks
    like a lambda.
    An anonymous block and a lambda are the exact same thing.
    The difference is that an block resolves all its non-argument
    references in the calling context
    Are you talking about forming closures here?
    Now, the cases that Ruby programmers I know always propose to me as
    use cases for anonymous blocks rely on conventions for naming certain
    objects used by their blocks (typically iteration variables)
    Please forgive my disbelief but "what?" Ruby's blocks take arguments
    (they're fundamentally nothing more than anonymous functions), I've
    never encountered a case where "anonymous blocks [relied] on
    conventions for naming certain objects used within their blocks".
    thus avoiding the need to specify arguments for them.
    See above. Some languages (Scala for instance) have "magical
    placeholders" to avoid having to name arguments (`_*3` is equivalent
    to `i => i*3`) but that's pretty much the extent of it.
    So a block seems to
    be a conventional way of currying a more general function to the
    context of a specific suite.
    And I don't know what to make of that one either. Blocks don't have
    any more to do with currying than functions in general do.
  • Stephen J. Turnbull at Oct 20, 2009 at 6:23 pm

    Masklinn writes:
    On 20 Oct 2009, at 07:37 , Stephen J. Turnbull wrote:

    That doesn't look like what "anonymous block" means to me. It looks
    like a lambda.
    > >
    An anonymous block and a lambda are the exact same thing.
    <WHINE>
    Why use different names for them, then? At least when discussing
    Python which calls the concept "lambda"?
    </WHINE>
    The difference is that an block resolves all its non-argument
    references in the calling context
    Are you talking about forming closures here?
    No, I'm talking about the exact opposite, I think. Let's forget Ruby,
    since we're talking about anonymous functions after all, and what I
    "know" about Ruby is all hearsay (and evidently not correctly
    understood at that). In Lisp, you can do something like this:

    (defvar i)
    (defvar f (lambda () (print i)))
    (do ((i 10 (- i 1)))
    ((< i 1))
    (funcall f))

    outputting 10 9 8 7 6 5 4 3 2 1 and returning nil. Ie, it was my
    understanding of "block" that free variables in the block have what in
    Lisp is called "dynamic scope".
    So a block seems to be a conventional way of currying a more
    general function to the context of a specific suite.
    That was a brain bubble, sorry.
  • Masklinn at Oct 20, 2009 at 6:45 pm

    On 20 Oct 2009, at 20:23 , Stephen J. Turnbull wrote:
    Masklinn writes:
    On 20 Oct 2009, at 07:37 , Stephen J. Turnbull wrote:

    That doesn't look like what "anonymous block" means to me. It looks
    like a lambda.
    An anonymous block and a lambda are the exact same thing.
    <WHINE>
    Why use different names for them, then? At least when discussing
    Python which calls the concept "lambda"?
    </WHINE>
    One reason is that the creators of Smalltalk liked renaming stuff. A
    more serious one is that as far as they were concerned, they were
    manipulating code blocks. There are only two places in Smalltalk where
    you can have code (apart from the Workspace, which is equivalent to a
    Python shell): methods (method bodies in Python) and blocks (lambdas).
    Since there are no statements and if/for/while/try/whatever are
    implemented through messages (method calls) and anonymous functions,
    it made sense to use the term blocks to designate, well, blocks. Of
    code.
    No, I'm talking about the exact opposite, I think. Let's forget Ruby,
    since we're talking about anonymous functions after all, and what I
    "know" about Ruby is all hearsay (and evidently not correctly
    understood at that). In Lisp, you can do something like this:

    (defvar i)
    (defvar f (lambda () (print i)))
    (do ((i 10 (- i 1)))
    ((< i 1))
    (funcall f))

    outputting 10 9 8 7 6 5 4 3 2 1 and returning nil. Ie, it was my
    understanding of "block" that free variables in the block have what in
    Lisp is called "dynamic scope".
    In most languages (that I know of), free variables come from the
    lexical scope not the dynamic one (apart from a pair of lisps, I know
    of no language using a dynamic scope). However as I'm not sure what
    precisely happens in your code `i` could be the same in the lexical
    and the dynamic scope so?

    Using Python's syntax:

    def foo():
    i = 5
    return lambda: i

    def bar(fn):
    i = "d"
    print fn()

    fn = foo()
    bar(fn)

    here, if the language is lexically scoped the last line will print "5"
    whereas if it's dynamically scoped it will print "d". In pretty much
    every language I know (and that includes Ruby and Smalltalk) it will ?
    as in Python ? print "5".
  • Nick Coghlan at Oct 20, 2009 at 11:04 am

    Stephen J. Turnbull wrote:
    Nick Coghlan writes:
    For myself, I don't actually agree it's a valid design rule - I think
    anonymous blocks have legitimate use cases (see Ars Technica's writeup
    of the Apple's new Grand Central Dispatch and C-level anonymous block
    system in OS X 10.6).
    That doesn't look like what "anonymous block" means to me. It looks
    like a lambda.
    The difference lies in the fact that in C, object references are
    non-local by default - you have to declare them explicitly in the
    current scope to make them local.

    Hence the code you stick inline in Apple's new C extensions can
    manipulate locals as if it were just a normal part of the current function.

    Accordingly, I find the idea of a new function-like construct where all
    non-argument variable references are nonlocal by default to be a
    potentially interesting one.

    It has nothing to do with Python's inherent syntax problems with nesting
    statements inside expressions though, which is the reason I snipped that
    digression from my previous message.

    Cheers,
    Nick.

    --
    Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
    ---------------------------------------------------------------
  • Masklinn at Oct 20, 2009 at 8:36 am

    On 20 Oct 2009, at 00:00 , Nick Coghlan wrote:
    However, for Python, the idea of having anonymous blocks runs headlong
    into the use of indentation for block delineation.
    I'm not sure that's the case, Haskell uses indentation for block
    delineation too and doesn't (as far as I know, I might be wrong)
    impose further restrictions on anonymous functions than on named ones.

    Though this might have to do with?
    You have to [?] embed significant whitespace inside an expression
    rather than
    only having it between statements.
    haskell only dealing with expressions and not with statements, thus
    "blocks" are expressions and it doesn't have to deal with a mismatch
    between statements and expressions.
  • Ben Finney at Oct 19, 2009 at 10:05 pm

    Masklinn <masklinn at masklinn.net> writes:
    On 19 Oct 2009, at 22:50 , Ben Finney wrote:
    When the code is more complex than a single expression, it's already
    complex enough that defining it first and then referring to it makes
    for clearer code.
    That sounds quite recursive.
    Where's the recursion? I'm not defining complexity in terms of
    complexity, if that's what you mean; I'm noting that a threshold on one
    continuum is located around the same place as a threshold on another.
    Is it a hard rule or are you allowed to write three consecutive
    statements or expressions in some cases?
    Of course it's not a hard rule; it's a rule of thumb, if you like.

    --
    \ ?Either he's dead or my watch has stopped.? ?Groucho Marx |
    `\ |
    _o__) |
    Ben Finney
  • Steven D'Aprano at Oct 19, 2009 at 11:06 pm

    On Tue, 20 Oct 2009 01:04:47 am Oleg Broytman wrote:
    On Mon, Oct 19, 2009 at 09:33:06PM +0800, starwing wrote:
    current lambda only support single line
    syntax. it's not very good.
    This is where you've made an error. Single-line lambdas are good
    enough, and if you need more - just create a named function.

    Oleg.

    Actually, lambda isn't limited to a single line, but to a single
    expression, and expressions can go over multiple lines:
    data = [1, 2, 3, 4]
    map(lambda n: (
    ... n**3 - # comment goes here
    ... n**2 +
    ... n + 1), data)
    [2, 7, 22, 53]

    http://docs.python.org/reference/expressions.html#lambda


    The only limitation is that the lambda syntax is limited to a single
    expression, which means you can't call statements.

    If your "anonymous code block" is more complicated than a single short
    expression, it's too complicated to be "obviously correct" just from
    looking at it, and so it should be documented and tested. The
    restriction on lambda forces people to move the code block into a named
    function, which has the happy consequence of encouraging documentation
    and testing.



    --
    Steven D'Aprano
  • Masklinn at Oct 20, 2009 at 8:39 am

    On 20 Oct 2009, at 01:06 , Steven D'Aprano wrote:
    If your "anonymous code block" is more complicated than a single short
    expression, it's too complicated to be "obviously correct" just from
    looking at it, and so it should be documented and tested.
    I have the same issue with this as with Oleg's pronouncement (which
    runs along the same lines): does that mean you never write for or if
    statements with more than a single line in them?

    Yet these are also "anonymous code blocks" which you say here are "too
    complicated to be obviously correct just from looking at [them]".

    If that's the case, why should compound statements even be allowed?
    They're breeding grounds for multiline anonymous blocks of code?
  • Steven D'Aprano at Oct 20, 2009 at 11:21 am

    On Tue, 20 Oct 2009 07:39:44 pm Masklinn wrote:
    On 20 Oct 2009, at 01:06 , Steven D'Aprano wrote:
    If your "anonymous code block" is more complicated than a single
    short expression, it's too complicated to be "obviously correct"
    just from looking at it, and so it should be documented and tested.
    I have the same issue with this as with Oleg's pronouncement (which
    runs along the same lines): does that mean you never write for or if
    statements with more than a single line in them?
    No, you are correct, my statement is overly strong. Please insert "very
    likely" between "it's" and "too complicated".

    Yet these are also "anonymous code blocks" which you say here are
    "too complicated to be obviously correct just from looking at
    [them]".

    If that's the case, why should compound statements even be allowed?
    They're breeding grounds for multiline anonymous blocks of code?
    There is at least one difference between compound statements and
    multi-statement anonymous code blocks:

    You don't pass compound statements around as input to other functions,
    so you know the environment that they're being called in, and can more
    easily reason about their correctness.

    But even then, compound statements are good candidates for being
    converted into named functions too. I usually start with something like
    this:

    if cond:
    do this
    do that
    do something else
    fe
    fi
    fo
    fum
    ...
    else:
    one fish
    two fish
    red fish
    blue fish
    ...

    and by the time I'm finished I've got something like this:

    if cond:
    call_one()
    else:
    call_two()

    The multi-line blocks are split into functions, each with their own
    documentation and tests.

    Of course I don't do this literally every single time. There's no hard
    rule about how many lines are allowed, just like there's no hard rule
    about how complex a data structure can be before you give it a name.
    But my point is that the restriction on lambda is not an odious one, or
    at least not so odious that it deserves the amount of heat that it
    generates. There are uses for multi-statement anonymous functions, but
    there is nothing that an anonymous function can do that a named
    function can't.[1]

    In my opinion, it simply isn't enough of a burden to define a function
    before you use it, using a "don't care" name, to deserve the amount of
    words written about potential multi-statement lambda syntax. If Python
    had different syntax, then perhaps we'd have anonymous functions like
    Ruby. But we don't, and frankly I don't think it is much of a
    restriction.






    [1] Some way to write an anonymous code block, which isn't a function
    and simply runs in the local environment where it is called as if it
    were written in-line, would be more interesting to me.


    --
    Steven D'Aprano
  • Masklinn at Oct 20, 2009 at 11:34 am

    On 20 Oct 2009, at 13:21 , Steven D'Aprano wrote:
    You don't pass compound statements around as input to other functions,
    so you know the environment that they're being called in, and can more
    easily reason about their correctness.
    But unless the language is dynamically scoped (which is getting pretty
    rare these days, and which Python definitely isn't) the environment in
    which the block is executed is not quite relevant, since the free
    variables are bound based on its lexical scope (the environment in
    which the block is created) and the rest is made of argument (as in
    every other function).
    In my opinion, it simply isn't enough of a burden to define a function
    before you use it, using a "don't care" name, to deserve the amount of
    words written about potential multi-statement lambda syntax. If Python
    had different syntax, then perhaps we'd have anonymous functions like
    Ruby. But we don't, and frankly I don't think it is much of a
    restriction.
    The biggest (by far) advantages I see to good anonymous functions
    (note: Ruby's aren't, as far as I'm concerned, because due to their
    nature they don't easily scale from 1/call to 2+/call) are in
    flexibility, freedom of experimentation and possibility to keep the
    core language itself small: had Python had "full-blown" anonymous
    functions, it wouldn't have been necessary to add the `with` statement
    to the language. It could just as well have been implemented through a
    protocol or the stdlib, and people would have been free to toy with it
    in their projects long before it was added to the core language.

    It also gives the possibility of making OO much less imperative (right
    now if one wants customized code paths, one usually has to rely on
    extracting data from objects, performing imperative operations and
    then feeding the result back to some other object, but objects could
    just as well provide "hooks" thought callables), and of creating
    custom control structures (see `with` above, but it applies to far
    more stuff).

    In fact, Smalltalk quite clearly demonstrated that with messages
    (method calls) and blocks (anonymous functions) you basically didn't
    need "hard-coded" control structures anymore. Now Smalltalk probably
    went a bit too far for most people, even 30 years later, but it does
    show how powerful this combination is, and how it allows the
    language's users to evolve the language itself, without having to
    change its core syntax.
  • Oleg Broytman at Oct 20, 2009 at 11:49 am

    On Tue, Oct 20, 2009 at 01:34:11PM +0200, Masklinn wrote:
    Now Smalltalk probably went a
    bit too far for most people, even 30 years later
    This is The Reason Number Two - there have to be a balance between what
    features are accepted in the language and what are rejected. Python
    developers decided that anonymous code blocks are allowed in a few special
    places and are forbidden generally.
    IWBN to have a PEP listing all pro et contra arguments so we don't
    need to repeat the same arguments over and over.

    Oleg.
    --
    Oleg Broytman http://phd.pp.ru/ phd at phd.pp.ru
    Programmers don't die, they just GOSUB without RETURN.
  • Masklinn at Oct 20, 2009 at 11:54 am

    On 20 Oct 2009, at 13:49 , Oleg Broytman wrote:
    On Tue, Oct 20, 2009 at 01:34:11PM +0200, Masklinn wrote:
    Now Smalltalk probably went a
    bit too far for most people, even 30 years later
    This is The Reason Number Two
    Erm? what was reason number one?
    - there have to be a balance between what
    features are accepted in the language and what are rejected. Python
    developers decided that anonymous code blocks are allowed in a few
    special
    places and are forbidden generally.
    Have they? I've seen the decision that anonymous functions generally
    aren't allowed to be useful, but there are anonymous code blocks
    everywhere. You just can't pass them around.
  • Oleg Broytman at Oct 20, 2009 at 12:13 pm

    On Tue, Oct 20, 2009 at 01:54:59PM +0200, Masklinn wrote:
    On 20 Oct 2009, at 13:49 , Oleg Broytman wrote:
    On Tue, Oct 20, 2009 at 01:34:11PM +0200, Masklinn wrote:
    Now Smalltalk probably went a
    bit too far for most people, even 30 years later
    This is The Reason Number Two
    Erm? what was reason number one?
    http://www.python.org/dev/peps/pep-3099/#core-language

    "multi-line arguments to function calls, for instance. That is just
    plain ugly."

    My argument about anonymous/named functions is a part of the explanation
    for the ugliness.
    - there have to be a balance between what
    features are accepted in the language and what are rejected. Python
    developers decided that anonymous code blocks are allowed in a few
    special
    places and are forbidden generally.
    Have they? I've seen the decision that anonymous functions generally
    aren't allowed to be useful, but there are anonymous code blocks
    everywhere. You just can't pass them around.
    The number of compound statements in Python is pretty low. def, for, if,
    try, with, while.

    A PEP, please?

    Oleg.
    --
    Oleg Broytman http://phd.pp.ru/ phd at phd.pp.ru
    Programmers don't die, they just GOSUB without RETURN.
  • Mike Meyer at Oct 21, 2009 at 12:02 am

    On Tue, 20 Oct 2009 15:49:58 +0400 Oleg Broytman wrote:

    This is The Reason Number Two - there have to be a balance between what
    features are accepted in the language and what are rejected. Python
    developers decided that anonymous code blocks are allowed in a few special
    places and are forbidden generally.
    They did? Where? The closest I've seen is that multi-line expressions
    - and in particular function invocations - are ugly, so reject any
    feature that allows them - which generally includes anonymous code
    blocks - will probably be rejected. This does leave open the
    possibility of anonymous code blocks being acceptable providing the
    syntax avoids that problem area.

    <mike
    --
    Mike Meyer <mwm at mired.org> http://www.mired.org/consulting.html
    Independent Network/Unix/Perforce consultant, email for more information.

    O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
  • Mike Meyer at Oct 20, 2009 at 11:57 pm

    On Tue, 20 Oct 2009 13:34:11 +0200 Masklinn wrote:
    The biggest (by far) advantages I see to good anonymous functions
    (note: Ruby's aren't, as far as I'm concerned, because due to their
    nature they don't easily scale from 1/call to 2+/call) are in
    flexibility, freedom of experimentation and possibility to keep the
    core language itself small: had Python had "full-blown" anonymous
    functions, it wouldn't have been necessary to add the `with` statement
    to the language. It could just as well have been implemented through a
    protocol or the stdlib, and people would have been free to toy with it
    in their projects long before it was added to the core language.
    Note that this is a two edged sword, in that all those people "toying"
    with "with"-like constructs might also be publishing code using them,
    meaning that instead of having one clean construct from the core
    developers, we'd have to deal with an unknown number of variant idioms
    from most anybody.

    A small core language doesn't help a lot when you have to know four or
    five different ways to build some basic construct because it's not in
    the core language.

    <mike
    --
    Mike Meyer <mwm at mired.org> http://www.mired.org/consulting.html
    Independent Network/Unix/Perforce consultant, email for more information.

    O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
  • Nick Coghlan at Oct 21, 2009 at 11:38 am

    Mike Meyer wrote:
    On Tue, 20 Oct 2009 13:34:11 +0200
    Masklinn wrote:
    The biggest (by far) advantages I see to good anonymous functions
    (note: Ruby's aren't, as far as I'm concerned, because due to their
    nature they don't easily scale from 1/call to 2+/call) are in
    flexibility, freedom of experimentation and possibility to keep the
    core language itself small: had Python had "full-blown" anonymous
    functions, it wouldn't have been necessary to add the `with` statement
    to the language. It could just as well have been implemented through a
    protocol or the stdlib, and people would have been free to toy with it
    in their projects long before it was added to the core language.
    Note that this is a two edged sword, in that all those people "toying"
    with "with"-like constructs might also be publishing code using them,
    meaning that instead of having one clean construct from the core
    developers, we'd have to deal with an unknown number of variant idioms
    from most anybody.

    A small core language doesn't help a lot when you have to know four or
    five different ways to build some basic construct because it's not in
    the core language.
    Yup, this is certainly one of the concerns with making it too easy for
    developers to invent their own syntax (and also why Guido has flatly
    ruled out a macro system for Python).

    The bar for anonymous blocks is a high one, because:

    1. Once an anonymous block syntax is accepted into the language we're
    pretty much stuck with it

    2. While it does exist, the use case gap between anonymous functional
    expressions (i.e. the current lambda) and full named functions is pretty
    narrow (especially since the introduction of true conditional
    expressions on the lambda side).

    3. Code is written once and read often. Anonymous blocks run a high risk
    of getting this back to front by making code easier to write but harder
    to read.

    The main point in favour of anonymous blocks of some kind is that having
    to define the subfunction before using it often *will* get the order of
    the code as written out of whack with respect to the order that makes
    the most logical sense. Both decorators and the with statement involved
    large elements of "don't leave important information trailing at the end
    where a reader may easily miss it" so it is an argument with some merit.

    Since it is a valid point that this can happen with arbitrary complex
    data objects rather than solely with named functions, one past proposal
    (PEP 359, the 'make' statement) involved attaching a suite to a function
    call, then providing the contents of that suite as a dictionary argument
    to the function being invoked. (Using the namespace to provide keyword
    arguments instead would allow a new construct to be used with existing
    functions, but would significantly constrain the use of temporary
    variables that weren't intended for use a arguments to the function
    (then again, that already happens with normal class definitions, and the
    del statement seems to handle that just fine).

    I should note that Guido ended up killing that PEP because he didn't
    like it, but I still believe some kind of "do this, but only after
    running this other suite first" out of order execution construct is more
    likely to gain acceptance than trying to come up with a full anonymous
    block syntax.

    However, nobody has suggested a particular nice syntax for that idea
    either, so, again it is unlikely to go anywhere anytime soon.

    Cheers,
    Nick.

    --
    Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
    ---------------------------------------------------------------
  • Guido van Rossum at Oct 21, 2009 at 4:56 pm

    On Wed, Oct 21, 2009 at 4:38 AM, Nick Coghlan wrote:
    The main point in favour of anonymous blocks of some kind is that having
    to define the subfunction before using it often *will* get the order of
    the code as written out of whack with respect to the order that makes
    the most logical sense.
    I actually don't buy that argument. I believe that the main reason
    people keep arguing for anonymous blocks (and this will never stop) is
    simply that there is a certain segment of the programmer population
    that is used to solving a large variety of problems with anonymous
    blocks and that they don't want to learn how to solve each of those
    cases using the existing tools in Python.

    See also my proposal of a moratorium on language changes.

    --
    --Guido van Rossum (home page: http://www.python.org/~guido/)
  • Sturla Molden at Oct 22, 2009 at 8:49 am

    Guido van Rossum skrev:
    I actually don't buy that argument. I believe that the main reason
    people keep arguing for anonymous blocks (and this will never stop) is
    simply that there is a certain segment of the programmer population
    that is used to solving a large variety of problems with anonymous
    blocks and that they don't want to learn how to solve each of those
    cases using the existing tools in Python.
    I think anonymous blocks have proven their usefulness in concurrency
    programming. Just take a look at OpenMP or Apple's GCD. But I'll make an
    argument against anonymous blocks anyway:

    We can create "anonymous" blocks by throw-away names like "def _()", but
    why clutter the scope with names that are never used? So assume we would
    allow write "def():" to designate an anonymous block. I think 99% would
    abuse it like this:

    name = def():
    <suite>

    This could just as well be written:

    def name():
    <suite>

    Thus, certainly "name = def():" should not be allowed.

    If that is not allowed then, an anynymous block cannot be called or
    referenced, as there are no name associated with it. So to be useful, it
    would always have to be associated with a decorator. That would be the
    only way to get access to it:

    @decorator
    def():
    <suite>

    Now we can see that the use for this anonymous block "def()" simply goes
    away, as it too is redundant syntax.

    Then it all comes down to whether or not allow decorators on code blocks:

    @decorator
    <suite>

    Since blocks do not create new scopes, I think the answer should be "no".



    S.M.
  • Steven D'Aprano at Oct 23, 2009 at 2:30 am

    On Thu, 22 Oct 2009 07:49:14 pm Sturla Molden wrote:

    If that is not allowed then, an anynymous block cannot be called or
    referenced, as there are no name associated with it.
    That is clearly wrong. You don't need a name to call an object. You just
    need the object.
    (lambda x: x+1)(42)
    43
    [None, lambda s: s.upper(), None][1]('abc')
    'ABC'


    So to be useful,
    it would always have to be associated with a decorator. That would
    be the only way to get access to it:

    @decorator
    def():
    <suite>
    That doesn't even make sense to me. I don't understand what the
    decorator is doing there, or how it helps you access the anonymous
    function. Under today's semantics (modified to allow anonymous def),
    that would create an anonymous function containing <suite>, then pass
    that function to decorator(), and treat the return result as anonymous.
    Since you're not keeping a reference to the anonymous function, it will
    then be garbage collected. Passing it into a decorator first won't
    change that (unless the decorator stores the function somewhere as a
    side-effect).

    In other words, the above is just like this:

    decorator(lambda: <suite>)

    which is legal but pointless unless you do something with the result.


    Now we can see that the use for this anonymous block "def()" simply
    goes away, as it too is redundant syntax.
    Why? Functions aren't the only thing you can apply decorators to. You
    can also call:

    @decorator
    class K:
    pass

    in Python 2.6 and better.



    --
    Steven D'Aprano
  • Jim Jewett at Oct 22, 2009 at 12:41 am

    On Tue, Oct 20, 2009 at 7:34 AM, Masklinn wrote:
    But unless the language is dynamically scoped (which is getting pretty rare
    these days, and which Python definitely isn't)
    err ... current python. I believe that changed around python 2.2.

    I've wanted a way to reverse that more often than I've wanted a way to
    avoid naming a function. (I originally wrote "far more", but ... the
    urge doesn't actually come up most years, so maybe it was a solution
    finding a problem.)
    The biggest (by far) advantages I see to good anonymous functions (note:
    Ruby's aren't, as far as I'm concerned, because due to their nature they
    don't easily scale from 1/call to 2+/call) are in flexibility, freedom of
    experimentation and possibility to keep the core language itself small: had
    Python had "full-blown" anonymous functions, it wouldn't have been necessary
    to add the `with` statement to the language.
    I'm not sure how the lack of a name buys you any of that. Callables
    as first-class objects that can be passed around, yes -- but naming
    them is fine. And to be honest, that flexibility and freedom seem
    like they would be amplified by dynamic scope, so that you could
    "tune" library functions by passing in arbitrary callables that could
    affect the "local" variables. The advantages of lexical scoping seem
    to be mostly about closures, rather than about extending an existing
    external function.

    Could you explain how (even named) multiline functions (as opposed to
    dynamic scope) would have served in place of "with:"?

    -jJ
  • Stephen J. Turnbull at Oct 22, 2009 at 7:00 am

    Jim Jewett writes:
    On Tue, Oct 20, 2009 at 7:34 AM, Masklinn wrote:
    But unless the language is dynamically scoped (which is getting pretty rare
    these days, and which Python definitely isn't)
    >
    err ... current python. I believe that changed around python 2.2. >
    I've wanted a way to reverse that more often than I've wanted a way to
    avoid naming a function.
    It's funny ... the language I use most is Emacs Lisp and that has
    taught me a severe aversion to dynamic scoping by default. Sometimes
    it's useful, but when I am using say Common Lisp an occasional defvar
    just isn't that painful. I don't think I've ever missed dynamic scope
    in Python since my first few days with it.
  • 小翼 at Oct 20, 2009 at 10:43 am
    Okay...but, Two--no, Three question:
    - is it necessary to implement it?
    - is it diffcult to implement it?
    - is it helps to import Python statement?

    if so, I will try to implement it (I'm trying to read the source of Python, but it sames too complicated :-(
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: <http://mail.python.org/pipermail/python-ideas/attachments/20091020/9175dd89/attachment.htm>

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-ideas @
categoriespython
postedOct 19, '09 at 1:33p
activeOct 23, '09 at 2:30a
posts37
users12
websitepython.org

People

Translate

site design / logo © 2018 Grokbase