Everything You Didn't Want to Know About Lua's Multi-Values
1–8 of 8 posts
Re: Everything You Didn't Want to Know About Lua's Multi-Values
#2For example, let's compare with Python: In Python, you can return multiple arguments as a tuple; it's not possible to have an optional return value without a lot of painful type matching and unpacking. In Lua you can:
local result, errmsg = do_stuff()
if not result then
error("Error in do_stuff:"..errmsg)
end
print(result + 5)
If you don't want the error message, just remove ", errmsg", and it will work as expected. This is incredibly flexible, which is exactly what I want in my dynamic languages. In Python, you would get an type error when attempting to add together a tuple and an integer.Re: Everything You Didn't Want to Know About Lua's Multi-Values
#3I do not really agree with the article's (implied?) statement that multivalues are an ugly part of Lua. It's subtle yes, but like most of Lua, is incredibly consistent. For example, let's compare with Python: In Python, you can return multiple arguments as a tuple; it's not possible to have an optional return value without a lot of painful type matching and unpacking. In Lua you can: local result, errmsg = do_stuff()…
Re: Everything You Didn't Want to Know About Lua's Multi-Values
#4I do not really agree with the article's (implied?) statement that multivalues are an ugly part of Lua. It's subtle yes, but like most of Lua, is incredibly consistent. For example, let's compare with Python: In Python, you can return multiple arguments as a tuple; it's not possible to have an optional return value without a lot of painful type matching and unpacking. In Lua you can: local result, errmsg = do_stuff()…
const [result, errmsg] = do_stuff();
And I guess you would be fine to omit the errmsg, even though I admit the resulting [result] syntax would be dissatisfyingRe: Everything You Didn't Want to Know About Lua's Multi-Values
#5I do not really agree with the article's (implied?) statement that multivalues are an ugly part of Lua. It's subtle yes, but like most of Lua, is incredibly consistent. For example, let's compare with Python: In Python, you can return multiple arguments as a tuple; it's not possible to have an optional return value without a lot of painful type matching and unpacking. In Lua you can: local result, errmsg = do_stuff()…
But why not just use a table in this case? Indexing a value that doesn't exist will give you nil as well.
Re: Everything You Didn't Want to Know About Lua's Multi-Values
#6I do not really agree with the article's (implied?) statement that multivalues are an ugly part of Lua. It's subtle yes, but like most of Lua, is incredibly consistent. For example, let's compare with Python: In Python, you can return multiple arguments as a tuple; it's not possible to have an optional return value without a lot of painful type matching and unpacking. In Lua you can: local result, errmsg = do_stuff()…
result, errmsg = do_stuff()
if errmsg:
error(f"Error in do_stuff: {errmsg}")
print(result+5)
Assuming that errmsg is 'None' when do_stuff() succeeds.Re: Everything You Didn't Want to Know About Lua's Multi-Values
#7I do not really agree with the article's (implied?) statement that multivalues are an ugly part of Lua. It's subtle yes, but like most of Lua, is incredibly consistent. For example, let's compare with Python: In Python, you can return multiple arguments as a tuple; it's not possible to have an optional return value without a lot of painful type matching and unpacking. In Lua you can: local result, errmsg = do_stuff()…
But why not just use a table in this case? Indexing a value that doesn't exist will give you nil as well.
But return lists are more than an optimization. Lua is a first-class functional language with guaranteed tail-call optimization. And Lua maintains strong semantic symmetry between its C API and in-language constructs. In both cases return lists provide an extremely elegant way for composing function calls, including composing mixtures of Lua and Lua C functions.
For example, returning a list in C is as simple as `push; push; return 2`, whereas in languages that require an array or tuple you need to need to create a separate object and then insert your value (by index or name). It's worth noting that Lua can handle allocation failure gracefully, throwing an error back to the more recent protected call while maintaining a clean state (e.g., OOM from an event loop client handler won't crash your app and the hundreds of thousands of other connections). Many simple functions that operate on the stack (e.g. lua_pushinteger) are guaranteed not to dynamically allocate. Such guarantees can make writing OOM-safe Lua C API code much easier.
If you look at it from the perspective of the C FFI, return lists make a ton of sense. Indeed, they're integral to the C API semantics, which is defined in terms of an abstract invocation stack--which is in fact implemented as a contiguous array.
Re: Everything You Didn't Want to Know About Lua's Multi-Values
#8Earlier quoted context omitted.
But why not just use a table in this case? Indexing a value that doesn't exist will give you nil as well.
Tables require dynamic allocation--as do Python tuples--which cause GC churn even when optimized. And accessing a table performs a lookup operation just to put it onto the value stack, anyhow. While insertion and index operations are fast, they're nowhere near as fast as not doing them at all. If you want stack semantics, just use the stack! Multiple return values (return lists) are one reason why Lua is often faster…