
I think I "get" what Thomas is talking about here: Starting with the simplest example, when defining a function, you can have one take a single positional parameter: def fun(x): ... and you can have code all over the place that calls it: fun(something) Later on, if you want to exapand the API, ytou can add a keyword parameter: def fun(x, y=None): ... And all the old code that already calls that function with one argument still works, and newer code can optionally specify the keyword argument -- this is a really nice feature that makes Python very refactorable. But for return values, there is no such flexibility -- if you have already written your function with the simple API: def fun(...): ... return something And it is being used already as such: x = fun() Then you decide that an optional extra return value would be useful, and you re-write your function: def fun(...): ... return something, something_optional now all the call locations will need to be updated: x, y = fun() or maybe: x, __ = fun() Sure, if you had had the foresight, then you _could_ have written your original function to return a more flexible data structure (dict, NamedTuple, etc), but, well, we usually don't have that foresight :-). My first thought was that function return tuples, so you could document that your function should be called as such: x = fun()[0] but, alas, tuple unpacking is apparently automatically disabled for single value tuples (how do you distinguish a tuple with a single value and the value itself??) . so you could do this if you started with two or more return values: x, y = fun()[:2] OR you could hae your original function return a len-1 tuple in the first place: def test(): return (5,) but then that would require the same foresight. So: IIUC, Thomas's idea is that there be some way to have"optional" return values, stabbing at a possible syntax to make the case: Original: def fun(): return 5 called as: x = fun() Updated: def fun() return 5, *, 6 Now it can still be called as: x = fun() and result in x == 5 or: x, y = fun() and result in x == 5, y == 6 So: syntax asside, I'm not sure how this could be implemented -- As I understand it, functions return either a single value, or a tuple of values -- there is nothing special about how assignment is happening when a function is called. That is: result = fun() x = result is exactly the same as: x = fun() So to impliment this idea, functions would have to return an object that would act like a single object when assigned to a single name: x = fun() but an unpackable object when assigned to multiple names: x, y = fun() but then, if you had this function: def fun() return x, *, y and you called it like so: result = fun() x, y = result either x, y = result would fail, or result would be this "function return object", rather than the single value. I can't think of any way to resolve that problem without really breaking the language. -CHB On Sat, Jan 26, 2019 at 9:48 AM Steven D'Aprano <steve@pearwood.info> wrote:
On Sat, Jan 26, 2019 at 12:01:55PM -0500, Wes Turner wrote:
Tuples are a dangerous (and classic, legacy) interface contract.
What?
-- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython