[Python-ideas] Quick idea: defining variables from functions that take the variable name
Émanuel Barry
vgr255 at live.ca
Tue May 31 14:08:08 EDT 2016
I think that the idea of implicit call or magically inserting items at the front (or any arbitrary position, for that matter) isn't going to work. For it to work, we need to address cases such as those:
x -> foo("bar")("baz") # is this foo("x", "bar")("baz") or foo("bar")("x", "baz") ?
x -> foo() # is this foo("x") or foo()("x") ?
x -> foo # hmm, are we doing foo("x") here, or should this be a syntax error?
I think that whatever we go for, we need to be explicit where the name goes - but that completely breaks the purpose of the proposal to begin with. Or we could get rid of ambiguity and something like this instead:
x -> foo("bar")("baz") # actually foo("x", "bar")("x", "baz")
x -> foo() # wait, this is actually foo("x")("x")
Yuck! I tend to like implicit black magic in some of my code, but that's pushing it too far. Or wait, maybe we can settle for a syntax like this (hypothetic pseudo-code):
x -> foo(?, "bar") # this is foo("x", "bar")
x -> foo(?) # foo("x")
x -> foo(?, "bar", ?) # is this foo("x", "bar", "x") or a syntax error?
This looks fine. What about this, though?
a, b, c -> foo(?) # probably foo(("a", "b", "c")), right?
a, b, c -> foo(?, "bar", ?, "baz", ?) # is this foo("a", "bar", "b", "baz", "c") or a syntax error?
In the face of ambiguity, refuse the temptation to guess and throw a syntax error in all ambiguous cases. Oh wait, that's how Python works right now - every case is ambiguous for that. The main point is that there's no way this is going to fly if there isn't an explicit way to declare the implicitness - at that point I'd rather hand-roll my own function (which I can probably customize to fit the needs of my module). Something like:
def set_global(func, name, *args, **kwargs):
globals()[name] = func(name, *args, **kwargs)
In fact, I would go for some decorator magic (I love decorators):
def call_with_name(func):
fn, args, kwargs = func()
return fn(func.__name__, *args, **kwargs)
@call_with_name
def x():
return namedtuple, (fields,), {}
There you go, and you only typed the name once, in the function definition. Magic enough for you?
I love syntactic sugar and Python's magic, and this would be just fine for me. And, as everyone knows, code is read much more often than it is written. As such,
x -> foo()
is easier to write, but much harder to read, turning the fun of writing something that works using compiler magic into a maintenance hell. While
x = foo("x")
takes more keystrokes to type, it's exactly in line with what I'm used to see in Python, doesn't require any magic, is very easy to get right and makes maintaining the module straightforward for everyone involved.
----
I agree that something like T = TypeVar("T") isn't pretty, but explicit is better than implicit here. If someone comes with an obviously unambiguous syntax for this, then I'll be in favour. Until then, count me -1 on the whole thing.
Finding the appropriate syntax for this isn't bikeshedding here, it's the most important part of the whole thing. As I stated above, most of the ideas mentioned here fall into the "obviously unobvious" category.
I also think that adding new syntax might become an attractive nuisance, where people use it all the time everywhere and code quickly becomes unreadable. It also makes one new concept for newbies to learn, possibly quite early if most start to adopt this. All in all, while I see and feel the need, I don't think the syntax change is a good idea, sadly.
- Emanuel
More information about the Python-ideas
mailing list