6 ms·
I used to quite like Lua, but got quite consistently wound by up several things - global variables by defauilt - weird choice of certain operators (~=
by blibble 6y ago
I used to quite like Lua, but got quite consistently wound by up several things
- global variables by defauilt
- weird choice of certain operators (~= for not equal)
- arrays start at 1
(fixed yet?)
- ebg13 6y ago~= and 1-indexing are only weird if you haven't seen them before. MATLAB uses them as well.
- sk0g 6y agoIsn't "weird == not seen it before" anyway? I get what you're trying to say, but MATLAB is not really a programming language SWEs would use, so if that's the best example you can think of, Lua's bound to confuse most people in the industry. May work better for mathematicians, non-SW engineers etc, but I wouldn't know.
- rpdillon 6y agoJulia is 1-indexed as well.
- luhn 6y agoWhich is also targeted towards scientific computing.
- ebg13 6y ago> I get what you're trying to say, but MATLAB is not really a programming language SWEs would use It may not be a language that website jockeys use, but "I don't use it therefore probably no one does" is almost never correct. MATLAB is huge in state machine and dynamic systems programming as well as being the original commercial powerhouse for linear algebra algorithms.
- sk0g 6y agoI meant to say most SWEs, which you seemed to have inferred anyway. Why do you think that's wrong? I simply claimed MATLAB is much more commonly used by scientists and non-SW engineers. Most SWE jobs are in B2B, web development, embedded, etc fields. Which one of these sees a lot of MATLAB usage? Maybe don't resort to insults straight away too.
- ebg13 6y ago> Most SWE jobs are in B2B, web development Citation? > embedded, etc fields. Which one of these sees a lot of MATLAB usage? Both embedded and etc. MATLAB is used widely in signal processing and controls software. > Maybe don't resort to insults straight away too. Sorry. I get annoyed when someone pretends that Software==Websites as if any of our trusted electronics are designed or programmed in javascript.
- deleted 6y ago[deleted]
- jontro 6y agoThe tilde ~ char is pretty annoying to type on swedish keyboards at least. Alt + ¨ and a space on my mac. Having to type this regularly on my main languages would be off putting
- deathanatos 6y agoIt's not just weird, or different, though; there are reasons to prefer 0-based indexing: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/E...
- curtisf 6y agoI really don't like seeing this cited as a "proof" that 0-based indexing of lists is better. It is too shallow and ignores too many important facets of the question. The main contrast Dijkstra is drawing is between closed and half open intervals. Typically, the choice "starting from one" is tied to "closed" intervals, but that's not strictly necessary. Nothing stops you from using half-open intervals on Lua lists any more than you can used closed intervals to index into C arrays. The main advantage of the typical coupling is avoiding `+`s and `-`s in your "typical" loops over the first n indices: for i = 1, n do -- closed for (int i = 0; i < n; i++) { // half open but what if you want to go in reverse? Getting the _final_ indexes requires arithmetic with half-open intervals, but it doesn't with closed (which also requires changing the operator from exclude-eq to include-eq): for i = n, 1, -1 do -- closed for (int i = n - 1; i >= 0; i--) { // half open Of course, probably the most important property of half-open intervals is the way that they can be broken down into two disjoint intervals: `[A, C) = [A, B) U [B, C)`. But if your indexes are integers this is straightforward with closed intervals too: `[A, C] = [A, B - 1] U [B, C]` or `[A, C] = [A, B] U [B + 1, C]`. But again, if you're using this property, you probably don't actually care about the "absolute" indexes at all; indexing with `[1, #list + 1)` isn't a problem _at all_ in Lua. Plus, between the operations of "get final index" and "split interval into non-overlapping pieces", "get final index" is far more common (it's crucial to stacks, queues, etc, in addition to various uses like iterating backwards). Choosing "closed" intervals is then the cleaner option to avoid an ugly "+" or "-"! Dijkstra mentions that requiring -1 to refer to an initial interval as "ugly" since -1 is not a valid index, but he has no qualms with using the length of the list, n, and allowing it to not be an index! This is all said without even going into the awkwardness of having [k] being the {k+1}th element (e.g., [4] is how we write "fifth" in C -- I distinctly remember at least one conversation at work where the wrong thing was communicated because someone said "fourth" to mean [4]) Now, don't take this as a serious argument that 0-indexed-lists are inferior to 1-indexed lists. It's just a demonstration that it's easy to argue either side. That's because it's really just an unimportant convention. Pick one and stick with it and everything will work fine, modulo confusion about what "fourth" means.
- samatman 6y agoI work with Lua extensively, including abstract syntax trees. To mark a node at the third position, containing one character, we say {3,3}. But what if there's a node at the third position, that contains no character? Well, thats {3,2}. It's like nails on a chalkboard every time. 1-based indexing is a mistake. ~=, by contrast, is just notation. You get used to it quickly.
- saagarjha 6y ago> To mark a node at the third position, containing one character, we say {3,3}. > But what if there's a node at the third position, that contains no character? Well, thats {3,2} Why not shift over indexing by one consistently? So you'd use {3, 4} and {3, 3} for each, so the length property is preserved.
- samatman 6y agoBecause that's not how the string library works. ("12345"):sub(3,3) returns "3", while ("12345"):sub(3,4) returns "34", and ("12345"):sub(3,2) returns "". Indexing in the array portion of tables, and strings, is at least consistent; but Djikstra was right. The Wiki[0] has a good discussion of Djikstra's iconic essay. The best of these arguments, imho: 0 based indexing unifies enumeration and measurement. [0]: https://wiki.c2.com/?WhyNumberingShouldStartAtZero https://wiki.c2.com/?WhyNumberingShouldStartAtZero
- int_19h 6y agoThat's an argument against end-inclusive ranges more so than against 1-based indexing. If they were end-exclusive, like in Python, then {3,3} would be an empty string, and {3,4} would be a single character at 3. Note how it suddenly doesn't matter at all whether the indices are 0-based or 1-based - all of the above is valid regardless. FWIW, I think that the real mistake was to make inclusivity/exclusivity implicit to begin with. If the syntax is explicit, and the choice is captured in the resulting value (i.e. it's more than just a pair of numbers), then you just use whatever is more convenient for the task at hand. Nim almost gets there: (x .. y) is end-inclusive, and (x ..< y) is end-exclusive - but the syntax still exhibits a preference.
- ufo 6y agoI find that the global by default thing is not as much of a problem if using a linter like Luacheck. If the text editor is configured to show linter warnings it catches typos before they become a problem. https://luacheck.readthedocs.io/ https://luacheck.readthedocs.io/
- anonymoushn 6y agoGlobal by default and block level scope seems like the right choice. In a popular dynamic language that uses local by default and function level scope, the language had to include two keywords for accessing variables other than locals, and the following becomes a bug when it would not be a bug in any sane language: x = calculate_n_dogs() # later ok = all(x.status_code == 200 for x in my_other_responses) # later let_the_dogs_out(x) # oh no, why isn't x n_dogs anymore
- deleted 6y ago[deleted]
- kgm 6y agoThis is clearly about Python, so I will note that this is not actually the case: The generator expression introduces a new scope, and so it does not reassign the value of x. Python does not require the "global" and "nonlocal" keywords in order to access variables, but to reassign names brought in from an outer scope. Python 2 did have the issue where list comprehensions (though still not generator expressions) didn't introduce a new scope, and so you could indeed get issues quite similar to your example above. This was corrected in Python 3. All that said, I will agree that Python's scoping rules are pants-on-head crazy. In very nearly every other programming language under the sun, you declare variables at the point where they exist. In Python, you declare a variable when it exists somewhere else (and you then want to reassign it). This does mean that you don't need to put a "local" or "var" or what-have-you in front of each new variable you declare (which is basically the reason Python did it this way), but the semantics of the thing can take some getting used to.
- anonymoushn 6y agoI appreciate the correction and I'm glad to know this is fixed in python 3! I've run into similar issues where the variable was used in a for loop declaration rather than a list comprehension, but these are a bit easier to spot. Also, maybe people who don't use lua constantly won't be in the habit of thinking they can safely shadow locals with their looping variables.
- saagarjha 6y ago> weird choice of certain operators (~= for not equal) It's a little unconventional, but then again ~ is a fairly standard (bitwise) negation operator. > arrays start at 1 Lua doesn't do arrays, it does tables. Though they have similar syntax in certain cases, and are occasionally used for the same things, they are fundamentally different things.
- G4BB3R 6y agoI am impressed modern languages haven't adopted 1-indexed array. This was a design mistake from BCPL and C.
- sitkack 6y agoLua was initially designed as a data description language for Oil and Gas simulations written in Fortran. 1 based indexing makes perfect sense in that context.
- idle_zealot 6y agoHaving 0-indexed arrays[1] makes sense. It's lists[1] that should be 1-indexed. [0]: where "array" means contiguous memory. [1]: where "list" refers to a high-level collection of elements
- Pxtl 6y agoTo me it's the lack of some functional features for 1-liners that really trip me up. Verbose function declaration, no null-coalesce operator, no ternary operators, stuff like that. I love the platform and ideals and goals - a simple, lightweight embedding language... but the language details rub me the wrong way.
- anonymoushn 6y agoA minor hobby of mine is collecting proposed changes for Lua. Let me make sure I have these right: - some syntax like js arrow function (this is tough because {} are not block delimiters, maybe single-expression lambdas like in python? I kind of hate those though.) - `??` operator which does the same thing as `or` except when the left operand is exactly `false` - `?:` operator. Should this evaluate to exactly one value or any number of values? e.g. x?2,3:4,5 I recently encountered a library that addresses some of the first need: https://github.com/starwing/luaiter#the-selector-interface https://github.com/starwing/luaiter#the-selector-interface
- mingodad 6y agoAlso there is https://github.com/mingodad/ljs https://github.com/mingodad/ljs that changed the parser to accept a Javascript like syntax, including https://github.com/mingodad/ljsjit https://github.com/mingodad/ljsjit for LuaJit and includes a tool to automatically convert lua to ljs https://github.com/mingodad/ljs/tree/master/lua2ljs https://github.com/mingodad/ljs/tree/master/lua2ljs and did several project conversions to check that it's feasible and works (see the readme).
- Pxtl 6y agoExactly. Theoretically I could get this stuff by using Moonscript, but then I'm using a somewhat esoteric language that brings in a lot of other very unusual ideas. Although for ternary, I honestly think the "if/elseif/else can be used as an expression" has always been my favorite syntax. Or the CASE...WHEN syntax of SQL.
- anonymoushn 6y ago