David, I saw now that I missed the biggest problem with your proposal: yet again you deliberately throw away errors. I'm talking about making Python code _less_ error prone, while you seem to want to make it _more_. Anyway, I'll modify your reach() to not have the if in it that has this error hiding property, it also simplifies it a lot. It should look like this:
def reach(name): return inspect.stack()[-2][0].f_locals[name] > 1. Huge performance penalty > > Huh? Have you actually benchmarked this is some way?! A couple lookups into > the namespace are really not pricey operations. The cost is definitely more > than zero, but for any function that does anything even slightly costly, the > lookups would be barely in the noise. I'm talking about using this for all or most function calls that aren't positional only. So no, you can absolutely not assume I only use it to call expensive functions. And yea, I did benchmark it, and since you didn't define what you would think is acceptable for a benchmark you've left the door open for me to define it. This is the result of a benchmark for 10k calls (full source at the very end of this email): CPython 3.6 time with use: 0:00:02.587355 time with standard kwargs: 0:00:00.003079 time with positional args: 0:00:00.003023 pypy 6.0 time with use: 0:00:01.177555 time with standard kwargs: 0:00:00.002565 time with positional args: 0:00:00.001953 So for CPython 3.6 it's 2.587355/0.003079 = 840x times slower and pypy: 1.177555/0.002565 = 460x slower I'm quite frankly a bit amazed pypy is so good. I was under the impression it would be much worse there. They've clearly improved the speed of the stack inspection since I last checked. > > 2. Rather verbose, so somewhat fails on the stated goal of improving > readability > > The "verbose" idea I propose is 3-4 characters more, per function call, than > your `fun(a, b, *, this, that)` proposal. It will actually be shorter than > your newer `fun(a, b, =this, =that)` proposal once you use 4 or more keyword > arguments. True enough. > 3. Tooling* falls down very hard on this > > It's true that tooling doesn't currently support my hypothetical function. > It also does not support your hypothetical syntax. If it was included in Python it would of course be added super fast, while the use() function would not. This argument is just bogus. > It would be *somewhat easier* to add special support for a function with a > special name like `use()` than for new syntax. But obviously that varies by > which tool and what purpose it is accomplishing. Easier how? Technically? Maybe. Politically? Absolutely not. If it's in Python then all tools _must_ follow. This solved the political problem of getting tool support and that is the only hard one. The technical problem is a rounding error in this situation. > Of course, PyCharm and MyPy and PyLint aren't going to bother special casing > a `use()` function unless or until it is widely used and/or part of the > builtins or standard library. I don't actually advocate for such inclusion, > but I wouldn't be stridently against that since it's just another function > name, nothing really special. Ah, yea, I see here you're granting my point above. Good to see we can agree on this at least. / Anders Benchmark code: ----------------------- import inspect from datetime import datetime def reach(name): return inspect.stack()[-2][0].f_locals[name] def use(names): kws = {} for name in names.split(): kws[name] = reach(name) return kws def function(a=11, b=22, c=33, d=44): pass def foo(): a, b, c = 1, 2, 3 function(a=77, **use('b')) c = 10000 start = datetime.now() for _ in range(c): foo() print('time with use: %s' % (datetime.now() - start)) def bar(): a, b, c = 1, 2, 3 function(a=77, b=b) start = datetime.now() for _ in range(c): bar() print('time with standard kwargs: %s' % (datetime.now() - start)) def baz(): a, b, c = 1, 2, 3 function(77, b) start = datetime.now() for _ in range(c): baz() print('time with positional args: %s' % (datetime.now() - start))
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/