| ▲ | antirez 9 hours ago |
| If this had been available in 2010, Redis scripting would have been JavaScript and not Lua. Lua was chosen based on the implementation requirements, not on the language ones... (small, fast, ANSI-C). I appreciate certain ideas in Lua, and people love it, but I was never able to like Lua, because it departs from a more Algol-like syntax and semantics without good reasons, for my taste. This creates friction for newcomers. I love friction when it opens new useful ideas and abstractions that are worth it, if you learn SmallTalk or FORTH and for some time you are lost, it's part of how the languages are different. But I think for Lua this is not true enough: it feels like it departs from what people know without good reasons. |
|
| ▲ | norir 8 hours ago | parent | next [-] |
| I don't love a good deal of Lua's syntax, but I do think the authors had good reasons for their choices and have generally explained them. Even if you disagree, I think "without good reasons" is overly dismissive. Personally though, I think the distinctive choices are a boon. You are never confused about what language you are writing because Lua code is so obviously Lua. There is value in this. Once you have written enough Lua, your mind easily switches in and out of Lua mode. Javascript, on the other hand, is filled with poor semantic decisions which for me, cancel out any benefits from syntactic familiarity. More importantly, Lua has a crucial feature that Javascript lacks: tail call optimization. There are programs that I can easily write in Lua, in spite of its syntactic verbosity, that I cannot write in Javascript because of this limitation. Perhaps this particular JS implementation has tco, but I doubt it reading the release notes. I have learned as much from Lua as I have Forth (SmallTalk doesn't interest me) and my programming skill has increased significantly since I switched to it as my primary language. Lua is the only lightweight language that I am aware of with TCO. In my programs, I have banned the use of loops. This is a liberation that is not possible in JS or even c, where TCO cannot be relied upon. In particular, Lua is an exceptional language for writing compilers. Compilers are inherently recursive and thus languages lacking TCO are a poor fit (even if people have been valiantly forcing that square peg through a round hole for all this time). Having said all that, perhaps as a scripting language for Redis, JS is a better fit. For me though Lua is clearly better than JS on many different dimensions and I don't appreciate the needless denigration of Lua, especially from someone as influential as you. |
| |
| ▲ | kbenson 4 hours ago | parent | next [-] | | > For me though Lua is clearly better than JS on many different dimensions and I don't appreciate the needless denigration of Lua, especially from someone as influential as you. Is it needless? It's useful specifically because he is someone influential, and someone might say "Lua was antirez's choice when making redis, and I trust and respect his engineering, so I'm going to keep Lua as a top contender for use in my project because of that" and him being clear on his choices and reasoning is useful in that respect. In any case where you think he has a responsibility to be careful what he says because of that influence, that can also be used in this case as a reason he should definitely explain his thoughts on it then and now. | |
| ▲ | bakkoting 6 hours ago | parent | prev | next [-] | | Formally JavaScript is specified as having TCO as of ES6, although for unfortunate and painful reasons this is spec fiction - Safari implements it, but Firefox and Chrome do not. Neither did QuickJS last I checked and I don't think this does either. | |
| ▲ | shawn_w 7 hours ago | parent | prev | next [-] | | >Lua is the only lightweight language that I am aware of with TCO. Scheme is pretty lightweight. | |
| ▲ | teo_zero 6 hours ago | parent | prev | next [-] | | > Lua has a crucial feature that Javascript lacks: tail call optimization. I'm not familiar with Lua, but I expect tco to be a feature of the compiler, not of the language. Am I wrong? | | |
| ▲ | mananaysiempre 3 hours ago | parent | next [-] | | You’re wrong in the way in which many people are wrong when they hear about a thing called “tail-call optimization”, which is why some people have been trying to get away from the term in favour of “proper tail calls” or something similar, at least as far as R5RS[1]: > A Scheme implementation is properly tail-recursive if it supports an unbounded number of active tail calls. The issue here is that, in every language that has a detailed enough specification, there is some provision saying that a program that makes an unbounded number of nested calls at runtime is not legal. Support for proper tail calls means that tail calls (a well-defined subgrammar of the language) do not ever count as nested, which expands the set of legal programs. That’s a language feature, not (merely) a compiler feature. [1] https://standards.scheme.org/corrected-r5rs/r5rs-Z-H-6.html#... | | |
| ▲ | IgorPartola 21 minutes ago | parent | next [-] | | I sort of see what you are getting at but I am still a bit confused: If I have a program that based on the input given to it runs some number of recursions of a function and two compilers of the language, can I compile the program using both of them if compiler A has PTC and compiler B does not no matter what the actual program is? As in, is the only difference that you won’t get a runtime error if you exceed the max stack size? | |
| ▲ | teo_zero 3 hours ago | parent | prev [-] | | Thank you for the precise answer. I still think that the language property (or requirement, or behavior as seen by within the language itself) that we're talking about in this case is "unbounded nested calls" and that the language specs doesn't (shouldn't) assume that such property will be satisfied in a specific way, e.g. switching the call to a branch, as TCO usually means. |
| |
| ▲ | naasking 5 hours ago | parent | prev | next [-] | | If the language spec requires TCO, I think you can reasonably call it part of the language. | | |
| ▲ | teo_zero 3 hours ago | parent [-] | | It wouldn't be the first time the specs have gone too far and beyond their perimeter. C's "register" variables used to have the same issue, and even "inline" has been downgraded to a mere hint for the compiler (which can ignore it and still be a C compiler). | | |
| ▲ | 201984 an hour ago | parent [-] | | inline and register still have semantic requirements that are not just hints. Taking the address of a register variable is illegal, and inline allows a function to be defined in multiple .c files without errors. |
|
| |
| ▲ | kerkeslager 4 hours ago | parent | prev [-] | | I don't think you're wrong per se. This is a "correct" way of thinking of the situation, but it's not the only correct way and it's arguably not the most useful. A more useful way to understand the situation is that a language's major implementations are more important than the language itself. If the spec of the language says something, but nobody implements it, you can't write code against the spec. And on the flip side, if the major implementations of a language implement a feature that's not in the spec, you can write code that uses that feature. A minor historical example of this was Python dictionaries. Maybe a decade ago, the Python spec didn't specify that dictionary keys would be retrieved in insertion order, so in theory, implementations of the Python language could do something like: >>> abc = {}
>>> abc['a'] = 1
>>> abc['b'] = 2
>>> abc['c'] = 3
>>> abc.keys()
dict_keys(['c', 'a', 'b'])
But the CPython implementation did return all the keys in insertion order, and very few people were using anything other than the CPython implementation, so some codebases started depending on the keys being returned in insertion order without even knowing that they were depending on it. You could say that they weren't writing Python, but that seems a bit pedantic to me.In any case, Python later standardized that as a feature, so now the ambiguity is solved. It's all very tricky though, because for example, I wrote some code a decade that used GCC's compare-and-swap extensions, and at least at that time, it didn't compile on Clang. I think you'd have a stronger argument there that I wasn't writing C--not because what I wrote wasn't standard C, but because the code I wrote didn't compile on the most commonly used C compiler. The better approach to communication in this case, I think, is to simply use phrases that communicate what you're doing: instead of saying "C", say "ANSI C", "GCC C", "Portable C", etc.--phrases that communicate what implementations of the language you're supporting. Saying you're writing "C" isn't wrong, it's just not communicating a very important detail: what implementations of the compiler can compile your code. I'm much more interested in effectively communicating what compilers can compile a piece of code than pedantically gatekeeping what's C and what's not. | | |
| ▲ | kristianp 2 hours ago | parent [-] | | Are you saying that Lua's TCO is an accidental feature due to the first implementation having it? How accurate is that? | | |
| ▲ | kerkeslager an hour ago | parent [-] | | What? No, I'm definitely not saying that. I'm saying it isn't very useful argue about whether a feature is a feature of the language or a feature of the implementation, because the language is pretty useless independent of its implementation(s). |
|
|
| |
| ▲ | lioeters 7 hours ago | parent | prev | next [-] | | > as my primary language I'd love to hear more how it is, the state of the library ecosystem, language evolution (wasn't there a new major version recently?), pros/cons, reasons to use it compared to other languages. About tail-calls, in other languages I've found sometimes a conversion of recursive algorithm to a flat iterative loop with stack/queue to be effective. But it can be a pain, less elegant or intuitive than TCO. | | |
| ▲ | alexdowad 6 hours ago | parent [-] | | Lua isn't my primary programming language now, but it was for a while. My personal experience on the library ecosystem was: It's definitely smaller than many languages, and this is something to consider before selecting Lua for a project. But, on the positive side: With some 'other' languages I might find 5 or 10 libraries all doing more or less the same thing, many of them bloated and over-engineered. But with Lua I would often find just one library available, and it would be small and clean enough that I could easily read through its source code and know exactly how it worked. Another nice thing about Lua when run on LuaJIT: extremely high CPU performance for a scripting language. In summary: A better choice than it might appear at first, but with trade-offs which need serious consideration. |
| |
| ▲ | xonix 7 hours ago | parent | prev | next [-] | | Re: TCO Does the language give any guarantee that TCO was applied? In other words can it give you an error that the recursion is not of tail call form? Because I imagine a probability of writing a recursion and relying on it being TCO-optimized, where it's not. I would prefer if a language had some form of explicit TCO modifier for a function. Is there any language that has this? | | | |
| ▲ | kerkeslager 3 hours ago | parent | prev | next [-] | | > More importantly, Lua has a crucial feature that Javascript lacks: tail call optimization. There are programs that I can easily write in Lua, in spite of its syntactic verbosity, that I cannot write in Javascript because of this limitation. Perhaps this particular JS implementation has tco, but I doubt it reading the release notes. > [...] In my programs, I have banned the use of loops. This is a liberation that is not possible in JS or even c, where TCO cannot be relied upon. This is not a great language feature, IMO. There are two ways to go here: 1. You can go the Python way, and have no TCO, not ever. Guido van Rossum's reasoning on this is outlined here[1] and here[2], but the high level summary is that TCO makes it impossible to provide acceptably-clear tracebacks. 2. You can go the Chicken Scheme way, and do TCO, and ALSO do CPS conversion, which makes EVERY call into a tail call, without language user having to restructure their code to make sure their recursion happens at the tail. Either of these approaches has its upsides and downsides, but TCO WITHOUT CPS conversion gives you the worst of both worlds. The only upside is that you can write most of your loops as recursion, but as van Rossum points out, most cases that can be handled with tail recursion, can AND SHOULD be handled with higher-order functions. This is just a much cleaner way to do it in most cases. And the downsides to TCO without CPS conversion are: 1. Poor tracebacks. 2. Having to restructure your code awkwardly to make recursive calls into tail calls. 3. Easy to make a tail call into not a tail call, resulting in stack overflows. I'll also add that the main reason recursion is preferable to looping is that it enables all sorts of formal verification. There's some tooling around formal verification for Scheme, but the benefits to eliminating loops are felt most in static, strongly typed languages like Haskell or OCaml. As far as I know Lua has no mature tooling whatsoever that benefits from preferring recursion over looping. It may be that the author of the post I am responding to finds recursion more intuitive than looping, but my experience contains no evidence that recursion is inherently more intuitive than looping: which is more intuitive appears to me to be entirely a function of the programmer's past experience. In short, treating TCO without CPS conversion as a killer feature seems to me to be a fetishization of functional programming without understanding why functional programming is effective, embracing the madness with none of the method. EDIT: To point out a weakness to my own argument: there are a bunch of functional programming language implementations that implement TCO without CPS conversion. I'd counter by saying that this is a function of when they were implemented/standardized. Requiring CPS conversion in the Scheme standard would pretty clearly make Scheme an easier to use language, but it would be unreasonable in 2025 to require CPS conversion because so many Scheme implementations don't have it and don't have the resources to implement it. EDIT 2: I didn't mean for this post to come across as negative on Lua: I love Lua, and in my hobby language interpreter I've been writing, I have spent countless hours implementing ideas I got from Lua. Lua has many strengths--TCO just isn't one of them. When I'm writing Scheme and can't use a higher-order function, I use TCO. When I'm writing Lua and can't use a higher order function, I use loops. And in both languages I'd prefer to use a higher order function. [1] https://neopythonic.blogspot.com/2009/04/tail-recursion-elim... [2] https://neopythonic.blogspot.com/2009/04/final-words-on-tail... | |
| ▲ | unclad5968 6 hours ago | parent | prev [-] | | > I do think the authors had good reasons for their choices and have generally explained them I'm fairly certain antirez is the author of redis | | |
|
|
| ▲ | brabel 8 hours ago | parent | prev | next [-] |
| > it feels like it departs from what people know without good reasons. Lua was first released in 1993. I think that it's pretty conventional for the time, though yeah it did not follow Algol syntax but Pascal's and Ada's (which were more popular in Brazil at the time than C, which is why that is the case)! Ruby, which appeared just 2 years later, departs a lot more, arguably without good reasons either? Perl, which is 5 years older and was very popular at the time, is much more "different" than Lua from what we now consider mainstream. |
| |
| ▲ | rwmj 8 hours ago | parent | next [-] | | We had a lot problems embedding Ruby in a multithreaded C program as the garbage collector tries to scan memory between the threads (more details here: https://gitlab.com/nbdkit/nbdkit/-/commit/7364cbaae809b5ffb6... ) Perl, Python, OCaml, Lua and Rust were all fine (Rust wasn't around in 2010 of course). | |
| ▲ | rapind 6 hours ago | parent | prev | next [-] | | > Ruby, which appeared just 2 years later, departs a lot more, arguably without good reasons either? I doubt we ever would have heard about Ruby without it's syntax decisions. From my understanding it's entire raison d'être was readability. | |
| ▲ | zeckalpha 6 hours ago | parent | prev | next [-] | | Pascal and Ada are Algol syntaxed relative to most languages. | |
| ▲ | nurettin 27 minutes ago | parent | prev [-] | | def ruby(is)
it = is
a = "bad"
example()
begin
it["had"] = pascal(:like)
rescue
flow
end
end
|
|
|
| ▲ | rweichler 9 hours ago | parent | prev | next [-] |
| I read this comment, about to snap back with an anecdote how I as a 13 year old was able to learn Lua quite easily, and then I stopped myself because that wasn't productive, then pondered what antirez might think of this comment, and then I realized that antirez wrote it. |
| |
| ▲ | aidenn0 7 hours ago | parent | next [-] | | I think the older you are the harder Lua is to learn. GP didn't say it made wrong choices, just choices that are gratuitously different from other languages in the Algol family. | |
| ▲ | le-mark 5 hours ago | parent | prev [-] | | I’m tickled that one of my favorite developers is commenting on another of my favorites work. Would be great if Nicolas Cannasse were also in this thread! |
|
|
| ▲ | CapsAdmin 3 hours ago | parent | prev | next [-] |
| It sounds like you're trying to articulate why you don't like Lua, but it seems to just boil down to syntax and semantics unfamiliarity? I see this argument a lot with Lua. People simply don't like its syntax because we live in a world where C style syntax is more common, and the departure from that seem unnecessary. So going "well actually, in 1992 when Lua was made, C style syntax was more unfamiliar" won't help, because in the current year, C syntax is more familiar. The first language I learned was Lua, and because of that it seems to have a special place in my heart or something. The reason for this is because in around 2006, the sandbox game "Garry's Mod" was extended with scripting support and chose Lua for seemingly the same reasons as Redis. The game's author famously didn't like Lua, its unfamiliarity, its syntax, etc. He even modified it to add C style comments and operators. His new sandbox game "s&box" is based on C#, which is the language closest to his heart I think. The point I'm trying to make is just that Lua is familiar to me and not to you for seemingly no objective reason. Had Garry chosen a different language, I would likely have a different favorite language, and Lua would feel unfamiliar and strange to me. |
| |
| ▲ | junon 3 hours ago | parent [-] | | GP is the creator of Redis. I would imagine he knows Lua well given that Redis has embedded it for around a decade. | | |
| ▲ | CapsAdmin 3 hours ago | parent [-] | | In that case, my point about Garry not liking Lua despite choosing it for Garrysmod, for seemingly the same reason as antirez is very appropriate. I haven't read antirez'/redis' opinions about Lua, so I'm just going off of his post. In contrast I do know more about what Garry's opinion on Lua is as I've read his thoughts on it over many years. It ultimately boils down to what antirez said. He just doesn't like it, it's too unfamiliar for seemingly no intentional reason. But Lua is very much an intentionally designed language, driven in cathedral-style development by a bunch of professors who seem to obsess about language design. Some people like it, some people don't, but over 15 years of talking about Lua to other developers, "I don't like the syntax" is ultimately the fundamental reason I hear from developers. So my main point is that it just feels arbitrary. I'm confident the main reason I like Lua is because garry's mod chose to implement it. Had it been "MicroQuickJS", Lua would likely feel unfamiliar to me as well. |
|
|
|
| ▲ | cxr 9 hours ago | parent | prev | next [-] |
| It wouldn't fix the issue of semantics, but "language skins"[1][2] are an underexplored area of programming language development. People go through all this effort to separate parsing and lexing, but never exploit the ability to just plug in a different lexer that allows for e.g. "{" and "}" tokens instead of "then" and "end", or vice versa. 1. <https://hn.algolia.com/?type=comment&prefix=true&query=cxr%2...> 2. <https://old.reddit.com/r/Oberon/comments/1pcmw8n/is_this_sac...> |
| |
| ▲ | nine_k 8 hours ago | parent | next [-] | | Not "never exploit"; Reason and BuckleScript are examples of different "language skins" for OCaml. The problem with "skins" is that they create variety where people strive for uniformity to lower the cognitive load. OTOH transparent switching between skins (about as easy as changing the tab sizes) would alleviate that. | | |
| ▲ | brabel 8 hours ago | parent | next [-] | | > OTOH transparent switching between skins (about as easy as changing the tab sizes) would alleviate that. That's one of my hopes for the future of the industry: people will be able to just choose the code style and even syntax family (which you're calling skin) they prefer when editing code, and it will be saved in whatever is the "default" for the language (or even something like the Unison Language: store the AST directly which allows cool stuff like de-duplicating definitions and content-addressable code - an idea I first found out on the amazing talk by Joe Armstrong, "The mess we're in" [1]). Rust, in particular, would perhaps benefit a lot given how a lot of people hate its syntax... but also Lua for people who just can't stand the Pascal-like syntax and really need their C-like braces to be happy. [1] https://www.youtube.com/watch?v=lKXe3HUG2l4 | | | |
| ▲ | cibyr 8 hours ago | parent | prev [-] | | People fight about tab sizes all the time though. | | |
| ▲ | dbdr 8 hours ago | parent [-] | | That's precisely the point of using tabs for indentation: you don't need to fight over it, because it's a local display preference that does not affect the source code at all, so everyone can just configure whatever they prefer locally without affecting other people. The idea of "skins" is apparently to push that even further by abstracting the concrete syntax. | | |
| ▲ | lucketone 7 hours ago | parent [-] | | > you don't need to fight over it, because it's a local display preference This has limits. Files produced with tab=2 and others with tab=8, might have quite different result regarding nesting. (pain is still on the menu) | | |
| ▲ | philsnow 4 hours ago | parent [-] | | Do you mean that files produced with "wide" tabs might have hard newlines embedded more readily in longer lines? Or that maybe people writing with "narrow" tabs might be comfortable writing 6-deep if/else trees that wrap when somebody with their tabs set to wider opens the same file? |
|
|
|
| |
| ▲ | rao-v 7 hours ago | parent | prev | next [-] | | One day Brython (python with braces allowing copy paste code to autoindent) will be well supported by LSPs and world peace will ensure | | | |
| ▲ | kevin_thibedeau 7 hours ago | parent | prev | next [-] | | VB.Net is mostly a reskin of C# with a few extras to smooth the transition from VB. | |
| ▲ | procaryote 7 hours ago | parent | prev [-] | | Lowering the barrier to create your own syntax seems like a bad thing though. C.f. perl. |
|
|
| ▲ | atdt an hour ago | parent | prev | next [-] |
| My hunch is that the same is true of Wikipedia's choice of Lua for template scripting, made back in 2012. https://lists.wikimedia.org/hyperkitty/list/wikitech-l@lists... |
|
| ▲ | garganzol 8 hours ago | parent | prev | next [-] |
| JavaScript in 2010 was a totally different beast, standartization-wise. Lots of sharp corners and blank spaces were still there. So, even if an implementation like MicroQuickJS existed in 2010, it's unlikely that too many people would have chosen JS over Lua, given all the shortcomings that JavaScript had at the time. |
|
| ▲ | vegabook 4 hours ago | parent | prev | next [-] |
| Lua has been a wild success considering it was born in Brazil, and not some high wealth, network-effected country with all its consequent influential muscle (Ruby? Python? C? Rust? Prolog? Pascal? APL? Ocaml? Show me which one broke out that wasn't "born in the G7"). We should celebrate its plucky success which punches waaay above its adoption weight. It didn't blindly lockstep ALGOL citing "adooooption!!", but didn't indulge in revolution either, and so treads a humble path of cooperative independence of thought. Come to think of it I don't think I can name a single mainstream language other than Lua that wasn't invented in the G7. |
|
| ▲ | rwmj 8 hours ago | parent | prev | next [-] |
| Out of interest, was Tcl considered? It's the original embeddable language. |
| |
| ▲ | rogerbinns 6 hours ago | parent | next [-] | | In 1994 at the second WWW conference we presented "An API to Mosaic". It was TCL embedded inside the (only![1]) browser at the time - Mosaic. The functionality available was substantially similar to what Javascript ended up providing. We used it in our products especially for integrating help and preferences - for example HTML text could be describing color settings, you could click on one, select a colour from the chooser and the page and setting in our products would immediately update. In another demo we were able to print multiple pages of content from the start page, and got a standing ovation! There is an alternate universe where TCL could have become the browser language. For those not familiar with TCL, the C API is flavoured like main. Callbacks take a list of strings argv style and an argc count. TCL is stringly typed which sounds bad, but the data comes from strings in the HTML and script blocks, and the page HTML is also text, so it fits nicely and the C callbacks are easy to write. [1] Mosaic Netscape 0.9 was released the week before | |
| ▲ | andrewshadura 7 hours ago | parent | prev [-] | | Wasn't the original Redis prototype written in Tcl? | | |
|
|
| ▲ | avaer an hour ago | parent | prev | next [-] |
| What are the chances of switching to MQJS or something like it in the future? |
|
| ▲ | dustbunny 3 hours ago | parent | prev | next [-] |
| I also strongly disliked luas syntax at first but now I feel like the meta tables and what not and pcall and all that stuff is kinda worth it. I like everything about Lua except some of the awkward syntax but I find it so much better then JS, but I haven't been a web dev in over a decade |
| |
| ▲ | junon 3 hours ago | parent [-] | | The only thing I dislike about Lua is the 1-indexing. I know they had reasons for it but it always caused issues. |
|
|
| ▲ | spacechild1 8 hours ago | parent | prev | next [-] |
| > it feels like it departs from what people know without good reasons. Lua is a pretty old language. In 1993 the world had not really settled on C style syntax. Compared to Perl or Tcl, Lua's syntax seems rather conventional. Some design decisions might be a bit unusual, but overall the language feels very consistent and predictable. JS is a mess in comparison. > because it departs from a more Algol-like syntax Huh? Lua's syntax is actually very Algol-like since it uses keywords to delimit blocks (e.g. if ... then ... end) |
| |
| ▲ | lucketone 7 hours ago | parent | next [-] | | I known for very long time that c (and co) inherited the syntax from algol. But only after long time I tried to check what Algol actually looked like. To my surprise, Algol does not look anything like C to me. I would be quite interested in the expanded version of “C has inherited syntax from Algol” Edit: apparently the inheritance from Algol is a formula: lexical scoping + value returning functions (expression based) - parenthesitis. Only last item is about visual part of the syntax. Algol alternatives were: cobol, fortan, lisp, apl. | | |
| ▲ | spacechild1 7 hours ago | parent [-] | | The use of curly braces for delimiting blocks of code actually comes from BCPL. Of course, C also inherited syntax from Algol, but so did most languages. |
| |
| ▲ | lioeters 8 hours ago | parent | prev [-] | | > consistent and predictable That's what matters to me, not how similar Lua is to other languages, but that the language is well-designed in its own system of rules and conventions. It makes sense, every part of it contributes to a harmonious whole. JavaScript on the other hand. When speaking of Algol or C-style syntax, it makes me imagine a "Common C" syntax, like taking the best, or the least common denominator, of all C-like languages. A minimal subset that fits in your head, instead of what modern C is turning out to be, not to mention C++ or Rust. | | |
| ▲ | procaryote 7 hours ago | parent [-] | | Is modern C really much more complicated than old C? C++ is a mess of course. | | |
| ▲ | lioeters 6 hours ago | parent [-] | | I don't write modern C for daily use, so I can't really say. But I've been re-learning and writing C99 more these days, not professionally but personal use - and I appreciate the smallness of the language. Might even say C peaked at C99. I mean, I'd be crazy to say that C-like languages after C99, like Java, PHP, etc., are all misguided for how unnecessarily big and complex they are. It might be that I'm becoming more like a caveman programmer as I get older, I prefer dumb primitive tools. |
|
|
|
|
| ▲ | zeckalpha 6 hours ago | parent | prev | next [-] |
| Redis' author also made jimtcl, so I don't think the lack of a small engine was the gap |
| |
|
| ▲ | andrewstuart 5 hours ago | parent | prev | next [-] |
| Lua - an entire language off by one. |
|
| ▲ | hnlmorg 7 hours ago | parent | prev | next [-] |
| Lua only departs from norms if you’ve had a very narrow experience with other programming languages. Frankly, I welcome the fact that Redis doesn’t use JavaScript. It’s an abomination of a language. The fewer times I need to use it the better. |
| |
| ▲ | DebugDruid 4 hours ago | parent [-] | | I think criticizing JavaScript has become a way of signaling "I'm a good programmer." Yes, good programmers ten years ago had valid reasons to criticize it. But today, attacking the efforts of skilled engineers who have improved the language (given the constraints and without breaking half of the web) seems unfair. They’ve achieved a Herculean task compared to the Python dev team, which has broken backward compatibility so many times yet failed to create a consistent language, lacking a single right way to do many things. | | |
| ▲ | hnlmorg an hour ago | parent [-] | | > But today, attacking the efforts of skilled engineers who have improved the language (given the constraints and without breaking half of the web) seems unfair. I was criticising a thing not a person. Also your comment implies it was ok to be critical of a language 10 years ago but not ok today because a few more language designers might get offended. Which is a weird argument to make. |
|
|
|
| ▲ | IshKebab 9 hours ago | parent | prev [-] |
| Not to mention the 1-based indexing sin. JavaScript has a lot of WTFs but they got that right at least. |
| |
| ▲ | nine_k 7 hours ago | parent | next [-] | | This indeed is not Algol (or rather C) heritage, but Fortran heritage, not memory offsets but indices in mathematical formulae. This is why R and Julia also have 1-based indexing. | | |
| ▲ | cmrdporcupine 6 hours ago | parent | next [-] | | Pascal. Modula-2. BASIC. Hell, Logo. Lately, yes, Julia and R. Lots of systems I grew up with were 1-indexed and there's nothing wrong with it. In the context of history, C is the anomaly. I learned the Wirth languages first (and then later did a lot of programming in MOO, a prototype OO 1-indexed scripting language). Because of that early experience I still slip up and make off by 1 errors occasionally w/ 0 indexed languages. (Actually both Modula-2 and Ada aren't strictly 1 indexed since you can redefine the indexing range.) It's funny how orthodoxies grow. | | |
| ▲ | teo_zero 5 hours ago | parent | next [-] | | In fact zero-based has shown some undeniable advantages over one-based. I couldn't explain it better than Dijkstra's famous essay:
http://www.cs.utexas.edu/~EWD/ewd08xx/EWD831.PDF | | |
| ▲ | cmrdporcupine 5 hours ago | parent [-] | | It's fine, I can see the advantages. I just think it's a weird level of blindness to act like 1 indexing is some sort of aberration. It's really not. It's actually quite friendly for new or casual programmers, for one. |
| |
| ▲ | nine_k 5 hours ago | parent | prev [-] | | Pascal, frankly, allowed to index arrays by any enumerable type; you could use Natural (1-based), or could use 0..whatever. Same with Modula-2; writing it, I freely used 0-based indexing when I wanted to interact with hardware where it made sense, and 1-based indexes when I wanted to implement some math formula. |
| |
| ▲ | IshKebab 6 hours ago | parent | prev [-] | | And MATLAB. Doesn't make it any better that other languages have the same mistake. |
| |
| ▲ | idle_zealot 8 hours ago | parent | prev | next [-] | | Does it count as 0-indexing when your 0 is a floating point number? | | |
| ▲ | krackers 8 hours ago | parent [-] | | Actually in JS array indexing is same as property indexing right? So it's actually looking up the string '0', as in arr['0'] | | |
| ▲ | idle_zealot 7 hours ago | parent [-] | | Huh. I always thought that JS objects supported string and number keys separately, like lua. Nope! [Documents]$ cat test.js
let testArray = [];
testArray[0] = "foo";
testArray["0"] = "bar";
console.log(testArray[0]);
console.log(testArray["0"]);
[Documents]$ jsc test.js
bar bar
[Documents]$
| | |
| ▲ | nvlled 2 hours ago | parent | next [-] | | Lua supports even functions and objects as keys: function f1() end
function f2() end
local m1 = {}
local m2 = {}
local obj = {
[f1] = 1,
[f2] = 2,
[m1] = 3,
[m2] = 4,
}
print(obj[f1], obj[f2], obj[m1], obj[m2], obj[{}])
Functions as keys is handy when implementing a quick pub/sub. | |
| ▲ | aidenn0 7 hours ago | parent | prev [-] | | They do, but strings that are numbers will be reinterpreted as numbers. [edit] let testArray = [];
testArray[0] = "foo";
testArray["0"] = "bar";
testArray["00"] = "baz";
console.log(testArray[0]);
console.log(testArray["0"]);
console.log(testArray["00"]);
| | |
| ▲ | minitech 6 hours ago | parent [-] | | That example only shows the opposite of what it sounds like you’re saying, although you could be getting at a few different true things. Anyway: - Every property access in JavaScript is semantically coerced to a string (or a symbol, as of ES6). All property keys are semantically either strings or symbols. - Property names that are the ToString() of a 31-bit unsigned integer are considered indexes for the purposes of the following two behaviours: - For arrays, indexes are the elements of the array. They’re the properties that can affect its `length` and are acted on by array methods. - Indexes are ordered in numeric order before other properties. Other properties are in creation order. (In some even nicher cases, property order is implementation-defined.) { let a = {}; a['1'] = 5; a['0'] = 6; Object.keys(a) }
// ['0', '1']
{ let a = {}; a['1'] = 5; a['00'] = 6; Object.keys(a) }
// ['1', '00']
|
|
|
|
| |
| ▲ | bigstrat2003 3 hours ago | parent | prev | next [-] | | There's nothing wrong with 1-based indexing. The only reason it seems wrong to you is because you're familiar with 0-based, not because it's inherently worse. | |
| ▲ | coliveira 8 hours ago | parent | prev | next [-] | | If you can't deal with off-by-one errors, you're not a programmer. | |
| ▲ | chrisweekly 8 hours ago | parent | prev [-] | | Except for Date. |
|