lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.
>