[Python-ideas] Quick idea: defining variables from functions that take the variable name
Guido van Rossum
guido at python.org
Tue May 31 00:45:48 EDT 2016
That all sounds not unreasonable, except the -> operator feels kind of
wrong given its use in function signatures. In terms of restricted
syntax, the precedent for such syntax restrictions would be
decorators, which also don't allow arbitrary expressions after the @.
In fact, maybe we could somehow unifying this with structural
unpacking *and* variable decorators (also oft-requested)?
I know you must think "Guido is high" or "someone broke into Guido's
account". My actual excuse is that I'm procrastinating on rehearsing
my PyCon keynote, which is in about 11 hours. So don't take all this
as too much of a ringing endorsement. :-)
On Mon, May 30, 2016 at 8:08 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Mon, May 30, 2016 at 06:16:26PM -0700, Guido van Rossum wrote:
>
> [...]
>> T = TypeVar('T')
>> x = Symbol('x')
>>
>> I'm sure this is not a new idea, but so far I've always thought that
>> this is pretty esoteric and the approach here is good enough. But
>> maybe we can actually do better, and whatever solution we come up with
>> might also be useful for extracting attributes from an object or
>> values from a mapping?
>
> This comes up a lot and it would be nice to clean it up.
>
> T = type('T', bases, ns)
> Record = namedtuple('Record', fields)
>
> It came up in the discussion on dict unpacking:
>
> a, b, c = **dict # unpacks keys 'a', 'b', 'c'
>
> which was rejected as too magical. But maybe it will seem less magical
> if we have a special assignment operator that takes the left hand symbol(s)
> and copies them to the right?
>
> How do you feel about an arrow operator?
>
>
> T -> TypeVar()
> x -> Symbol()
> T -> type(bases, ns)
> Record -> namedtuple(fields)
>
> In general:
>
> name [, name, ...] -> callable(...)
>
> where "callable" is some expression, e.g. a name, a dot lookup, etc.
>
> # okay
> name -> sympy.Symbol()
>
>
>
> The easy case
> -------------
>
> All assignment targets are plain names.
>
> The arrow operator takes the names, turns them into strings, and passes
> them to the callable on the right as a tuple of strings, given as the first
> positional argument.
>
> Since the most common case will be a single target, I think it is worth
> while to treat it as a special case and pass just a string:
>
> T -> Type() # like Type('T')
>
> a, b, c -> Spam(arg) # like Spam(('a', 'b', 'c'), arg)
>
> The callable being called doesn't need to know or care whether it is
> being called with the -> or = assignment. It just receives the name(s)
> as the first argument.
>
> This will mean that callables that take the name as (say) the second
> argument cannot be used with this syntax.
>
> Using the arrow operator with arbitrary expressions on the
> right will be a SyntaxError:
>
> x -> y + 1
> my_name -> spam*f()
> my_name -> f() or g()
>
> I reject that third example as it is unclear whether both f and g, or
> only f, get the name as first argument.
>
> But this is allowed:
>
> my_name -> f(g()) # like f('my_name', g())
>
> If f isn't *actually* a callable, you get a runtime TypeError as usual.
>
>
> The hard case
> -------------
>
> Assignment target(s) is not a plain name.
>
> spam[2].eggs().attr -> Symbol()
>
>
> I'm going to take the cowards way out and just say "we don't allow
> that".
>
>
> --
> Steve
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
--
--Guido van Rossum (python.org/~guido)
More information about the Python-ideas
mailing list