[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: I wish function execution continued past `return'
- From: Majic <majic.one@...>
- Date: Tue, 16 Mar 2010 11:41:02 +0000
One of the things I don't think I made clear enough with my last
collosal post was what a multi-lined conditional might look like.
What I should have said, or what I meant, was if the conditionals were
nested like so:
function whatever()
if conditional1 then
if conditional 2 then
if conditional3 then
return 2
else
return 4
end
end
end
return 'whatever'
end
Obviously this would be a situation where someone would append the
returned 2 or 4 to a localized table in the function, then return the
table or return unpack(local_table). Both of these methods I deem as
a little strange with the [assumed] cost of the table that I think
should be unnecessary. Tables are quite lovely but I wish this were
handled more like a stack, how it is in the Lua CAPI.
*runs off to eat pie for a belated celebration of our favorite day in March*
On Tue, Mar 16, 2010 at 11:33 AM, Majic <majic.one@gmail.com> wrote:
> Hello all,
>
> today I came across something extremely scary. For the past year or
> so I had been under the impression function execution continued past
> any `return something' statement. Whereas writing code like this:
>
> function whatever()
> if condition then
> return 1
> end
> return 2
> end
>
> Resulted in either `return 1, 2' or `return 2' upon completion of the
> function. I could have sworn that a few people had complained about
> this behavior when I would give them advice on how to write the flow
> of their control in their functions. However, I recently tested this
> for someone when he asked me about it, only to find out return acted
> like it did in any "sane" language. When I asked about it in #lua on
> Freenode another person said it was what sane languages did. However,
> while the inconsistency of my memory is in question and while I am
> shocked to think that I wrote my functions without ever relying on the
> behavior of what I was misled into thinking, I believe this would be
> an ideal behavior for Lua. My understanding of coroutines is that the
> function temporarily yields control to the calling block of code with
> it's returned value and then resumes execution. What I am talking
> about here is that every return statement instead pushes the value
> it's returning onto the Lua stack, and then the stack as a whole is
> returned at the end of the function. When I discussed *this* behavior
> in #lua someone said I should return a table of the parameters
> instead. However, I don't believe this would be suitable considering
> the unnecessary memory used to create this table which is only going
> to be unpacked at the end of the function anyway. What I am talking
> about is theoretical code like this:
>
> return condition and 1 or 2, 3, condition and 4 or 5
>
> The problem I see with this is when we imagine that each condition can
> span many lines and cannot be concisely represented with Lua's
> equivalent of a ternary operator. When we know what value will be
> returned constantly on every function call, in this case 3, but not
> what the first or last conditional will return. This is why I believe
> it would be a great idea to instead be able to write something like
> the first function I showed. In this false reality I had going for
> the past year, I had always looked down on functions that were written
> like `whatever()' that I showed above, because it would always return
> 2 (so I thought). This was the reason that people (so I had thought)
> did not like how Lua's return did not return right away and cease
> execution of the function. All that would change by modifying the
> behavior of return, is we would be structuring our functions
> differently to make use of else, once again:
>
> function whatever()
> if condition then
> return 1
> else
> return 2
> end
> end
>
> The beauty of these stack-based returns is that hopefully it would
> allow for another data type to be exploited in Lua, instead of relying
> on tables to represent sparse arrays.
>
> It would be great (in my opinion) if we could do things like:
>
> for x in function () return 1, 2, 3, 4, 5 end do
> print(x)
> end
>
> Obviously no one would write this exact code but the idea here is that
> the anonymous function would execute before the loop is started and
> each iteration of the loop would take next returned value from this
> "stack". And let's pretend that was return 3, 2, 7, 99, 182, so I
> won't get comments saying you could do this with the usual for loop
> incrementing x.
>
> The biggest issue I see with this would be finding a way to represent
> an array instead of a table when you:
>
> local bleh = assignallreturnedvalues()
>
> I therefore propose this syntax:
>
> local bleh = | assignallreturnedvalues() |
>
> Whereas if this were a table it would be using the brackets ({})
> enclosed around the function call.
>
> Hopefully this would allow for "saner" array handling instead of
> hitting pitfalls with holes in ..."iterable" tables. (ipairs())
>
> -----------------------
>
> In conclusion, I have no patches, I have no test cases, this is just a
> crazy idea that I really love and thought I would share. What I
> wanted to avoid was:
>
> function whatever()
> local t = {}
> if multi_line conditional then
> table.append(t, 4)
> end
> table.append(t, 'potato')
> if multi_line conditional then
> table.append(t, { 'cat', 'dog', 'horse' })
> end
> end
>
> PS: I'm pretty sure this idea sprung from how values are pushed onto
> the Lua stack and then the number of elements is returned in exposed C
> functions from the CAPI.
>
> I hope you enjoyed reading.
>