7 ms·
I really wish Lua were popular for small-scale utility scripting instead of Python and JS. Because Lua is way snappier: even with language translation, plenty o
by aasasd 6y ago
I really wish Lua were popular for small-scale utility scripting instead of Python and JS. Because Lua is way snappier: even with language translation, plenty of Fennel scripts will run under Python's startup time. Likewise, Lua seems like a great fit for small mobile apps and automation (dunno about threading though, but I seem to have read that Lua can do threads with a library).
My primary woe with Lua is the absence of ‘null’. You can't preserve structure of deserialized tables if there are nil values in them, so you can't really build API middleware and such, without extra effort for that (so you'd also not be able to use functional libraries like Penlight in your middleware).
- samatman 6y agocould you expand on that a bit? null and nil are effectively synonyms, and I'm having difficulty understanding what about Lua's use of nil has caused problems for you.
- mumblemumble 6y agoLua doesn't distinguish between, "the key is not in the table," and, "there is a value for that key, and the value is nil." Setting the value for the key to nil simply erases it from the table.
- nikki93 6y agoYou can just create a sentinel value and use that. eg. `local mySentinel = {}`. Then insert that value when that's the behavior you want. `nil` on its own rarely makes for a good semantic understanding of what value is actually in the table anyways. Also, in Lua 5.4, the behavior is different -- you need to do `t[key] = undef` (which is the only context you can use `undef` in). And `nil` can actually be a value in a table. Not saying what's better or worse, but that the behavior in 5.4 is different.
- pansa2 6y agoDid `undef` actually make it into 5.4? I thought it was removed during the beta period.
- samatman 6y agoIt was.
- aasasd 6y agoDo libraries like Penlight know about your sentinels or ‘undef’? Maybe in ten years they will use undef, or maybe you whipped up your own functional library and keep it optimized and full-featured. But now we have what we have. Besides, please tell: if you receive an empty object as a value in JSON, how do you preserve it in your ‘sentinel’ approach? Gotta need another special value for that.
- nikki93 6y agoFor the JSON case, it doesn't make sense to use an empty object as a sentinel, for sure. JSON parsers usually have their own sentinel for `null`. Lua has a lot of issues, but `nil` being not-present hasn't been an issue that has come up a lot in practice. If you have any specific cases where that has been an issue, would be interesting to hear about them.
- aasasd 6y agoAs I wrote in the first comment, the use-case is e.g. API integration, which is what ‘scripting’ often is, these days. More widely, any transformations or filtering or helper code where you accept structures and pass them on after mild fiddling—again, quite typical use for Python or JS if you ever pipe data between scripts in the terminal or over the network. You don't put your data schema in each of those scripts and maintain them on every change at the source. Imagine implementing `jq` in Lua with all those ‘sentinels’ throughout the whole function library. The issue is that interoperability is crippled. The fact that you haven't so far run into these use-cases doesn't help with the problem that an entire, very common, class of functionality can't be done without tracking those nulls at each and every step with some crutches that bring their own troubles.
- samatman 6y agoAh, so the problem is JSON compatibility. Yeah, I can see that. But I have to say: I think the mistake was on JSONs part. That's what `nil` should mean, imho: the value of anything which has no other value. An object { "foo" : 12, "bar" : null } could just be { "foo" : 12 }, and if I was expecting a "bar" field, well, I can set it to null/nil myself. Other people have pointed out ways to work around it, so I won't go down that road myself.
- aasasd 6y agoIn Lua, nil is not a value. It's an all-encompassing void in which variables are suspended when not having some other value—simultaneously existing and non-existing: both manifest variables or fields of this reality and the infinite multitude of potential variables of other timelines. And you can't tell which reality you're in. So it's useless for interfacing with ‘null’s of other languages.
- samatman 6y agoIn Lua, nil is assuredly a value. `return type(nil) == 'nil'` is a valid program which returns `true`. It doesn't have the semantics you're used to from other languages. I happen to prefer Lua's approach, I think the distinction between undefined and null is clunky and I'm glad that `undef` didn't make the cut in 5.4. You presumably disagree, which is fine. There is one rough edge I've encountered, which is down to a serious wart in the standard library: `table.insert(tab, value)` inserts the value at the end of the array portion, which in Lua we express as `#tab + 1`. But `table.insert(tab, index, value)` is what's used to insert into another slot in the array portion. This is a serious mistake which only prevails for historical reasons. I beg of you: never shift the meaning of parameters around when you add more of them. Nothing good will ever come of this! As a result, `table.insert(a, b, nil)` doesn't do the same thing as `table.insert(a, b)`. In the three parameter version, `b` is an index, in the two parameter version, it's a value. It's not possible to write this sort of monstrosity in pure Lua, where nil is well behaved; but `table.insert` is a builtin, implemented in C, or whatever the host language of your particular Lua implementation happens to be. In C, there's a difference between a `nil` on the parameter stack, and a shorter parameter stack. A Lua programmer will never see this: passing a third `nil` or just calling a function with two parameters will have the same effect.
- nikki93 6y agoYou can actually implement that sort of logic in pure Lua too using `...` in your parameter list and then using `select('#', ...)` in the function body. For example: > function f(...) print(select('#', ...)) end > f(1, 2) 2 > f(1, 2, nil) 3
- ebg13 6y agoLua will never be more popular without a proper standard library. Leaving everything up to the user so that you have to manually implement (or hunt the web for) even the most basic features is mega annoying. How many millions of people need to rewrite string.startswith? The whole "sequence iteration stops at the first internal hole and therefore the # operator doesn't do what you think it should" gotcha is extremely user hostile. Metatables are cool and all, but holy crap are they confusing for Lua newbies. Having an integrated class system would go a long way.
- fit2rule 6y ago1. Luarocks. 2. I regularly carry these little enumerables around with me and use it so frequently I found it quaint to be reminded of the 'hole problem': --- get all packed entries, until gap -- func on the provided list -- @param list table to be inspected -- @param func do func what you func want table.each = function(list, func) for i,v in ipairs(list) do func(v, i) end end --- get all entries, packed or not, until completion -- func on the provided list, completely -- @param list table to be inspected -- @param func do func what you func want table.all = function(list, func) if (list ~= nil) then for i,v in pairs(list) do func(v, i) end end end Disclaimer: I love Lua and would us it for everything if I could.
- ebg13 6y agoDo you also carry a table deepcopy with you? What about string.trim? And LuaRocks is a trash fire that doesn't integrate well with Lua's primary role as an embedded plugin engine and leaves you to waste your time in endless discovery of a slew of unmaintained packages that all do the same thing in different ways and with different bugs. Want to collaborate? I hope everyone is familiar with "classy" and not "oops" or "objectlua" or "Luaoop" or "lobject" or "classyng" or "klesi" or "halo" or "lua-c3class" or "pool" or "middleclass" or "Sunclass" or any other module that implements one of the half dozen official recommendations for faking classes with metatables or closures. It also becomes a huge "left-pad" risk.
- 6y ago