Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #32076 > unrolled thread

Re: while expression feature proposal

Started byIan Kelly <ian.g.kelly@gmail.com>
First post2012-10-24 16:54 -0600
Last post2012-10-25 10:35 +0100
Articles 9 on this page of 29 — 11 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: while expression feature proposal Ian Kelly <ian.g.kelly@gmail.com> - 2012-10-24 16:54 -0600
    Re: while expression feature proposal Paul Rubin <no.email@nospam.invalid> - 2012-10-24 16:08 -0700
      Re: while expression feature proposal Ian Kelly <ian.g.kelly@gmail.com> - 2012-10-24 17:39 -0600
        Re: while expression feature proposal Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2012-10-25 09:21 +0200
          Re: while expression feature proposal Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2012-10-25 12:12 +0200
          Re: while expression feature proposal Ian Kelly <ian.g.kelly@gmail.com> - 2012-10-25 10:36 -0600
            Re: while expression feature proposal Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2012-10-25 22:49 +0200
              Re: while expression feature proposal Dan Loewenherz <dloewenherz@gmail.com> - 2012-10-25 22:12 -0700
                Re: while expression feature proposal Paul Rubin <no.email@nospam.invalid> - 2012-10-25 23:06 -0700
                  Re: while expression feature proposal Chris Angelico <rosuav@gmail.com> - 2012-10-26 17:23 +1100
                    Re: while expression feature proposal Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-10-26 09:43 +0000
                  Re: while expression feature proposal Dan Loewenherz <dloewenherz@gmail.com> - 2012-10-26 08:29 -0700
                    Re: while expression feature proposal Ian Kelly <ian.g.kelly@gmail.com> - 2012-10-26 09:42 -0600
                    Re: while expression feature proposal Paul Rubin <no.email@nospam.invalid> - 2012-10-26 09:10 -0700
                      Re: while expression feature proposal Cameron Simpson <cs@zip.com.au> - 2012-10-27 09:03 +1100
                      Re: while expression feature proposal Ian Kelly <ian.g.kelly@gmail.com> - 2012-10-26 16:48 -0600
                        Re: while expression feature proposal Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-10-27 00:07 +0000
                          Re: while expression feature proposal Paul Rubin <no.email@nospam.invalid> - 2012-10-26 20:43 -0700
                      Re: while expression feature proposal Tim Chase <sed@thechases.com> - 2012-10-26 18:26 -0500
                      Re: while expression feature proposal Devin Jeanpierre <jeanpierreda@gmail.com> - 2012-10-26 19:41 -0400
                  Re: while expression feature proposal Devin Jeanpierre <jeanpierreda@gmail.com> - 2012-10-26 19:19 -0400
                  Re: while expression feature proposal Chris Angelico <rosuav@gmail.com> - 2012-10-27 11:42 +1100
                Re: while expression feature proposal Devin Jeanpierre <jeanpierreda@gmail.com> - 2012-10-26 19:12 -0400
                  Re: while expression feature proposal Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-10-27 00:18 +0000
                    Re: while expression feature proposal Devin Jeanpierre <jeanpierreda@gmail.com> - 2012-10-26 20:27 -0400
                    Re: while expression feature proposal Tim Chase <python.list@tim.thechases.com> - 2012-10-27 14:15 -0500
                Re: while expression feature proposal Devin Jeanpierre <jeanpierreda@gmail.com> - 2012-10-26 19:51 -0400
          Re: while expression feature proposal Ian Kelly <ian.g.kelly@gmail.com> - 2012-10-25 10:47 -0600
      Re: while expression feature proposal Paul Rudin <paul.nospam@rudin.co.uk> - 2012-10-25 10:35 +0100

Page 2 of 2 — ← Prev page 1 [2]


#32243

FromDevin Jeanpierre <jeanpierreda@gmail.com>
Date2012-10-26 19:19 -0400
Message-ID<mailman.2913.1351293624.27098.python-list@python.org>
In reply to#32196
On Fri, Oct 26, 2012 at 2:23 AM, Chris Angelico <rosuav@gmail.com> wrote:
> while (client.spop("profile_ids") as profile_id) is not None:
>     print profile_id
>
> Why is everyone skirting around C-style assignment expressions as
> though they're simultaneously anathema and the goal? :)

