We now have the mythical SET-BLOCK! and GET-BLOCK!. You can write:
multi-return: function [a b] [ return :[(a * 3) (b - 16)] ] >> [x y]: multi-return 10 20 == [30 4] >> x == 30 >> y == 4
That's relatively cool. And you don't have to take all the values...
>> [x]: [10 20] == [10 20] >> x == 10
You have to know that it's returning multiple values though. Using a plain SET-WORD! will get you the block:
>> x: some-function-i-didnt-know-was-multi-return ... == [ret1 ret2 ret3] ; the block! could easily be mistaken for single return
But I've been having one of those ideas that just won't go away...
Rather than choose between [x]: and [x y]: and knowing in advance how many values you're taking or throwing away, I've wanted someone who only wants one value to be blissfully ignorant. So the choice would be between:
>> x: multi-return ... >> [x y]: multi-return ...
So even though the first case is a multiple return, you wouldn't set x to a block of values, but just get the first value.
This would require some kind of magic.
Here's a stab at what "magic" might look like...
What if AT-BLOCK! ("new LIT-BLOCK!?") wasn't just inert, but had a special relationship with SET, SET-BLOCK!s and SET-WORD!s?
>> reduce [@[10 20]] == @[10 20] >> reduce [x: @[10 20]] == 10 ; the 20 just vaporizes in the assignment >> x == 10 >> reduce [[x y]: @[10 20]] == [10 20] >> x == 10 >> y == 20
This would let you upgrade functions to have more return values without the user knowing it.
The only catch is when you're trying to work with these AT-BLOCK!s literally. Assignment is such a foundational thing that undermining it has consequences.
You'd need a way to do a hard SET. That could be done via SET/ONLY or similar. But for a briefer notation, perhaps SET-GROUP! could be a SET/ONLY?
>> (x): @[10 20] == @[10 20] >> x == @[10 20]
It seems so incredibly useful that I feel we must try something along these lines, even if just to put the notion out of my head so I don't keep thinking about it!