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