<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>I might not have understood it completely, but I think the use
      cases would probably better be splitted into two categories, each
      with a simple solution (simple in usage at least):</p>
    <p><b>When we just want a tiny scope for a variable:</b></p>
    <p><tt>Syntax:<br>
      </tt></p>
    <p><tt>with [assignment]:<br>
            # use of the variable<br>
        <br>
        # assigned variable is now out of scope<br>
      </tt></p>
    <p>Examples:</p>
    <p><tt>with b = a + 1:</tt><tt><br>
      </tt><tt>    y = b + 2</tt><tt><br>
      </tt><tt><br>
      </tt><tt># we can use y here, but not b</tt><br>
    </p>
    <p>or</p>
    <p><tt>with delta = lambda a, b, c: b**2 - 4 * a * c:</tt><tt><br>
      </tt><tt>    x1 = (- b - math.sqrt(delta(a, b, c))) / (2 * a)</tt><tt><br>
      </tt><tt>
            x2 = (- b + math.sqrt(delta(a, b, c))) / (2 * a)</tt></p>
    <p><tt># delta func is now out of scope and has been destroyed<br>
      </tt></p>
    <p>We don't keep unnecessarily some variables, as well as we don't
      risk any collision with outer scopes (and we preserve readability
      by not declaring a function for that).</p>
    <p>It would probably mean the assignment operator should behave
      differently than it does now which could have unexpected (to me)
      implications. It would have to support both __enter__ and __exit__
      methods, but I don't know if this makes any sense. I don't know if
      <tt>with a + 1 as b:</tt> would make a better sense or be a
      side-effect or special cases hell.</p>
    <p><b>When we want to simplify a comprehension:</b></p>
    <p>(although it would probably help in many other situations)</p>
    <p>Syntax:</p>
    <p><tt>prepare_iterable(sequence, *functions)</tt></p>
    <p><tt>which creates a new iterable containing tuples like (element,
        return_of_function_1, return_of_function_2, ...)</tt></p>
    <p><tt>Examples:<br>
      </tt></p>
    <pre wrap="">[m(spam)[eggs] for _, m in <tt>prepare_iterable(</tt>sequence, lambda obj: obj[0].field.method) if m]</pre>
    <p>or, outside of a comprehension:<br>
    </p>
    <p><tt>sequence = [0, 1, 5]</tt><tt><br>
      </tt><tt><tt>prepare_iterable(</tt>sequence, lambda o: o * 3,
        lambda o: o + 1)<br>
        # -> [(0, 0, 1), (1, 3, 2), (5, 15, 6)]</tt><br>
    </p>
    The "<tt>prepare_iterable</tt>" method name might or might not be
    the right word to use. But English not being my mother language, I'm
    not the right person to discuss this... <br>
    It would be a function instead of a method shared by all iterables
    to be able to yield the elements instead of processing the hole set
    of data right from the start.<br>
    This function should probably belong to the standard library but
    probably not in the general namespace.<br>
    <br>
    -- Brice<br>
    <br>
    <div class="moz-cite-prefix">Le 17/06/17 à 12:27, Steven D'Aprano a
      écrit :<br>
    </div>
    <blockquote type="cite"
      cite="mid:20170617102659.GI3149@ando.pearwood.info">
      <pre wrap="">On Sat, Jun 17, 2017 at 09:03:54AM +0200, Sven R. Kunze wrote:
</pre>
      <blockquote type="cite">
        <pre wrap="">On 17.06.2017 02:27, Steven D'Aprano wrote:
</pre>
        <blockquote type="cite">
          <pre wrap="">I think this is somewhat similar to a suggestion of Nick Coghlan's. One
possible syntax as a statement might be:

y = b + 2 given:
    b = a + 1
</pre>
        </blockquote>
        <pre wrap="">
Just to get this right:this proposal is about reversing the order of 
chaining expressions?
</pre>
      </blockquote>
      <pre wrap="">
