News for hackers. Stuff that matters.
Re:Lua, a Misunderstood Language by epage on Friday January 15, 2021 @05:17PM (#25797276)
> Complaints about 1-based indexing for arrays

I think this misses the point, at least for my case. It doesn't matter which is technically better. What makes more sense for humans is a matter of application (and even "non-dev" stuff varies as to which is better).

For me, my big concern about using Lua in my products is

- I expect other developers to be writing the Lua scripts

- I expect the developers to be frequently using 0-indexed languages

In this scenario, "being different" means you are likely to run into off-by-one errors. Think of that crufty Perl script you might have around at work where people avoid touching it because no one is comfortable enough with Perl. Having predictable semantics helps a lot in scenarios like this.

Re:Lua, a Misunderstood Language by mumblemumble on Friday January 15, 2021 @05:29PM (#25797383)
So, I don't do a lot of Lua programming - basically just having fun with Pico-8 on occasion - so I can't say I have a lot of experience with this. Every single other language I use starts at 0.

But what I have seen is that, starting from 1 felt weird to me for approximately 1 hour, tops. After that, it was no more or less of a switching challenge than switching between semicolon languages and non-semicolon languages. In other words, no big deal. And, once I got over it, I was pleasantly surprised to find out that I actually have fewer off-by-one errors in Lua than I do in other languages. Because the author is right: No matter how much professional experience I have starting with 0, starting with 1 is still the more innate way of thinking.

Also, my single biggest all time source of off by one errors is translating between mathematical notation and code in a 0-based language. That fact alone is cause for me to hope that Julia might one day supplant Python for data work.

Re:Lua, a Misunderstood Language by bilkow on Friday January 15, 2021 @06:33PM (#25798093)
You clearly have a different experience using 1-based index than me, it has caused me many off-by-one mistakes. Also, I almost never need to -1 with 0-based index, but in 1-based index its pretty common, specially if moving slices inside an array, the new index of the element is move_position + old_index - 1 (see example). Also see arguments by Djikstra [0].

Example:

  # python
  lov = ['l', 'o', 'v']
  o_index = 1;
  array = ['a', 'b', 'c', 'd', 'e', 'f']
  move_position = 3
  # elements moved here
  array = ['a', 'b', 'c', 'l', 'o', 'v']
  new_o_index = move_position + o_index
  print(array[new_o_index]) # prints 'o'

  -- lua
  local lov = { 'l', 'o', 'v' }
  local o_index = 2;
  local array = { 'a', 'b', 'c', 'd', 'e', 'f' }
  local move_position = 4
  -- elements moved here
  array = { 'a', 'b', 'c', 'l', 'o', 'v' }
  local new_o_index = move_position + o_index - 1
  print(array[new_o_index]) -- prints 'o'
Note that I'm not saying 0-based indexing is always absolutely better, but I generally prefer it and believe it usually makes more sense even outside of programming (including math), we're just not taught that way.

[0] https://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF transcript: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/E...

Re:Lua, a Misunderstood Language by bsder on Friday January 15, 2021 @05:58PM (#25797685)
I'm glad that's true for you, but my personal experience suggests otherwise. Dijkstra also mentions the Mesa programming language which had all four of the conventions and that anything other than 0-based, half-open leads to errors. See: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/E...

And for those claiming the world is 1-based, they're full of it. Machining measurement, for example, is ALL 0-based. We're talking a field that has multiple standards for everything and yet they converged on 0-based measurement.

The bigger problem, though, is that I even have to use array-based indexing to iterate something. That's just asking for bugs.

And, my favorite question for people who like 1-based is "Given index and length N, how do I create index-1?"

The answer, of course, is newindex = index - 1 % N.

The question is, of course, a trick because the answer is really: newindex = (index - 1) % N. Don't forget the parentheses or you have a bug.

Yeah, no. I'll stay in my 0-based languages thanks.

Side Note: I have other objections to Lua. The big one being that it's not really compatible between Lua installations. Everybody compiles different modules so Lua becomes neither small nor is it the same language between any two implementations.

Re:Lua, a Misunderstood Language by josephg on Friday January 15, 2021 @06:21PM (#25797963)
> my favorite question for people who like 1-based is "Given index and length N, how do I create index-1?"

Create index-1? I don't think I've ever needed do that. What does come up all the time in practice in both JS and Lua is "how do I assign past the current end of an array?"

In javascript (if you don't use .push) its arr[arr.length] = x

In Lua its arr[#arr + 1] = x

Even having worked with 0-based indexes for over 20 years, I still doubletake reading that javascript code when it’s embedded in complex code before I can convince myself its inserting. But the lua code is intuitive.

Likewise "read the last element in an array":

JS: arr[arr.length - 1]

Lua: arr[#arr]

I much prefer the lua version in all these cases.

And simplicity is important here because the code gets much worse when the array isn't in a local variable, but instead is some complex expression. confabulate(foo.bar.baz[foo.bar.baz.length - 1]); <-- Simple statement. Absolute mess.

Re:Lua, a Misunderstood Language by creata on Friday January 15, 2021 @07:17PM (#25798485)
> if you don't use .push

I don't think I've ever needed to avoid .push.

> I still doubletake

Why? "arr[i]" just means "skip i elements and get the next one," which is perfectly intuitive to me. I understand that familiarity is useful, but can you give an intuition for one-indexing that doesn't just appeal to what people are used to?

> the code gets much worse when the array... is some complex expression

Then... don't do that? Rust has "xs.last()", Python has "xs[-1]", and every language has variables. Anyway, even if that code is an "absolute mess" (which is a bit hyperbolic) it's hardly worse than the one-indexed equivalent, which would be

    confabulate(foo.bar.baz[foo.bar.baz.length]);
Re:Lua, a Misunderstood Language by josephg on Friday January 15, 2021 @08:26PM (#25798993)

    confabulate(foo.bar.baz[foo.bar.baz.length]);
The problem I have is that at a glance this looks correct. Even after decades of programming, I would scroll right past this line in JS without noticing the off-by-1 error here. The only saving grace is that this error will occur consistently.

But yes, I'd take Rust's xs.last() in a heartbeat. Especially because you can assign through it with last_mut().

That said, I agree with others in this thread. People fixate on the 1 based indexing of lua but you get used to it pretty quickly once you spend time with the language. Lua's real problem is its sparse standard library and its weak package ecosystem. If history had run its course slightly differently, I could easily see lua ending up inside web browsers instead of javascript. And becoming much more popular as a result. Lua and javascript are remarkably similar languages semantically.

Re:Lua, a Misunderstood Language by samatman on Friday January 15, 2021 @06:20PM (#25797945)
> The bigger problem, though, is that I even have to use array-based indexing to iterate something. That's just asking for bugs.

You absolutely do not, the standard Lua idiom is to use ipairs. The numeric for loop is there, of course, and the index of the pair (index, value) returned by ipairs will be 1 based. of course.

Iteration isn't why 1-based indexing is bad, it really shows its inadequacy when doing interval maths. I make abstract syntax trees in Lua, and a node in that tree with zero width at the 4th position is { left = 4, right = 3 } which is... awful.

Re:Lua, a Misunderstood Language by robscallsign on Friday January 15, 2021 @08:03PM (#25798816)
> And for those claiming the world is 1-based, they're full of it.

I just did an N=1 experiment with my two children, aged 4 and 6. I held up a single apple in my hand, and asked them how many apples I was holding.

They said 1.

Re:Lua, a Misunderstood Language by bsder on Friday January 15, 2021 @08:21PM (#25798960)
Except that your children are >1460 days old and >2190 days old.

You count age from 0 in most English-speaking countries (there are places where "1 year old" means 0<=x<365 days old). When you are less than 1, we count with smaller units.

So, my N=3 sample (you and your two children) says we use 0-based counting.

Thank you for making my point. :)

Re:Lua, a Misunderstood Language by robscallsign on Friday January 15, 2021 @08:49PM (#25799121)
That's because I use round(age) when referring to their floating point age in conversation like any sane person.
Re:Lua, a Misunderstood Language by bsder on Saturday January 16, 2021 @01:53AM (#25800623)
Round(age)? So, they became one year old at 180 days? I doubt that.

And, as I pointed out, there are folks in the world who call their newborn "one year old". And they consider themselves quite sane, thanks.

They count from 1. We count from zero.

Back to the original issue ...

The problem you now have in programming is that it isn't enough that basing from 1 is equivalent. The vast majority of the programming world has converged on 0-based. 1-based has to demonstrate that it is better in order to compensate for the friction of existing in a 0-based world.

And 1-based simply isn't demonstrably better even if I concede that it isn't worse (and I do not concede that).

Re:Lua, a Misunderstood Language by snarfy on Friday January 15, 2021 @06:52PM (#25798256)
It made a lot more sense to me once I fixed the terminology.

You keep saying index, but what you are referring to is an offset.

Re:Lua, a Misunderstood Language by LgWoodenBadger on Friday January 15, 2021 @06:57PM (#25798293)
Measuring and counting seem to be two fundamental things in this context.
Re:Lua, a Misunderstood Language by necovek on Friday January 15, 2021 @07:32PM (#25798593)
I generally agree there are benefits to both, but even the author uses a bad example. They talk of a baby becoming one year old after one full Earth revolution, but do not acknowledge that baby is basically 0 years old until that time. Sure, we'd say it's in its first year, but age-in-years is zero-based.

Part of this is using counting numbers for continuous values, part of it is philosophical, but there are a lot of mathematical properties of zero that make it really appealing (eg. being zero-based allows Python to have a very clear iterable[-1] interpretation).

Re:Lua, a Misunderstood Language by hisham_hm on Friday January 15, 2021 @07:55PM (#25798767)
The Lua standard library also uses -1 to mean "last element" in various functions; never found it to be an issue. In fact, it feels quite symmetric, going 1,2,3 from one side and -1,-2,-3 from the other.
Re:Lua, a Misunderstood Language by necovek on Friday January 15, 2021 @08:30PM (#25799021)
So is l[len(l) - 1] == l[-1] in those contexts?

Potential for one-offs is always there, but I am highlighting how _most_ of the math is simplified when there is a zero between positive and negative numbers :)

Re:Lua, a Misunderstood Language by hisham_hm on Friday January 15, 2021 @09:08PM (#25799258)
> So is l[len(l) - 1] == l[-1] in those contexts?

No, because Lua is 1-based :) The last element is l[#l] (#l is "length of l"). Negative indices aren't really used in arrays, but are used in the string library, so given s = "hello"; s:sub(1,4) gives you "hell" and s:sub(-2,-1) gives you "lo".

Re:Lua, a Misunderstood Language by necovek on Saturday January 16, 2021 @03:25AM (#25800937)
Sure, that was my point: s:sub(#s-2,#s-1) != s:sub(-2,-1) — if # works on s at all :)

Basically, some things are more "natural" with 1-based counting, but some aren't.

Re:Lua, a Misunderstood Language by hisham_hm on Monday January 18, 2021 @01:42PM (#25824995)
> Sure, that was my point: s:sub(#s-2,#s-1) != s:sub(-2,-1) — if # works on s at all :)

And why would they ever be the same? Writing "#s-2" you're treating -2 as a relative _offset_, not an index.

> Basically, some things are more "natural" with 1-based counting, but some aren't.

Yes, offsets are naturally zero-based, and indices (everywhere other than languages derived from the C tradition) are naturally 1-based. The reason why C and its descendants use zero-based indexes is because C mixes indexes with offsets (since offsets are the low-level primitive in machine language), so that given a pointer p, we have that p[i] and p+i are the same.

If instead C had not done that and used 1-based indexing like everyone else back then, I'm sure people today would be claiming how C is superior for providing both 1-based indexing with [] and 0-based offsets with +, since there are always scenarios where one leads to more natural expressions that the other, and how people mixing them up were clearly not suited for the subtleties of low-level programming in C, and should be instead using simpler languages with garbage collection and without pointer arithmetic. :)

Re:Lua, a Misunderstood Language by xscott on Friday January 15, 2021 @09:37PM (#25799445)
> Also, my single biggest all time source of off by one errors is translating between mathematical notation and code in a 0-based language.

If you were working with polynomial coefficients, Fast Fourier Transforms and convolutions, or modulo arithmetic, you'd prefer zero based arrays. In my experience, the majority of places where math notation uses 1-based arrays are in applications where the index doesn't matter.

I prefer zero based arrays specifically because they are better for doing mathematics. Yeah, it sucks that a lot of matrix algorithms in text books use one based arrays, but I blame the text book for getting it wrong.

Re:Lua, a Misunderstood Language by phaedryx on Friday January 15, 2021 @05:28PM (#25797380)
There are only two hard things.

This is an aside, but I think that "index" is the wrong name. I wish that "index" meant you start counting at 1 (which everyone outside of CS does) and "offset" was the name for starting at 0.

Re:Lua, a Misunderstood Language by nvader on Friday January 15, 2021 @05:31PM (#25797399)
1ndex and 0ffset. I like it.
Re:Lua, a Misunderstood Language by d3ckard on Friday January 15, 2021 @05:48PM (#25797573)
I love what you did here. Great mnemonic!
Re:Lua, a Misunderstood Language by phaedryx on Wednesday January 20, 2021 @01:30PM (#25850053)
ooo, I'm going to steal that; clever.
Re:Lua, a Misunderstood Language by zajio1am on Friday January 15, 2021 @05:36PM (#25797455)
> (which everyone outside of CS does)

In set theory (math foundations), ordinals also start at 0.

Re:Lua, a Misunderstood Language by layer8 on Friday January 15, 2021 @07:38PM (#25798641)
That usage gets awkward though when you want to talk about the offset from one array index to another (and the array is 0-based). In actual (common) usage, the distinction between index and offset is the distinction between absolute and relative positions.
Re:Lua, a Misunderstood Language by Pet_Ant on Friday January 15, 2021 @05:36PM (#25797449)
I think I will intentionally start using this usage. Maybe we can make it a thing. I mean we already have argument & parameter for similar things to make a distinction.
Re:Lua, a Misunderstood Language by CountSessine on Friday January 15, 2021 @06:13PM (#25797855)
Djikstra argued in favour of 0-based indexing and against 1-based indexing. Let’s just agree that if you’re arguing for 1-based indexing, you’d better have a pretty fantastic argument.

I think for FORTRAN or Julia, using 1-based indexing is a good idea, because most mathematical algorithms are written in notation using 1-based indices. As someone who spent a semester debugging subtle off-by-one errors and small differences in results in his scientific computing classes because I foolishly opted for C rather than FORTRAN, understand that converting algorithms with nested summations and integrators from one convention to another is painful.

Lua should never have used 1-based indexing because it was meant to interface with C code which itself will have data structures that use 0-based indexing. Writing lua extensions for wireshark, for example, is incredibly painful just because of this.

Re:Lua, a Misunderstood Language by samatman on Friday January 15, 2021 @06:16PM (#25797897)
I was with you up to the last paragraph.

Lua uses 1-based indexing because it started as a data description language, and data tends to use 1-based indexing.

It evolved to where the primary use case is at odds with this origin. I work with Lua every day and consider the indexing convention to be a genuine flaw. But it's useful to know where that came from, because it wasn't a mistake.

Re:Lua, a Misunderstood Language by CountSessine on Friday January 15, 2021 @07:04PM (#25798350)
That makes a lot sense. History is a path-dependent function, I guess. Interesting that it was a data description language - in that context, 1-based indexing really would be called for, although maybe flexible indexing like Pascal’s would be even better.
Re:Lua, a Misunderstood Language by berkut on Friday January 15, 2021 @05:49PM (#25797583)
Yep, I think consistency is key here...

Especially when it's used as an embedded language in a C/C++ app, or an additional Lua API alongside other APIs that exist already.

Having to convert back and forth between 0 and 1 based indices is very annoying, and error-prone. You can make helper methods to abstract some of it, but that only gets you so far, and it's annoying (at least I found it that way) having to context switch your brain depending on what part of the call stack you're looking at.

Re:Lua, a Misunderstood Language by chmod775 on Friday January 15, 2021 @06:04PM (#25797757)
Not only that, but starting at 0 just works mathematically better when doing stuff like dividing into round/ceil/floor or a modulo operation. If your index starts at 1 these can become really unintuitive. Depending on what you're doing you'll have to add/subtract 1 after/before operations a lot.

The only upside I'm aware of is that the 'length' of your array is now a valid index, which is mostly not very useful unless you want to iterate backwards.

Re:Lua, a Misunderstood Language by noizejoy on Friday January 15, 2021 @05:25PM (#25797350)
It doesn’t miss the point, because the point was that non-developer humans will do better with 1 based indexing.

Side note: As a former developer, turned regular human being who scripts from time to time, I don’t find switching between 0 based and 1 based indexing particularly intellectually taxing.

Re:Lua, a Misunderstood Language by TulliusCicero on Friday January 15, 2021 @05:28PM (#25797376)
Yeah I have a bunch of complaints about the language that I developed while learning it and simultaneously teaching my 9 year old kid, but the 1-based indexing isn't one of them. That's totally fine, and certainly easier to grasp for a beginner.

But there's certainly other stuff that's just weird and bad, and I think just the fact that it's dynamically typed made it harder for him to build an accurate mental model -- sometimes he didn't even realize that an identifier that he had typed in earlier was a variable, let alone what kind of value it'd be holding.

Re:Lua, a Misunderstood Language by zajio1am on Friday January 15, 2021 @05:34PM (#25797428)
Well, i started programming in Pascal (with 1-based indexing) and later switched to C. I remember that after switching to C off-by-one errors magically disappeared.
Re:Lua, a Misunderstood Language by billfruit on Friday January 15, 2021 @05:57PM (#25797665)
Wait till you need to use a formula which has somewhat complex uses of indexes like 2^(2n+1) and see how having deal with them in 1-base indexing in addition to 0 based indexing makes it add bit of unnecessary confusion.
Re:Lua, a Misunderstood Language by craftinator on Friday January 15, 2021 @05:57PM (#25797671)
It's not an intellectually challenging context switch, which is actually what makes it such a problem. You don't have to think about it, because it's so simple and easy, so sometimes you won't even think to do it.
Re:Lua, a Misunderstood Language by intrepidhero on Friday January 15, 2021 @06:12PM (#25797849)
I've written a fair bit of Lua in last 5 years and never once cared how arrays are indexed. `for _, value in ipairs(mytable)` works quite well. Looping by index hasn't been necessary.
Re:Lua, a Misunderstood Language by brundolf on Friday January 15, 2021 @05:36PM (#25797453)
Agreed. 1-indexing may be more intuitive for humans broadly, and this may have been a good argument before C became ubiquitous, but when it comes to programmers the landscape of what's intuitive is different; 0-indexing is a deeply ingrained habit. Very few norms are so universal across programming languages
Re:Lua, a Misunderstood Language by goatlover on Friday January 15, 2021 @06:23PM (#25797987)
But it's not universal, since there are established languages like Fortran and R which are 1 based. And Fortran proceeded C.
Re:Lua, a Misunderstood Language by d3ckard on Friday January 15, 2021 @05:53PM (#25797628)
That’s more dependent on language syntax IMO. When you have traditional C-style loops, maybe. When you use ranges, iterators etc. it doesn’t make any difference.
Re:Lua, a Misunderstood Language by brundolf on Friday January 15, 2021 @06:03PM (#25797735)
If Lua is range/iterator-heavy (I haven't used it), then yeah that would definitely ease the burden, but I wouldn't say it doesn't make any difference unless you never ever index anything directly
Re:Lua, a Misunderstood Language by layer8 on Friday January 15, 2021 @07:42PM (#25798677)
It makes a difference as soon as you want to specify a subrange by index.
Re:Lua, a Misunderstood Language by themadsens on Friday January 15, 2021 @06:07PM (#25797789)
Brillant. This distinction nails it. Luckily it doesn't matter much in 99.9% of the cases where one just enumerates/filters/maps a collection and indexing is not involved.
Re:Lua, a Misunderstood Language by garaetjjte on Friday January 15, 2021 @06:13PM (#25797860)
I don't really see how 1-based indexing makes anything better. It just requires sprinkling magic +1 and -1 in various places.

Really only reason to use 1-based indexing I see is to make array index arithmetic needlessly annoying, to discourage users from doing any complex operations there..

Re:Lua, a Misunderstood Language by pasquinelli on Friday January 15, 2021 @08:04PM (#25798818)
Aren't those +1's and -1's just the mirror images of the -1's and +1's you have to do in a 0 based system?

This whole conversation is really silly. 1 based indexing is such trivial detail of lua that I'm not surprised so many words have been spent discussing it.

Re:Lua, a Misunderstood Language by remram on Friday January 15, 2021 @05:27PM (#25797365)
Doesn't it bother you as the person writing both the application and the original scripts, to be using both styles at once in the same product (sometimes to refer to the same data)? Nevermind the end-users' additions.
Re:Lua, a Misunderstood Language by kwhitefoot on Saturday January 16, 2021 @05:16AM (#25801340)
Why do so many languages restrict arrays to 0 or 1 based indexing? I much prefer the way it is done in Basic where you can choose what you like for each array or even better Pascal where you can use any ordinal type (including boolean) as the index and you can define subtypes of the ordinal types to use as index types.