why the unpacking has to happen automatically?

I would prefer something like:
switch *args:
case:...

Also I'm not a big fan of adding two new keywords to the syntax, I would think something like:

switch *args:
           &(a==1, ...) as a, *b:
# code
&(a,b) as a, b:
# code
&(a,b, ...) as a, b, *c:
# code
&(...) as a:
# code

This would reduce the numbers of new keywords needed to 1, it would make sense to use the & operator because all the conditions have to be TRUE and this use at the moment raises SyntaxError.
For how I see it could also make sense to be able to pass the arguments to a callable.

switch *args:
           &(a==1, ...): (lambda a, *b: ...)
&(a,b): (lambda a, b: [a, b])
&(a,b, ...): (lambda a, b, *c: [ a+1, b+1, *c])
&(...) as a: (lambda *a: [*a])

On Fri, May 20, 2016 at 4:37 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On 19 May 2016 at 14:15, Guido van Rossum <guido@python.org> wrote:
> The attribute idea would be similar to a duck-type check, though more
> emphasizing data attributes. It would be nice if we could write a
> match that said "if it has attributes x and y, assign those to local
> variables p and q, and ignore other attributes". Strawman syntax could
> be like this:
>
> def demo(arg):
>     switch arg:
>         case (x=p, y=q): print('x=', p, 'y=', q)
>         case (a, b, *_): print('a=', a, 'b=', b)
>         else: print('Too bad')

For the destructuring assignment by attribute, I'd suggest the "value
as name" idiom, since it's not quite a normal assignment, as well as a
leading "." to more readily differentiate it from iterable unpacking:

def demo(arg):
    switch arg:
        case (.x as p, .y as q): print('x=', p, 'y=', q)
        case (a, b, *_): print('a=', a, 'b=', b)
        else: print('Too bad')

Whether to allow ".x" as a shorthand for ".x as x" would be an open question.

> Someone else can try to fit simple value equality, set membership,
> isinstance, and guards into that same syntax.

For these, I'd guess the most flexible option would be to allow the
switch expression to be bound to a name:

    switch expr as arg:
        case arg == value: ...
        case lower_bound <= arg <= upper_bound: ...
        case arg in container: ...

Similar to with statement and for loops, this wouldn't create a new
scope, it would just bind the name in the current scope (and hence the
value would remain available after the switch statement ends)

If we went down that path, then the "assign if you can, execute this
case if you succeed" options would presumably need an explicit prefix
to indicate they're not normal expressions, perhaps something like
"?=":

    switch expr as arg:
        case ?= (.x as p, .y as q): print('x=', p, 'y=', q)
        case ?= (a, b, *_): print('a=', a, 'b=', b)
        case arg == value: ...
        case lower_bound <= arg <= upper_bound: ...
        case arg in container: ...
        else: print('Too bad')

Which would then have the further implication that it might also make
sense to support attribute unpacking as the LHS of normal assignment
statements:

    (.x as p, .y as q) = expr

In a similar vein, item unpacking might look like:

    (["x"] as p, ["y"] as q) = expr

And unpacking different structures might look like:

    switch expr:
        case ?= (.x as x, .y as y): ... # x/y as attributes
        case ?= (["x"] as x, ["y"] as y): ... # x/y as mapping
        case ?= (x, y): ... # 2-tuple (or other iterable)

Cheers,
Nick.

--
Nick Coghlan   |   ncoghlan@gmail.com   |   Brisbane, Australia
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/