> we had better regard —after all those centuries!— zero as a most natural number
Of course, a counter argument is that we've already made the mistake of indexing with 1 in natural language (first, second, ...). That decision is not free of annoyances, though: the 19th century are year numbers 18xx, floors below the first have a varying names when they could have been negative numbers, etc.
I like the argument that 1-based is better for indexing and 0-based is better for offsets: https://hisham.hm/2021/01/18/again-on-0-based-vs-1-based-ind...
If I get the root of the argument in the linked article, it is that zero-based indexing is more of a optimization than anything, but I would disagree; there are reasons beyond that (see the examples in my previous comment).
Also, here's an example of an 1-index based system that has caused me some headaches: In music theory, the first note of the scale is called the "first", etc. It also talks about e.g. "stacking thirds", which means take the third of the scale, than take the third from there. However, the offsets are two. (first=offset 0, second=offset 1, third=offset 2). Which is hard to work with in my opinion.
You have an interesting argument about iterating backwards, although I would say; if we need a tie-breaker between the two, iterating forward should have more weight than backwards.
I appreciate your comment, and while trying as best I can to be convinced of the "other side", I still land on 0-indexing. The only argument I buy, is that it matches our natural language starting at 1. Which, of course, is a strong argument.
It's like right-click-to-select.
local alive_enemies = {}
for _, enemy in ipairs(enemies) do
if not enemy.dead then
table.insert(alive_enemies, enemy)
end
end
enemies = alive_enemies
with enemies = enemies.filter(enemy => enemy.alive) enemies = array.filter(enemies, function(e) return e.alive end)
Or even setting a metatable so you can do: enemies = enemies.filter(function(e) return e.alive end)If you're in Love and/or control the environment you're free to bring in whatever libraries you want. Or to build your wrapper to support multiple files from the user.
Like you could suffer from a bad embedded scripting setup with any language. Granted if it was embedded Python or Javascript you would get a bit more for builtin if they embed a full implementation. But also embedding Lua with support for user supplied libraries is less effort than embedding a whole Python/JS runtime
Last time I used LÖVE that wasn't the case, nor does it seem to be the case today, you can require libraries or even use LuaRocks if that is what you prefer, and everything just works.
The only difference is that one of the language is embedded and barely takes any place. it's just a few C files :-D It offers just enough functionality while not making it overly complicated to make basic things.
The other one is way way bigger. and even Array.filter didn't exist from the start
(set enemies (filter |($ :alive) enemies))
Though JavaScript has QuickJS, which is also lightweight.But if it is about using it as an embedded language. you want just enough language to get you started and be able to tweak controls. so that the embedded language itself doesn't take up unnecessary space, on its own.
It's a design choice to have a language as small as possible while still offering cool tools.
Wait just a minute, there exist many web frameworks in lua, and programmers who enjoy lua might want to use them.
I see why people might hate Lua. Especially for game dev!
It still is an issue nowadays https://discussions.unity.com/t/app-needs-warmup-first-slow-...
Similar story with the GC, it's nice to have, until it causes you problems (wich it will), so you end up having to avoid using it and instead rely on manual techniques
JIT and GC aren't the panacea people make them out to be
Most JITs let you tune when and how they inline. It's also worth knowing how they works and what they can/can't inline.
You linked to monojit. Luajit is a whole other beast. I'd argue it's superior to anything in JS/JAVA/C# land (and I say that as someone with a reasonable understanding of the JVMs C2 JIT).
As an aside with low latency GCs like the JVM's ZGC trading manual memory management for no memory related security vulnerabilities is pretty appealing.
Like everything in programming it's a trade off.