Partly. Did you read the PEP?

<a class="moz-txt-link-freetext" href="https://www.python.org/dev/peps/pep-3150/">https://www.python.org/dev/peps/pep-3150/</a>

I quote:

    The primary motivation is to enable a more declarative style of 
    programming, where the operation to be performed is presented to the 
    reader first, and the details of the necessary subcalculations are 
    presented in the following indented suite.
    [...]
    A secondary motivation is to simplify interim calculations in module 
    and class level code without polluting the resulting namespaces.

It is not *just* about reversing the order, it is also about avoiding 
polluting the current namespace (global, or class) with unnecessary 
temporary variables. This puts the emphasis on the important part of the 
expression, not the temporary/implementation variables:

    page = header + body + footer where:
        header = ...
        body = ... 
        footer = ... 

There is prior art: the "where" and "let" clauses in Haskell, as well as 
mathematics, where it is very common to defer the definition of 
temporary variables until after they are used.


</pre>
      <blockquote type="cite">
        <pre wrap="">Instead of:

b = a + 1
c = b + 2

we could write it in reverse order:

c = b + 2 given/for:
    b = a + 1
</pre>
      </blockquote>
      <pre wrap="">

Right. But of course such a trivial example doesn't demonstrate any 
benefit. This might be a better example.

Imagine you have this code, where the regular expression and the custom 
sort function are used in one place only. Because they're only used 
*once*, we don't really need them to be top-level global names, but 
currently we have little choice.

regex = re.compile(r'.*?(\d*).*')

def custom_sort(string):
    mo = regex.match(string)
    ... some implementation
    return key

# Later
results = sorted(some_strings, key=custom_sort)

# Optional
del custom_sort, regex


Here we get the order of definitions backwards: the thing we actually 
care about, results = sorted(...), is defined last, and mere 
implementation details are given priority as top-level names that 
either hang around forever, or need to be explicitly deleted.

Some sort of "where" clause could allow:

results = sorted(some_strings, key=custom_sort) where:
    regex = re.compile(r'.*?(\d*).*')

    def custom_sort(string):
        mo = regex.match(string)
        ... some implementation
        return key


If this syntax was introduced, editors would soon allow you to fold the 
"where" block and hide it. The custom_sort and regex names would be 
local to the where block and the results = ... line.

Another important use-case is comprehensions, where we often have to 
repeat ourselves:

[obj[0].field.method(spam)[eggs] for obj in sequence if obj[0].field.method]

One work around:

[m(spam)[eggs] for m in [obj[0].field.method for obj in sequence] if m]

But perhaps we could do something like:

[m(spam)[eggs] for obj in sequence where m = obj[0].field.method if m]

or something similar.



</pre>
      <blockquote type="cite">
        <pre wrap="">If so, I don't know if it just complicates the language with a feature 
which does not save writing nor reading 
</pre>
      </blockquote>
      <pre wrap="">
It helps to save reading, by pushing less-important implementation 
details of an expression into an inner block where it is easy to ignore 
them. Even if you don't have an editor which does code folding, it is 
easy to skip over an indented block and just read the header line, 
ignoring the implementation. We already do this with classes, functions, 
even loops:

    class K:
        ... implementation of K

    def func(arg):
        ... implementation of func

    for x in seq:
        ... implementation of loop body

    page = header + body + footer where:
        ... implementation of page


As a general rule, any two lines at the same level of indentation are 
read as being of equal importance. When we care about the implementation 
details, we "drop down" into the lower indentation block. But when 
skimming the code for a high-level overview, we skip the details of 
indented blocks and focus only on the current level:

    class K:
    def func(arg):
    for x in seq:
    page = header + body + footer where:


(That's why editors often provide code folding, to hide the details of 
an indented block. But even without that feature, we can do it in our 
own head, although not as effectively.)



</pre>
    </blockquote>
    <br>
  </body>
</html>