I am all in for that proposal.


Let the construction:

    for element in iterable if condition:
        loop_body

mean:

    for element in iterable:
        if not condition: continue
        loop_body


However this construction may be abused (in a good way) to cause the `condition` be evaluated on every loop iteration. And this is exactly what we need for loop invariants.

    class InvariantError(AssertionError):
        pass

    def loop_invariant(condition:bool):
        if not condition:
            raise InvariantError
        return True

    for element in iterable if loop_invariant(condition):
        loop_body


We are killing 3 birds with 1 stone:

1. We are unifying normal loop syntax with list comprehension syntax.
2. We are adding a syntactic sugar for a very useful feature (filtering).
3. We are adding a means of specifying loop invariants where they belong.


To specify invariants on `while` loops we could do something like:

    while loop_invariant(condition) and running:
        loop_body

so no new syntax is needed.


With this syntax, annotatin loops with invariants would be possible without changing indentation.


haael



Hello Everyone,

If I've done this incorrectly, please let me know so that I can improve/revise. I'm new to the Python community and quite enjoy the more functional features of Python 3, but have I have a peeve about it. I'd like to propose and discuss the following enhancement to Python 3:
*
Consider the following trivial for-loop:*

chars=  "abcaaabkjzhbjacvb"
seek=  {'a','b','c'}
count=  0
for  ain  chars:
      if  ain  seek:
           count+=  1
Gross. Twice nested for a simple count.

/We could refactor the block like so:/

chars=  "abcaaabkjzhbjacvb"
seek=  {'a','b','c'}
count=  0
for  ain  filter(lambda  c:  cin  seek,  chars):  count+=  1

Which is all well and good, but doesn't quite read like English. It's verbose, too.

It also uses advanced concepts new programmers may not understand.

/We could do this:/

chars=  "abcaaabkjzhbjacvb"
seek=  {'a','b','c'}
count=  sum([1  for  ain  charsif  ain  seek])

However, this changes important semantics by creating an entire new list before summing.

Also, adding just one more expression to the most nested block thwarts that refactor.

I propose the following enhancement:

chars=  "abcaaabkjzhbjacvb"
seek=  {'a','b','c'}
count=  0
for  ain  charsif  ain  seek:  count+=  1

*What happened there?*

I've allowed a condition to follow the "for" construct without a colon or newline between.

/To be clear, this remains incorrect:/

chars = "abcaaabkjzhbjacvb" seek = {'a','b','c'} count = 0 for a in chars # No colon prior to the newlineifa inseek:count +=1

*Value proposal:*

I assert that the inlined 'if' condition pattern is superior to the alternative refactors.

Right now, the way to acquire an invariant in a more nasty loop would be:

for  ain  iterable:
      if  condition:
           continue

But this is messy and not particularly Pythonic.

The filter approach uses concepts that should not be necessary for this task.

The comprehension approach has different, undesirable semantics.

*Conclusion:*

I wanted to submit my thoughts here before getting too deep into this. Any input would be appreciated!

Thanks everyone.





_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/A2PTKIJX5XY6Y2ZH7RAZJPGLFJDHTF5S/
Code of Conduct: http://python.org/psf/codeofconduct/

_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/FW5YJHRJEEQXFFCM2XQQL4CUIH3DPW5F/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to