Rendered at 21:07:52 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
Heliodex 19 hours ago [-]
A comment <https://github.com/LuaJIT/LuaJIT/issues/1475#issuecomment-47...> has already been made on the issue regarding the ternary operator, recommending `if x then y else z` over `x ? y : z`. This is exactly how it's done with if-then-else expressions in Luau <https://luau.org/syntax/#if-then-else-expressions>, another language compatible with Lua, and makes it a ton easier to nest (especially with elseif) and I believe still easier to read than `y if x else z`.
noelwelsh 13 hours ago [-]
Exactly. I don't understand why people think the ternary operator is needed when you can just make `if` an expression instead of a statement. Then there is no new syntax to learn and `if` just becomes more useful.
aeonflux 7 hours ago [-]
I don't really understand where is this need to compress the logic into where small chunks comes from. In result we get single line of code which has multiple statement conditions, different paths, and it's not possible to grasp in one go.
Other practical example why ternary is bad: Many code-coverage solutions break on ternary because they don't correctly see that one of the branches was missed in tests.
bruce343434 4 hours ago [-]
Because you can deduplicate certain parts of the logic which make the whole thing less error prone, such as
if c
x=1
else
x=2
If I ever want to change x, or refactor this code some other way, its a more brittle process over x=c?1:2
The ternary expression also takes up much less space so there is less of an emphasis on it, this can be a stylistic tool in a programmer's toolbox
drunken_thor 6 hours ago [-]
I think that allowing an if statement to return a value to deal with the ternary introduces a now concept to Lua and that is that the value on the final line of a block is a return value much like Ruby. This changes the logic of the entire language more than adding a ternary. I do prefer the if statement as it allows so much more emergent behaviour, but it does have more implications to consider.
Heliodex 4 hours ago [-]
I suppose, though I feel what most people in this thread are thinking of is updating the existing if statement to also work as an expression, which does have plenty of implications (not that I think they would be bad, just more of a change to the language than the feature designers were going for) including final returns. The example I took from Luau still keeps the if statement and the if-then-else expression as separate constructs. One problem is that the statement and expression versions look very similar despite having different semantics (expression version must only contain expressions in its branches, must have an `else` case, does not have `end`).
Of course there are differences between LuaJIT and Luau that I think influence their decisions on possible ternary expression features:
- Luau users are disproportionately beginners to programming that I believe would find the if-then-else expression syntax easier to learn; LuaJIT developers have a larger user base of professional devs wanting to make their code faster, and they will probably be more familiar with the `x ? y : z` style since it's used in plenty of other languages.
- Luau is a lot faster moving in its development than LuaJIT in terms of language features, the Luau team just wanted to move people to ternaries from `x and y or z` because it's easier to optimise in a normal interpreter; LuaJIT, with their JIT, I assume would be able to more easily implement optimisations for constructs like `x and y or z` despite its slight semantic differences (my assumption on why the change is being considered now rather than earlier).
mjcohen 19 hours ago [-]
The ternary operator is easy to nest if you put each clause on a separate line. Then it looks just like nested if-then-else.
edoceo 19 hours ago [-]
I love the ternary operator as much as anyone. But dang if it doesn't get hard to read when there is are a few, nested even.
Does that operator compile to faster assembly that if I make the same logic with verbose `if` logic? Is that a language specific outcome?
if cond1 then res1
else if cond2 then res2
else if cond3 then res3
else or_else_res
or
if cond1 then res1
elif cond2 then res2
elif cond3 then res3
else or_else_res
what is most lua-like?
shevy-java 18 hours ago [-]
I find that so much harder to read compared to if/else or case/when in ruby.
The ? is basically an attempt to use fewer if/else, at the cost of condensed if-else like structure. I always need to look at both parts after the ? whereas in a single if or elsif I don't. case/when in ruby is even better here e. g. regex check:
def foo(i)
case i
when /^cat/
handle_cats
when /^dog/
handle_dogs
(I ommitted the "end"s here to just focus on the conditional logic.)
spider-mario 12 hours ago [-]
Unless you mess up its associativity, like PHP until 7.4.
So is LuaJIT resuming active development after a decade or so of only maintenance? Great!
A lot of these changes make sense (although some of them are a bit too TIMTOWTDI for my taste) - but perhaps LuaJIT 3 would benefit from a change of name as well? Certainly with all these changes, it would be more like a separate language than merely a JIT-compiled version of Lua.
orthoxerox 14 hours ago [-]
A bunch of them are from Luau, the Roblox fork of Lua and the dialect most young programmers know. Adding them to LuaJIT will make it easier to write for both Zoomers and AI agents, who have been exposed to a lot of Luau code.
krapp 11 hours ago [-]
I know the LuaJIT maintainer(s?) will never add it because it's too radical a departure from Lua but I wish they would include Luau's type annotations. There are typed languages like Teal that will compile to Lua that should work (although I've had a difficult time getting Teal to work with cdefs) and you can kind of fake it by using C structs obviously but having such a feature be native to Lua itself would be nice.
201984 20 hours ago [-]
>TIMTOWTDI
What on earth is this supposed to mean?
Twirrim 20 hours ago [-]
There Is More Than One Way To Do It.
That takes me back a bit. It's a perl-ism. I used to think it was a great design feature but I've come to strongly prefer "There should be one way to do it, and it should be obvious"
BobBagwill 7 hours ago [-]
TCBOO, AKA, the Highlander Conjecture.
201984 20 hours ago [-]
Interesting, thank you.
ncruces 11 hours ago [-]
Using acronyms is one of those ways. /s
matheusmoreira 20 hours ago [-]
There is more than one way to do it.
18 hours ago [-]
matheusmoreira 5 hours ago [-]
> but perhaps LuaJIT 3 would benefit from a change of name as well?
> Certainly with all these changes, it would be more like a separate language than merely a JIT-compiled version of Lua.
I agree. I suggested this on the GitHub issue but got nothing but downvotes.
Looks like LuaJIT is catching up, but calling these "syntax extensions" is confusing. Is the intent to hold LuaJIT fixed against some earlier Lua version (I guess 5.1) and adopt newer syntax piecemeal?
I welcome the compound assignment operators. Playdate's version of Lua also has that extension.
Heliodex 3 hours ago [-]
I wouldn't be surprised if their plan is to keep compatible with 5.1 and adopt newer features where feasible/compatible. Luau, another language with the explicit goal of extending Lua 5.1 in a compatible way, has a section in their documentation listing all newer Lua features and detailing why they chose to or not to adopt them <https://luau.org/compatibility/>. The needs of Luau and LuaJIT are different though the reasoning is nonetheless fascinating.
orthoxerox 14 hours ago [-]
LuaJIT is an involuntary fork of 5.1. It already had various extensions that conflicted with the 5.2 implementation of the same features, and Mike Pall made it clear on the mailing list he wasn't going to change how LuaJIT worked.
matheusmoreira 5 hours ago [-]
> Is the intent to hold LuaJIT fixed against some earlier Lua version (I guess 5.1)
Yeah. PUC-Rio went in a direction that Mike Pall didn't want to follow. Something to do with garbage collector finalizers, if I remember correctly, which is a notoriously thorny issue in every language it exists.
fsfod 3 hours ago [-]
I think it was more the extra layers of indirection added to function environment\effectively global variable access added in 5.2 .
The removal of scanning for changed userdata finalizer meta method in 5.2 is just a commonsense fix for bad design that made GC atomic phase run time, thats not incremental scale up with the number of GC userdata objects alive no matter if they have a finalizer or not.
Dylan16807 44 minutes ago [-]
5.1 had function environments, then 5.2 changed them from a hidden value to a hardcoded variable name that was easier to change. How did that add extra indirection or slow anything down?
martinjc 32 minutes ago [-]
Say you were to embed a lua engine today. Which implementation would you choose? I also consider syntax important. So if you were to choose what seemed sane, but also something you saw working in 5 years.
I am asking because i want to implement plugins in my media server, however i want to guard them in vm's i can control.
Ardren 17 hours ago [-]
> For compatibility with other computer languages, the following classic Lua operators can be written in a more customary syntax:
Why though? What does changing `and` to `&&` actually achieve? Were people confused?
Changing the syntax seems very surface level. It's not actually fixing any problems, just making Lua no longer look like Lua. It's not going to help anyone write/learn Lua. It will make everything more complicated as there are now two ways to do everything.
This feels like adding braces to Python because you don't like indenting your code.
nullpoint420 16 hours ago [-]
> This feels like adding braces to Python because you don't like indenting your code.
Ruby has both kinds of operators as well, and it's fine. The thing in Ruby, though, is that the English logical operators have lower precedence than the symbolic logical operators, so you can use them in place of parentheses. Sometimes that's confusing, other times it can be used to make code very readable.
In general, I would expect symbolic operators to be desirable in complex boolean expressions, because "loud punctuation" stands out among English words when reading the code.
spider-mario 12 hours ago [-]
Same in Perl, hence the good old pattern:
open my $fh, '<', 'input.txt' or die;
codesnik 10 hours ago [-]
yes, ruby inherited this from perl, though 'or' has lower precedence than 'and' in perl, and they're equal in ruby. Which sounds like something going to cause mistakes, but I yet to see 'and' and 'or' together in the same expression in ruby.
ClikeX 10 hours ago [-]
I've always found it odd that and/or in Ruby isn't just considered equal to &&/||, and I have never really used the english operators except for the usual modifiers like if and unless.
What is a practical use case where the lower precedence makes sense?
aeonflux 7 hours ago [-]
Those two behave in the same way if you drop the parentheses:
1. statement if (condition || something)
2. (statement if condition) or something
doophus 15 hours ago [-]
> Why though? What does changing `and` to `&&` actually achieve? Were people confused?
Also consider AI, that has a greater training base of JavaScript than Lua. So making Lua look more like JS, should improve output and reduce mistakes.
lionkor 14 hours ago [-]
No, don't consider AI.
boomlinde 6 hours ago [-]
I can't imagine that making the differences between the languages more subtle would improve the performance of chatbots. Subtleties aren't their strong suit.
boxed 14 hours ago [-]
AI has greater training on Python, which uses `and` and `or`, and it has absolutely no issue keeping that straight.
12 hours ago [-]
ianm218 18 hours ago [-]
Tangently related but I’ve been deep in Lua recently working on a rust implementation that supports Lua 5.1-5.5 in one Rust Binary https://github.com/ianm199/omnilua.
My ultimate goal was to support LuaJIT in Rust as well but this does not make it easier.
valorzard 15 hours ago [-]
Also, one issue I have with this repo is that, since so much of it seems to use Claude, as an actual human I struggle to read and parse any of the information.
In a mix of official and unofficial benchmarks wall clock performance is ~1.4x as fast as C Lua and the memory usage is ~1.7x.
So performance is worse to be clear but within range. There’s some performance improvements I haven’t gone for yet that would get it down to ~1.1 I think.
lifthrasiir 16 hours ago [-]
Oh wow, seriously, I always thought Lua should have been like this. The 5.1/5.2/5.3+ split was so painful.
> My ultimate goal was to support LuaJIT in Rust as well but this does not make it easier.
I think you could stop right before the syntax extension.
ianm218 4 hours ago [-]
Heh I was going to queue up a skill that uses the CLI to make it easy to convert scripts to older or newer versions.
If you have any Lua use cases let me know I’m looking for more real world use use cases to justify the effort here.
genxy 17 hours ago [-]
This is amazing! Can a program call across versions? Like could we take a Lua 5.1 codebase and upgrade only a portion of it at a time to a new Lua version?
ianm218 6 hours ago [-]
Hmm I think in general I would not recommend doing this just because Lua does change pretty significant things from 5.1-5.5 so you could have some really hard to understand behavior if some portions are 5.1 vs 5.4 for example.
I think where it would be most helpful is converting a codebase and being able to easily run tests to ensure behavior is the same.
Do you have a use case in mind? Would love to chat or take a look at an github issue if you create one.
valorzard 15 hours ago [-]
[dead]
camgunz 14 hours ago [-]
One of the interesting things about Lua is because they don't really maintain compatibility between major versions, there isn't a huge ecosystem, and as a result there's less friction against making your own, slightly incompatible version. When you add on the simplicity of implementing the language, it's created a really diverse set of lua-alikes. Weird (and cool) for a language to have a diverse ecosystem of implementations, but not necessarily libraries.
matheusmoreira 5 hours ago [-]
Fragmentation is terrible for a language. Just look at Scheme. Nobody actually uses Scheme itself, it's always some Scheme implementation like Racket, Guile, Chicken, Chez, etc.
Languages should probably protect themselves with trademarks or something.
ricardobeat 20 hours ago [-]
I see JavaScript.
Some of these really look like QoL improvements. I'm not convinced ternary statements are an ergonomic improvement in particular. The examples given don't make a compelling case, 'visually tidy' is not the same as readable.
nine_k 19 hours ago [-]
Worse, I see C (as in ! or &&), and Perl (as in manifestly more than one way to do it).
There are real improvements though, such as ?. and ??= that help with default-nullable everything.
Ternary is very useful, but it I'd rather see it implemented idiomatically:
pos += (if forward then +1 else -1)
Structural pattern-matching could be fantastic, but no syntax is suggested.
9 hours ago [-]
jsomedon 12 hours ago [-]
I kinda have seen somewhere on internet, that the language design of lua and js(well, ecmascript to be precise) is somehow related. But can't really find the exact reference I have seen.. it was long time ago when I read this.
cygx 10 hours ago [-]
There's some overlap in the languages they were inspired by (eg Scheme, or the chains Modula -> Lua vs Modula -> Java -> Javascript), but as far as I'm aware, the original designs were made independently.
Now, the object systems do look similar, but that seems to be a case of convergent evolution: Javascript took direct inspiration from Self, whereas Lua's system is based on a more generic fallback mechanism for table access.
fluoridation 13 hours ago [-]
Lua to me always felt very JavaScripty, just with a different syntax.
drdexebtjl 8 hours ago [-]
Lua predates JavaScript by about 2 years though.
3eb7988a1663 20 hours ago [-]
Never will I understand ternary operators. As soon as you introduce it, some chuckle heads want to use them everywhere. Worse if the syntax allows nested ternarys. I guess it keeps the language open for code golfing, but it otherwise seems like redundant syntax that at best saves a few characters.
demilicious 20 hours ago [-]
That’s why “if” should just be an expression
matheusmoreira 20 hours ago [-]
This is the best answer in my opinion. Ternary is just sugar for an expressive if. LuaJIT seems to be focusing on adding new syntax though, maintainer might not be amenable to updating existing semantics.
boomlinde 5 hours ago [-]
I imagine that if/if-else as expressions and then necessarily their bodies as expressions would entail a much more fundamental change to the language. You then have to think of a way for the bodies to indicate a result. That, or you have to make a special case for if/else sequences where the bodies are bare expressions, in which case you've just invented the ternary operator.
Zig and Rust have addressed the problem of how the result of a block expression should be presented, but neither solution seems particularly satisfying to me.
In Rust, blocks may end with an expression, giving them a non-void result. But a block may also end in a statement, the only difference being that the statement ends in a semicolon, in which case the expression still has the void result, and I think that semicolon being the only difference makes it hard to scan at a glance where values come from.
In Zig, blocks may give non-void results by `break`ing out of them with an expression. But break normally ignores blocks and break out of loops only, so to break out of blocks you have to provide a label for it and give that when you break so as to break out of the named block and not the outer loop, e.g. `const x = label: { break :label 35; }`. That creates a problem of one of the most difficult classes in software engineering: naming things. Ideally I think `break` from a block should have its own keyword, e.g. `const x = { give 35; }`
wavemode 18 hours ago [-]
I don't think if-expressions have to affect existing semantics. Basically, in the parser you would have two different kinds of AST nodes, one for when the `if` keyword is encountered in statement position and another for when it's encountered in expression position.
Right now, `if` in expression position is just a syntax error ("unexpected symbol")
Joker_vD 16 hours ago [-]
Well, I believe there could be some complications with parsing related to the fact that Lua grammar doesn't really requires semicolons between the statements.
But other than that, yeah, detecting "if" in the expression position is pretty unambiguous. No idea why most languages went with "cond-expr ? then-expr : else-expr" bracketed syntax instead.
_flux 15 hours ago [-]
Surely the most likely explanation is familiary from C?
But e.g. ml-family languages (like OCaml, F#, Haskell) and Rust just have the *if* expression that has a non-void value. If your language accepts expressions as statements (most do?), then I think that should just be compatible out of the box.
Joker_vD 15 hours ago [-]
Yes, but why C had that syntax? Oh, right, because it didn't use if-then[-else]-end for the conditional statement, and reusing if(cond)[-else] with prohibited braces would be awkward.
Oh, and Lua most famously does not accept expressions as statements. Which, now that I think of it, would actually evade most of the parsing complications.
rirze 6 hours ago [-]
As long as the language supports lazy evaluation and short-circuiting through expressions, then great.
NuclearPM 18 hours ago [-]
Yep. Everything should be.
201984 20 hours ago [-]
Lua basically already has ternary operators anyway since "and" and "or" short circuit. I also don't see the need of adding additional syntax for it.
local x = condition ? value_a : value b
local x = condition and value_a or value_b
matheusmoreira 20 hours ago [-]
> The classic Lua idiom a and b or c has a pitfall when b is nil or false: then c is returned, even when a is truthy.
> E.g. true and false or 42 returns 42, whereas true ? false : 42 returns the (expected) false.
nmz 4 hours ago [-]
No, not basically, it simply doesn't have them, Ternary means three as in it operates on 3 operands, and/or operates on 2 operands. They are also not equivalent.
x = a ? b : c # x is b, same as you would if a {x=b} else {x=c}
lua and/or
a,b,c = true, 1, 2
x = a and b or c -- x is b
a,b,c = true, false, 2
x = a and b or c -- x is c
The or is dependent on its previous operand, so b will return false and skips to c, even if you meant for it to be b. you must use an if then else. However, you can have more than a ternary, if there is no need for short-circuit evaluation, as in, any of the operand is not a function CALL like c(), and you want to remain inside an expression, then you can do this instead
select (select is a native C function, this is faster than the table creation below)
x = select(a and 1 or 2, b, c)
table creation/selection
x = ({false,2})[a and 1 or 2]
of course, doing something like
local x; if a then x=b else x=c end
does not look so bad
7 hours ago [-]
Gualdrapo 20 hours ago [-]
I guess for the JS case it makes sense to be able to shave a few characters for file shrinking purposes, but generally I'm more biased to code clarity and "self-explainability"
NuclearPM 18 hours ago [-]
That’s what compression is for.
hiccuphippo 20 hours ago [-]
I find it most useful in languages that have non-mutable variables and you want to avoid a mutable variable or an extra function when the value comes from a simple condition.
otikik 7 hours ago [-]
In Lua (and LuaJIT) you can already use `and` and `or`:
local x = y and y + 1 or 0
The knuckle heads are already using them everywhere.
HexDecOctBin 15 hours ago [-]
It might have been better to publicly document and stabilise the LuaJIT bytecode, which would allow people to then come up with whatever syntax they wanted in their own custom frontends.
matheusmoreira 20 hours ago [-]
Looks like LuaJIT is really going to fork away from Lua this time. After these changes, it won't be a compatible Lua 5.1 implementation anymore, it will be a new language.
So shouldn't it have a new name?
orthoxerox 14 hours ago [-]
Why won't it be compatible? Any code written in Lua 5.1 will run on LuaJIT.
matheusmoreira 5 hours ago [-]
But not the other way around.
orthoxerox 4 hours ago [-]
LuaJIT has always been a superset of 5.1.
matheusmoreira 3 hours ago [-]
Which is why it should be a new language. Like C and C++.
ulbu 16 hours ago [-]
well, it doesn’t say Lua5.1-JIT
a_t48 19 hours ago [-]
It could be opt in.
sourcegrift 19 hours ago [-]
Are there any rough estimates on popularity of lua implementations? At this point it feels lua means luajit
latenightcoding 19 hours ago [-]
not even close, because there are a lot of places where you can't run LuaJIT
tuvix 18 hours ago [-]
Where can you not run LuaJIT? Genuinely curious
Boxxed 17 hours ago [-]
Wasm and platforms like iOS and Nintendo Switch (I think).
extrememacaroni 17 hours ago [-]
anywhere that does not allow self modifying code such as app stores.
Dylan16807 16 hours ago [-]
LuaJIT is not just a JIT, it also includes high speed interpreters for x86, Arm, and more.
I'm proud of it and thankfull to the Lua/Luajit projects.
klibertp 3 hours ago [-]
This:
var ary = [1,2,3,4]; //Array style declaration, syntax sugar for {}
Is not a good idea. I tried using Haxe with Lua target at some point - the mismatch between what you think you get with [], and what you actually get in Lua, requires either a lot of boilerplate (Haxe compiles [] to Array objects), or a chronic WTF from all the new people reading your code (and from yourself, after a few weeks to months of disuse). If you want [1,2,3], make it behave more like an array - or just leave it out, would be my advice. Lua doesn't have arrays, and adding syntax that suggests it does will be a permanent footgun for your users, I think.
mid-kid 8 hours ago [-]
LuaJIT has held back the lua ecosystem for over a decade. There's no reason to not at least try to move the implementation closer to luau or puc lua, not create yet more incompatible syntax
kzrdude 7 hours ago [-]
I don't think Lua is your average ecosystem. Lua is used as an embedded interpreter. For example, Neovim doesn't want to change its configuration language's syntax just because there is a new version of Lua available.
On the contrary, we can claim that luajit has stabilized lua for implementations and for users (strengthening Lua 5.1 dominance, which makes the experience more homogenous across apps).
bawolff 20 hours ago [-]
+= and ..= are things i find i'm constantly missing in lua.
Personally im a fan of introducing ternaranary operator in lua. Everyone uses `x and y or z` as a ternanary which i find way more confusing than ?:
linzhangrun 15 hours ago [-]
Lua pursues "simplicity, purity, and simplicity." So... too much syntactic sugar is unlikely
spankalee 16 hours ago [-]
They shouldn't add the ternary operator, it keeps `?` from being usable on it's own for safe navigation and requires the ugly `?.` operator, like `a?.[b]` or `f?.()` instead of `a?[b]` or `f?()`.
orphea 10 hours ago [-]
Yep. This is awful:
obj?.:method(…)
coneonthefloor 6 hours ago [-]
The syntax proposals look fine. But I don’t feel they are needed. Lua is easy to write and grok. I default to using LuaJIT, and have never had an issue with the actual code. Integration with the Lua ecosystem is the problem. Fix the compatibility issues with LuaRocks packages and PucRio. That would be the best dev ex update in my opinion.
pseudony 17 hours ago [-]
Seems like a bad idea to actively diverge from Lua, hostile even, especially without at least a clear change of name.
linzhangrun 20 hours ago [-]
I thought luajit had completely stopped feature updates
10 hours ago [-]
le-mark 20 hours ago [-]
I’m confused I thought Mike Pall left luajit and Laurence Tratt took over as maintainer?
ltratt 4 hours ago [-]
We did have a project some years ago looking at extending LuaJIT on which Tom Fransham did excellent work. Alas, the funder's priorities moved on (as is their right!), so we didn't get to finish it. It was a bit sad, as we (well, mostly Tom) had built up a real head of steam, but c'est la vie. Still, either way, I would never have claimed enough personal expertise with LuaJIT to take over maintainership!
dang 19 hours ago [-]
Mike Pall is to LuaJIT as PG is to Hacker News.
Edit: meaning he can come back anytime.
misiek08 11 hours ago [-]
He left for a break, returned and there was no second break or anything.
I don't want to spam it in repo, so leaving it here: he is kind of a hero doing this work and I (hopefully we) am very grateful for his contribution to this world.
swah 10 hours ago [-]
Are there great uses of LuaJIT out there? It was such a big thing before fast JS engines IIRC.
Some of these things are already implemented in PUC Lua. I don't know why they are diverting from lua spec on other aspects though. Why not work together with the PUC Lua team to add some of these to both lua versions and work on bringing their functionality closer to each other
instead of further apart. You might as well just make a new language instead. New features will end up not being used in effort to keep lua scripts portable.
In effort to not pollute the github issue, and hopes that the authors read this thread, I will put some of my thoughts here. There are 3 main strengths of Lua: Embeddable, Fast, and Small(easy to learn). I worry some of these changes divert from the last, expanding the language into a more complicated language.
Here is a list of things already implemented in PUC Lua so can be considered safe to add:
● ~ a Bitwise negate
● a & b Bitwise and
● a | b Bitwise or
● a ~ b Bitwise Xor
● a << b Left-shift
● a >> b Logical right-shift
● a // b Floor divide
● break Break statement
Don't get me wrong, I love some of these quality of life changes like:
● Const keyword: changing const from `local a <const> = 42` to `const a = 42` is far better syntax. The bracketed syntax was never a good idea.
● nil-Coalescing and safe navigation are great additions as they are basically macros at the parsing stage.
● Compound assignment is also basically a macro at the parsing stage as well. Lua should already have this honestly.
● Ternary Operator: I *like* it and it will help the stumbling block of the `a and b or c` common pattern already in use. Though I think (like others have stated) the If/then/else syntax would be more inline with the language, similar to ruby and would enable far more emergent behaviour. However it does establish a new pattern that the last value in a block is a return value similar to ruby so I am conflicted about that.
● `continue` it is nicer than a goto and is helpful.
● String interpolation: I honestly don't love lua's concat operator `..` so honestly string interpolation would be a nice to have and a feature of many modern languages. However I do worry about it's effect on parsing performance, and complexity of the language.
● Underscores in numbers: *shrug*
These are great ideas for the language but I would want all lua versions to support them, not just JIT. These are things that I think are a distraction:
● The `and` `&&` and `or` `||`. This just goes in the wrong direction for lua. It is often confusing in ruby (especially because of precedence issues) but also lua is a wordy language. It has `do` `end` blocks instead of brackets. It adds ambiguity for no reason.
● Short form function syntax. Lua does not need this and I am not sure anyone asked for this. Why `a = |x| do ... end` is more helpful than just `a = function(x) ... end` is unclear and would love to hear more about why this is being considered.
● Named varargs: It may be nice, but there is no real reason to add this. If you wanted a name for your varargs you could do `local name = ...` or just use the `args` variable already available in every function.
● Switch/Match/Select Statements: An optimized if/else block works just as well and another expansion of a small language.
rustyminnow 2 hours ago [-]
I asked for short form functions! Neovim has a ton of apis that accept functions as configuration. Having to write `function(x) return x > 3 end` is so much more annoying than `|x| -> x > 3`. I'd prefer just `|x| x > 3` but alas. I agree that a `|x| -> do ... end` lambda variant is redundant to normal anonymous functions though.
nmz 21 minutes ago [-]
> Const keyword: changing const from `local a <const> = 42` to `const a = 42` is far better syntax. The bracketed syntax was never a good idea.
The bracketed syntax is an okay idea especially for <close>, adding close as a keyword would be a disaster given how common the word is. If anything, local should have been tossed away as a keyword and the bracketed syntax adopted completely
v <local const close>, v2 = io.open'file', false
g <global const> = 5
5.5 introduced global which makes better use of attributes as well. of course, I don't deny how great it would be to not type <> or local const since const would already imply a local
> string interpolation
Hisham already made this nice module https://github.com/hishamhm/f-strings Which I don't dare use, even if you don't have string interpolation. Of course, I don't care because I just have a table.format(tbl, "tbl.key is %{key}"), is it a little tedious? sure, but its just a gsub call.
> short form function syntax
I disagree with this, I've always wanted it and roll my eyes as I write/create a function, especially when you like to use lots of them like
str:gsub('%d+', (s){ tonumber(s)+1 })
> Named varargs: It may be nice, but there is no real reason to add this. If you wanted a name for your varargs you could do `local name = ...` or just use the `args` variable already available in every function.
You've made a mistake there
local name = ...
is
local name = ({...})[1]
In order to actually do this you need to
local name = table.pack(...)
If you will use a vararg, you will always have to do this, so why not just let it be handled in the parameter definition? its costless. AND lua5.5 already introduced this so it seems they liked it.
Quite frankly I would like the capability of treating ... as just an array like ...[1] but I haven't looked at the parser to see if its feasible or not.
> Switch/Match/Select Statements: An optimized if/else block works just as well and another expansion of a small language.
I don't disagree, but big table of functions is so ugly, switch statements would be nice
matheusmoreira 2 hours ago [-]
> You might as well just make a new language instead.
I agree. I posted this on the GitHub issues but got nothing but downvotes.
> In effort to not pollute the github issue
You should make yourself heard. It's a legitimate concern.
childintime 13 hours ago [-]
> local gauge = direction == "up" ? count + 10 : count - 10
I imagine these changes make the original Lua adepts think their training wheels have come off. The language now looks like any other. That's a good thing to me, and it will help with the adoption of the JIT, but the whole language could have been syntax modernized as a result. But.. when the work is done someone else can fork it into something independent from its Lua roots.
From that perspective the conditional operator seems defensible, where it would be feature creep otherwise, as it is generally unloved elsewhere.
freestanding 9 hours ago [-]
extensions are detachable/optional, those arent extensions but features
15 hours ago [-]
JSR_FDED 19 hours ago [-]
Cool to see this - ergonomic syntax will make it easier to recommend Lua. Hope the PUC team aligns with this.
Also, I love this kind of pragmatism:
> Exponentiation assignment a ^= b has been deliberately omitted to avoid a predictable pitfall: this is how xor assignment is written in most other computer languages. Also, a syntax for exponentiation assignment is rarely asked for.
A ‘defer’ for closing files or deleting temp files at the end of a script will make life more enjoyable.
larrry 19 hours ago [-]
I would love to see all of these come to LuaJIT (and love2d to support the new version too). It’s nice that Lua is simple, the syntax changes should hopefully make Lua code even simpler to read too
Rohansi 19 hours ago [-]
> It’s nice that Lua is simple, the syntax changes should hopefully make Lua code even simpler to read too
But which Lua?
Lua as implemented by LuaJIT is a fork of the language at this point. It's not fully compatible with PUC Lua (the reference implementation) and LuaJIT does not support features from the latest Lua version.
klibertp 3 hours ago [-]
> Lua as implemented by LuaJIT is a fork of the language at this point.
Lua is strange. Lua 5.2 was more of a "fork of the language" than LuaJIT, at the time. 5.3 and 5.4 (especially the latter) changed even more. Lua looks like a family of languages, and it seems to be by design. It probably makes sense in the "embedded scripting" space. Lua is not really meant to be (though it obviously is, if you want) a general-purpose language. It's meant for extending other apps, and scripting engines have different requirements than other language implementations: basically, hardcore backward compatibility. But it's impossible to evolve the language and innovate in its design if you commit to that. This is still an academic project, so hardcore backward compatibility is unlikely to be something the authors would value. Hence, the mixed model - every major version is a new "take" on the language. You're expected to pick a version when you first need a scripting engine, and then sit on that version until the end of time. Meanwhile, PUC releases new versions of Lua, and new projects pick those newer versions (and then sit on them forever).
It looks strange, and it has important downsides (a fragmented ecosystem, huge PITA when trying to write portable libraries, so fewer libraries in general, etc.), but it does seem to work in that Lua still exists and, project after project (not within a single project), it continues evolving.
NuclearPM 18 hours ago [-]
LuaJIT of course.
kibwen 19 hours ago [-]
Please don't, inscrutable bitwise operators are an accident of the past even in systems languages, let alone in a scripting language. I'm not against infix operators for bitwise operations, just please spell them out with keywords rather than giving them sigils.
Likewise, going from `and` and `or` to `&&` and `||` would be a dispiriting regression. This is something that Zig got right.
Dylan16807 16 hours ago [-]
What kind of person understands and needs bitwise operators but can't easily remember & | ~ and the arrows for shift? It's very little information.
The part I'd call a hassle is the different kinds of right shift but you have that same hassle if you use keywords.
I like using the and/or keywords for logical operations. Now let's make bitwise look significantly different from that.
Mond_ 15 hours ago [-]
It's not about having to remember them, it's that you shouldn't waste these short single symbols on operations that are only rarely used.
This stuff (especially the ternary) are a step backwards. There is just no reason to waste | on a bitwise or that gets used at 1% of the frequency of the standard or. In the future you might have a better use for it (pipeline syntax, sum or union types come to mind in other languages).
I dislike basically everything about these syntax extensions.
Dylan16807 7 hours ago [-]
Lua is very unlikely to want to add newer/less-common syntax with special symbols.
Also a syntax for types can repurpose most symbols without being ambiguous.
And you can overload the bitwise operators. You can configure __bor to give you pipelining right now.
I'm going to disagree only because one of the primary use cases for LuaJIT is interop with C and I think there's a case for making the ergonomics match.
JSR_FDED 19 hours ago [-]
What’s the Lua/LuaJIT story these days for bundling up all the scripts of an application into a single file? Is there a way to do the super convenient go-like thing?
zdragnar 18 hours ago [-]
There's a bunch of options from a Google search, but embedding it in a thin C program and building that with https://github.com/jart/cosmopolitan would be a pretty go-like experience, I'd think.
orthoxerox 14 hours ago [-]
There was a Lua[JIT] fork called Idle that seems to have fallen off the face of the Earth that did exactly that: it would take a small stub program, a runtime library and all the scripts and package them into a single PE/COFF binary that would read itself when run.
Love2D does it as well:
zip -9 -r SuperGame.love .
cat love.exe SuperGame.love > SuperGame.exe
This doesn't work with ELF files, though.
gucci-on-fleek 18 hours ago [-]
I personally use a hand-written C wrapper program (which is not much more than a dozen lines long), and then embed the Lua scripts using objdump. This isn't quite as easy as Go since cross-compiling C programs is often somewhat tricky, but Lua is very portable and has zero dependencies, so it's usually not too hard.
17 hours ago [-]
flumpcakes 16 hours ago [-]
Is LuaJIT still based on Lua5.1? I wonder why they haven't followed the language spec up to Lua5.5.
Because they don't like the changes, to put it mildly.
lt-runtime 6 hours ago [-]
The question is does the coding agent like it or not ?
yxhuvud 14 hours ago [-]
In aggregate this looks like a godsend, but there are some examples (like foo?.:method) that looks atrocious.
Ciantic 11 hours ago [-]
Yeah, "?." as safe navigation operator even in JS where it already exists is eye-sore. They could use some other single character instead of two characters. Question mark is already doing a lot with ternaries etc.
Instead of obj?.:method?.(…) it would be like obj#:method#(…)
Replace # with your favorite extra character instead of questionmark.
JBits 8 hours ago [-]
Is there any reason why they're not considering a single '?' like rust? Is it a parsing issue?
So you'd have: obj?:method(…)
orthoxerox 5 hours ago [-]
Mike Pall wrote in the issue that it's easier to parse. If they get rid of the ternary operator, I'll ask him again to drop the period.
nmz 2 hours ago [-]
a lone ? can mean anything, you can already tell that . is for fetching a subtable.
orthoxerox 2 hours ago [-]
In C# it's not a lone ?, it's two operators: ?. and ?[
Lua could have ?. ?[ ?" ?{ and ?(
sourcegrift 19 hours ago [-]
What are some pragmatic embedded scripting languages of choice these days if one has to consider:
1) Ease of learning, ideally minimal deviant behaviour (eg i consider lua tables to be a new concept in itself)
2) Reasonably fast. Not as much as lua jit but even half would be good enough
3) Mature
4) Has Rust bindings
NuclearPM 18 hours ago [-]
Lua. Lua tables are easy and awesome. My hobby language unites Lua tables with functions too.
kevinten10 12 hours ago [-]
[dead]
shevy-java 18 hours ago [-]
Lua has a lot of useless syntax. For instance, the "then". I have been using ruby and python for many years. Lua is living in the old age here.
That's just one example of so many more. I get that lua occupies a useful niche with its focus on embedded systems, but lua is not really a well-designed language in general. JavaScript has a similar problem.
xonre 15 hours ago [-]
For readability, `then` allows splitting with newlines very long conditional expressions, without having to wrap the condition in parentheses:
if x + y + z > a
or verylongconditionalhere ()
or anotherverylongconditionalhere ()
then
...
after `if` and `elseif` the parser simply goes on until it finds `then`.
nmz 4 hours ago [-]
This is something I don't see a lot of people do. I've tended to do
for long,list,of,variables,here
in ageneratorhere(bigparameterhere)
do
end
and
local x do
-- everything after is just here to define x
end
I'm still a little irked it works so well, the only alternative would be for the language to have labeled blocks. but that might be too terse
drunken_thor 6 hours ago [-]
Agreed, it keeps the parser fast as well because it is a lot more clear when the boolean statement ends and the code block begins. You either need parentheses, `then` or brackets around the block to make parsing clearly defined.
Dylan16807 16 hours ago [-]
Python spells "then" as ":"
In Ruby you can choose between "then" and a newline.
Other practical example why ternary is bad: Many code-coverage solutions break on ternary because they don't correctly see that one of the branches was missed in tests.
The ternary expression also takes up much less space so there is less of an emphasis on it, this can be a stylistic tool in a programmer's toolbox
Of course there are differences between LuaJIT and Luau that I think influence their decisions on possible ternary expression features:
- Luau users are disproportionately beginners to programming that I believe would find the if-then-else expression syntax easier to learn; LuaJIT developers have a larger user base of professional devs wanting to make their code faster, and they will probably be more familiar with the `x ? y : z` style since it's used in plenty of other languages.
- Luau is a lot faster moving in its development than LuaJIT in terms of language features, the Luau team just wanted to move people to ternaries from `x and y or z` because it's easier to optimise in a normal interpreter; LuaJIT, with their JIT, I assume would be able to more easily implement optimisations for constructs like `x and y or z` despite its slight semantic differences (my assumption on why the change is being considered now rather than earlier).
Does that operator compile to faster assembly that if I make the same logic with verbose `if` logic? Is that a language specific outcome?
The ? is basically an attempt to use fewer if/else, at the cost of condensed if-else like structure. I always need to look at both parts after the ? whereas in a single if or elsif I don't. case/when in ruby is even better here e. g. regex check:
(I ommitted the "end"s here to just focus on the conditional logic.)https://wiki.php.net/rfc/ternary_associativity
http://phpsadness.com/sad/30
A lot of these changes make sense (although some of them are a bit too TIMTOWTDI for my taste) - but perhaps LuaJIT 3 would benefit from a change of name as well? Certainly with all these changes, it would be more like a separate language than merely a JIT-compiled version of Lua.
What on earth is this supposed to mean?
That takes me back a bit. It's a perl-ism. I used to think it was a great design feature but I've come to strongly prefer "There should be one way to do it, and it should be obvious"
> Certainly with all these changes, it would be more like a separate language than merely a JIT-compiled version of Lua.
I agree. I suggested this on the GitHub issue but got nothing but downvotes.
https://www.lua.org/versions.html#5.3
https://www.lua.org/manual/5.3/manual.html#3.4.2
Looks like LuaJIT is catching up, but calling these "syntax extensions" is confusing. Is the intent to hold LuaJIT fixed against some earlier Lua version (I guess 5.1) and adopt newer syntax piecemeal?
I welcome the compound assignment operators. Playdate's version of Lua also has that extension.
Yeah. PUC-Rio went in a direction that Mike Pall didn't want to follow. Something to do with garbage collector finalizers, if I remember correctly, which is a notoriously thorny issue in every language it exists.
The removal of scanning for changed userdata finalizer meta method in 5.2 is just a commonsense fix for bad design that made GC atomic phase run time, thats not incremental scale up with the number of GC userdata objects alive no matter if they have a finalizer or not.
I am asking because i want to implement plugins in my media server, however i want to guard them in vm's i can control.
Why though? What does changing `and` to `&&` actually achieve? Were people confused?
Changing the syntax seems very surface level. It's not actually fixing any problems, just making Lua no longer look like Lua. It's not going to help anyone write/learn Lua. It will make everything more complicated as there are now two ways to do everything.
This feels like adding braces to Python because you don't like indenting your code.
Now this I can get behind...
In general, I would expect symbolic operators to be desirable in complex boolean expressions, because "loud punctuation" stands out among English words when reading the code.
What is a practical use case where the lower precedence makes sense?
1. statement if (condition || something)
2. (statement if condition) or something
Also consider AI, that has a greater training base of JavaScript than Lua. So making Lua look more like JS, should improve output and reduce mistakes.
My ultimate goal was to support LuaJIT in Rust as well but this does not make it easier.
For example, what’s the performance like?
In a mix of official and unofficial benchmarks wall clock performance is ~1.4x as fast as C Lua and the memory usage is ~1.7x.
So performance is worse to be clear but within range. There’s some performance improvements I haven’t gone for yet that would get it down to ~1.1 I think.
> My ultimate goal was to support LuaJIT in Rust as well but this does not make it easier.
I think you could stop right before the syntax extension.
If you have any Lua use cases let me know I’m looking for more real world use use cases to justify the effort here.
I think where it would be most helpful is converting a codebase and being able to easily run tests to ensure behavior is the same.
I created a github gist https://gist.github.com/ianm199/5ba0366376eca673142e1f0c79b4... that explains what is practical (I used AI for this to be clear feel free to skim).
Do you have a use case in mind? Would love to chat or take a look at an github issue if you create one.
Languages should probably protect themselves with trademarks or something.
Some of these really look like QoL improvements. I'm not convinced ternary statements are an ergonomic improvement in particular. The examples given don't make a compelling case, 'visually tidy' is not the same as readable.
There are real improvements though, such as ?. and ??= that help with default-nullable everything.
Ternary is very useful, but it I'd rather see it implemented idiomatically:
Structural pattern-matching could be fantastic, but no syntax is suggested.Now, the object systems do look similar, but that seems to be a case of convergent evolution: Javascript took direct inspiration from Self, whereas Lua's system is based on a more generic fallback mechanism for table access.
Zig and Rust have addressed the problem of how the result of a block expression should be presented, but neither solution seems particularly satisfying to me.
In Rust, blocks may end with an expression, giving them a non-void result. But a block may also end in a statement, the only difference being that the statement ends in a semicolon, in which case the expression still has the void result, and I think that semicolon being the only difference makes it hard to scan at a glance where values come from.
In Zig, blocks may give non-void results by `break`ing out of them with an expression. But break normally ignores blocks and break out of loops only, so to break out of blocks you have to provide a label for it and give that when you break so as to break out of the named block and not the outer loop, e.g. `const x = label: { break :label 35; }`. That creates a problem of one of the most difficult classes in software engineering: naming things. Ideally I think `break` from a block should have its own keyword, e.g. `const x = { give 35; }`
Right now, `if` in expression position is just a syntax error ("unexpected symbol")
But other than that, yeah, detecting "if" in the expression position is pretty unambiguous. No idea why most languages went with "cond-expr ? then-expr : else-expr" bracketed syntax instead.
But e.g. ml-family languages (like OCaml, F#, Haskell) and Rust just have the *if* expression that has a non-void value. If your language accepts expressions as statements (most do?), then I think that should just be compatible out of the box.
Oh, and Lua most famously does not accept expressions as statements. Which, now that I think of it, would actually evade most of the parsing complications.
> E.g. true and false or 42 returns 42, whereas true ? false : 42 returns the (expected) false.
select (select is a native C function, this is faster than the table creation below)
table creation/selection of course, doing something like does not look so badSo shouldn't it have a new name?
I'm proud of it and thankfull to the Lua/Luajit projects.
On the contrary, we can claim that luajit has stabilized lua for implementations and for users (strengthening Lua 5.1 dominance, which makes the experience more homogenous across apps).
Personally im a fan of introducing ternaranary operator in lua. Everyone uses `x and y or z` as a ternanary which i find way more confusing than ?:
Edit: meaning he can come back anytime.
I don't want to spam it in repo, so leaving it here: he is kind of a hero doing this work and I (hopefully we) am very grateful for his contribution to this world.
http://torch.ch/
https://github.com/torch/torch7
In effort to not pollute the github issue, and hopes that the authors read this thread, I will put some of my thoughts here. There are 3 main strengths of Lua: Embeddable, Fast, and Small(easy to learn). I worry some of these changes divert from the last, expanding the language into a more complicated language.
Here is a list of things already implemented in PUC Lua so can be considered safe to add:
Don't get me wrong, I love some of these quality of life changes like: These are great ideas for the language but I would want all lua versions to support them, not just JIT. These are things that I think are a distraction:The bracketed syntax is an okay idea especially for <close>, adding close as a keyword would be a disaster given how common the word is. If anything, local should have been tossed away as a keyword and the bracketed syntax adopted completely
5.5 introduced global which makes better use of attributes as well. of course, I don't deny how great it would be to not type <> or local const since const would already imply a local> string interpolation
Hisham already made this nice module https://github.com/hishamhm/f-strings Which I don't dare use, even if you don't have string interpolation. Of course, I don't care because I just have a table.format(tbl, "tbl.key is %{key}"), is it a little tedious? sure, but its just a gsub call.
> short form function syntax
I disagree with this, I've always wanted it and roll my eyes as I write/create a function, especially when you like to use lots of them like
> Named varargs: It may be nice, but there is no real reason to add this. If you wanted a name for your varargs you could do `local name = ...` or just use the `args` variable already available in every function.You've made a mistake there
is In order to actually do this you need to If you will use a vararg, you will always have to do this, so why not just let it be handled in the parameter definition? its costless. AND lua5.5 already introduced this so it seems they liked it.Quite frankly I would like the capability of treating ... as just an array like ...[1] but I haven't looked at the parser to see if its feasible or not.
> Switch/Match/Select Statements: An optimized if/else block works just as well and another expansion of a small language.
I don't disagree, but big table of functions is so ugly, switch statements would be nice
I agree. I posted this on the GitHub issues but got nothing but downvotes.
> In effort to not pollute the github issue
You should make yourself heard. It's a legitimate concern.
local gauge = count + (direction == "up" ? 10 : -10)
I imagine these changes make the original Lua adepts think their training wheels have come off. The language now looks like any other. That's a good thing to me, and it will help with the adoption of the JIT, but the whole language could have been syntax modernized as a result. But.. when the work is done someone else can fork it into something independent from its Lua roots.
From that perspective the conditional operator seems defensible, where it would be feature creep otherwise, as it is generally unloved elsewhere.
Also, I love this kind of pragmatism:
> Exponentiation assignment a ^= b has been deliberately omitted to avoid a predictable pitfall: this is how xor assignment is written in most other computer languages. Also, a syntax for exponentiation assignment is rarely asked for.
A ‘defer’ for closing files or deleting temp files at the end of a script will make life more enjoyable.
But which Lua?
Lua as implemented by LuaJIT is a fork of the language at this point. It's not fully compatible with PUC Lua (the reference implementation) and LuaJIT does not support features from the latest Lua version.
Lua is strange. Lua 5.2 was more of a "fork of the language" than LuaJIT, at the time. 5.3 and 5.4 (especially the latter) changed even more. Lua looks like a family of languages, and it seems to be by design. It probably makes sense in the "embedded scripting" space. Lua is not really meant to be (though it obviously is, if you want) a general-purpose language. It's meant for extending other apps, and scripting engines have different requirements than other language implementations: basically, hardcore backward compatibility. But it's impossible to evolve the language and innovate in its design if you commit to that. This is still an academic project, so hardcore backward compatibility is unlikely to be something the authors would value. Hence, the mixed model - every major version is a new "take" on the language. You're expected to pick a version when you first need a scripting engine, and then sit on that version until the end of time. Meanwhile, PUC releases new versions of Lua, and new projects pick those newer versions (and then sit on them forever).
It looks strange, and it has important downsides (a fragmented ecosystem, huge PITA when trying to write portable libraries, so fewer libraries in general, etc.), but it does seem to work in that Lua still exists and, project after project (not within a single project), it continues evolving.
Likewise, going from `and` and `or` to `&&` and `||` would be a dispiriting regression. This is something that Zig got right.
The part I'd call a hassle is the different kinds of right shift but you have that same hassle if you use keywords.
I like using the and/or keywords for logical operations. Now let's make bitwise look significantly different from that.
This stuff (especially the ternary) are a step backwards. There is just no reason to waste | on a bitwise or that gets used at 1% of the frequency of the standard or. In the future you might have a better use for it (pipeline syntax, sum or union types come to mind in other languages).
I dislike basically everything about these syntax extensions.
Also a syntax for types can repurpose most symbols without being ambiguous.
And you can overload the bitwise operators. You can configure __bor to give you pipelining right now.
[1] https://en.cppreference.com/cpp/language/operator_alternativ...
Love2D does it as well: zip -9 -r SuperGame.love . cat love.exe SuperGame.love > SuperGame.exe
This doesn't work with ELF files, though.
Instead of obj?.:method?.(…) it would be like obj#:method#(…)
Replace # with your favorite extra character instead of questionmark.
So you'd have: obj?:method(…)
Lua could have ?. ?[ ?" ?{ and ?(
1) Ease of learning, ideally minimal deviant behaviour (eg i consider lua tables to be a new concept in itself)
2) Reasonably fast. Not as much as lua jit but even half would be good enough
3) Mature
4) Has Rust bindings
That's just one example of so many more. I get that lua occupies a useful niche with its focus on embedded systems, but lua is not really a well-designed language in general. JavaScript has a similar problem.
In Ruby you can choose between "then" and a newline.
This is very pot calling the kettle black.