Why should these two statements behave differently? :(

    with foo() as bar: bar.baz()
    with (foo() as bar): bar.baz()

I don't understand why everyone is so attached to this "as" syntax.
It's confusing because it behaves subtly differently than how it works
in "with", and it puts the variable on the wrong side of the
assignment operator.

(I've always been partial to ":=", personally.)

-- Devin

[toc] | [prev] | [next] | [standalone]


#32258

FromChris Angelico <rosuav@gmail.com>
Date2012-10-27 11:42 +1100
Message-ID<mailman.2926.1351298548.27098.python-list@python.org>
In reply to#32196
On Sat, Oct 27, 2012 at 10:19 AM, Devin Jeanpierre
<jeanpierreda@gmail.com> wrote:
> On Fri, Oct 26, 2012 at 2:23 AM, Chris Angelico <rosuav@gmail.com> wrote:
>> while (client.spop("profile_ids") as profile_id) is not None:
>>     print profile_id
>>
>> Why is everyone skirting around C-style assignment expressions as
>> though they're simultaneously anathema and the goal? :)
>
> Why should these two statements behave differently? :(
>
>     with foo() as bar: bar.baz()
>     with (foo() as bar): bar.baz()
>
> I don't understand why everyone is so attached to this "as" syntax.
> It's confusing because it behaves subtly differently than how it works
> in "with", and it puts the variable on the wrong side of the
> assignment operator.
>
> (I've always been partial to ":=", personally.)

I'm not attached to "as", myself. It puts the variable at the wrong
end, and feels backward compared to a convention that exists elsewhere
in the language (regular variable assignment). This is a much stronger
backwardness issue than the Python ternary operator (which is only
backward in comparison to other languages).

Personally, I'm quite happy with assignment itself being an
expression. But since that's unlikely to be directly accepted in
Python, I would be looking for something as general as possible -
something that can truly be used _anywhere_ - rather than a specific
while-statement enhancement. Capturing partial expression results is
an extremely convenient thing to do.

ChrisA

[toc] | [prev] | [next] | [standalone]


#32242

FromDevin Jeanpierre <jeanpierreda@gmail.com>
Date2012-10-26 19:12 -0400
Message-ID<mailman.2912.1351293180.27098.python-list@python.org>
In reply to#32194
On Fri, Oct 26, 2012 at 1:12 AM, Dan Loewenherz <dloewenherz@gmail.com> wrote:
> It seems the topic of this thread has changed drastically from the original message.
>
> 1) "while EXPR as VAR" in no way says that EXPR must be a boolean value. In fact, a use case I've run into commonly in web development is popping from a redis set. E.g.
>
>     client = StrictRedis()
>     while True:
>         profile_id = client.spop("profile_ids")
>         if not profile_id:
>             break
>         print profile_id
>
> In this case, profile_id is "None" when the loop breaks. It would be much more straightforward (and more Pythonic, IMO), to write:
>
>     client = StrictRedis()
>     while client.spop("profile_ids") as profile_id:
>         print profile_id

For loops are pythonic. You can do this in Python today:

    client = StrictRedis()
    for profile_id in iter(lambda: client.spop("profile_ids"), None):
        pass

I would like a better iter(), rather than a better while loop. It is
irritating to pass in functions that take arguments, and it is
impossible to, say, pass in functions that should stop being iterated
over when they return _either_ a None or a, say, False.

-- Devin

[toc] | [prev] | [next] | [standalone]


#32253

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-10-27 00:18 +0000
Message-ID<508b2858$0$29967$c3e8da3$5496439d@news.astraweb.com>
In reply to#32242
On Fri, 26 Oct 2012 19:12:17 -0400, Devin Jeanpierre wrote:

> I would like a better iter(), rather than a better while loop. It is
> irritating to pass in functions that take arguments, and it is
> impossible to, say, pass in functions that should stop being iterated
> over when they return _either_ a None or a, say, False.

Write a trivial helper function. Not everything has to be a one-liner or 
a built-in.

def iterate_until_none_or_false(func, *args, **kwargs):
    while True:
        x = func(*args, **kwargs)
        # Halt if x is None or False, but not other falsey values.
        if x is None or x is False:
            return
        yield x

for x in iterate_until_none_or_false(
        some_function, 1, 2, "c", spam="yummy"):
    process(x)



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#32257

FromDevin Jeanpierre <jeanpierreda@gmail.com>
Date2012-10-26 20:27 -0400
Message-ID<mailman.2925.1351297695.27098.python-list@python.org>
In reply to#32253
On Fri, Oct 26, 2012 at 8:18 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
>> I would like a better iter(), rather than a better while loop. It is
>> irritating to pass in functions that take arguments, and it is
>> impossible to, say, pass in functions that should stop being iterated
>> over when they return _either_ a None or a, say, False.
>
> Write a trivial helper function. Not everything has to be a one-liner or
> a built-in.

You are missing the point. I was suggesting that the use case of new
syntax might be satisfied instead by new functions, which are clearly
preferable to new syntax from the perspective your rebuttal comes
from.

Indeed, one could write those helper functions, and use them, without
any changes to Python being made at all!

-- Devin

[toc] | [prev] | [next] | [standalone]


#32289

FromTim Chase <python.list@tim.thechases.com>
Date2012-10-27 14:15 -0500
Message-ID<mailman.2944.1351365278.27098.python-list@python.org>
In reply to#32253
On 10/26/12 19:18, Steven D'Aprano wrote:
> def iterate_until_none_or_false(func, *args, **kwargs):
>     while True:
>         x = func(*args, **kwargs)
>         # Halt if x is None or False, but not other falsey values.
>         if x is None or x is False:
>             return
>         yield x
> 
> for x in iterate_until_none_or_false(
>         some_function, 1, 2, "c", spam="yummy"):
>     process(x)

I was initially a pretty strong advocate of the proposed "as"
syntax.  However, the more I've thought about it, the more I keep
coming back to how I've solved the problem in the past which is
mostly what Steven suggests here.  There are so many edge-cases and
warts in the "as" syntax; most of which disappear with this
generator+forloop:

- yielding/unpacking multiple results  each time: the "as" syntax
would get really ugly.  Do you test the whole result, or an element
of the result?

- knowing the stopping condition varies: is it when something is
False-ish (an empty string/tuple/list, False, None, etc)?  When it
"is None"?  When it is exactly "False"?

- the whole "x = (foo(bar) as result) if result else None" (or
should that be "x = result if (foo(bar) as result) else None"?)
style/discussion just really looks ugly to me.  Usually I find
Python code quite beautiful and this syntax doesn't resonate as
"beautiful".

To despite my previous excitement, I'm now neutral at best on a
limited "while TERM as VAR:" syntax.

I know this "being persuaded by rational arguments and changing
one's mind" thing is rare on the Intarwebs, so I hope I haven't
upset the natural balance of things too greatly. :-)

-tkc




[toc] | [prev] | [next] | [standalone]


#32248

FromDevin Jeanpierre <jeanpierreda@gmail.com>
Date2012-10-26 19:51 -0400
Message-ID<mailman.2919.1351295955.27098.python-list@python.org>
In reply to#32194
On Fri, Oct 26, 2012 at 7:41 PM, Dan Loewenherz <dloewenherz@gmail.com> wrote:
-- snip insanity --
>
> But this is yucky. I'd much rather have something a bit more clear to the
> reader.

That's why I said I wanted a better iter, not some equality-overriding
object strawman thing.

I was thinking more like this:

    for profile_id in iter(None)(client.spop, "profile_ids"):

or alternatively:

    for profile_id in iter(bool)(client.spop, "profile_ids"):

Or perhaps either as keyword arguments (which is the only reason I
curried iter).

The interesting case for in-place assignment is not here. This is a
trivial case. It's in cases like this:

    while True:
        x = foo(bar())
        if x is None: break
        if x % 2 == 0: break

        print x

Imagine doing that with iter. :)

-- Devin

[toc] | [prev] | [next] | [standalone]


#32148

FromIan Kelly <ian.g.kelly@gmail.com>
Date2012-10-25 10:47 -0600
Message-ID<mailman.2857.1351183692.27098.python-list@python.org>
In reply to#32093
On Thu, Oct 25, 2012 at 10:36 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
> On Thu, Oct 25, 2012 at 1:21 AM, Thomas Rachel
> <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
> wrote:
>>> j = next(j for j in iter(partial(randrange, n), None) if j not in
>>> selected)
>>
>>
>> This generator never ends. If it meets a non-matching value, it just skips
>> it and goes on.
>
> next() only returns one value.  After it is returned, the generator is
> discarded, whether it has ended or not.  If there were no valid values
> for randrange to select, then it would descend into an infinite loop.
> But then, so would the dropwhile and the original while loop.

To demonstrate that the code does in fact return:

>>> selected = set(range(5))
>>> n = 10
>>> from functools import partial
>>> from random import randrange
>>> j = next(j for j in iter(partial(randrange, n), None) if j not in selected)
>>> j
5

[toc] | [prev] | [next] | [standalone]


#32101

FromPaul Rudin <paul.nospam@rudin.co.uk>
Date2012-10-25 10:35 +0100
Message-ID<87d306nbbv.fsf@no-fixed-abode.cable.virginmedia.net>
In reply to#32080
Paul Rubin <no.email@nospam.invalid> writes:

> kind of ugly, makes me wish for a few more itertools primitives

JOOI, do you have specific primitives in mind?

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.python


csiph-web