This may or may not already be common knowledge, but this surprised me when I discovered it. Lua's supposed "free-form" grammar actually requires the use of a semicolon delimiter in some places where the grammar would otherwise be ambiguous.

Here's the code that led me to discover this. I was reading the source code of g3d (a 3D engine for LÖVE) and I found this in the camera-handling code:


camera.viewMatrix:setViewMatrix(camera.position, camera.target, camera.down);
(shaderGiven or g3d.shader):send("viewMatrix", camera.viewMatrix)

Hold on, why is there a semicolon at the end of that first line? Maybe the author is just used to writing in other languages where semicolons are required, and accidentally let one slip through? Out of curiosity, I removed the semicolon and tried to run my project, and I got this error:


Error: Syntax error: g3d/camera.lua:99: ambiguous syntax (function call x new statement) near '('

Here's what's happening: the above code can be parsed one of two ways:


-- Option A (the intended way)
camera.viewMatrix:setViewMatrix(camera.position, camera.target, camera.down); -- end of function call
(shaderGiven or g3d.shader):send("viewMatrix", camera.viewMatrix)

-- Option B (the unintended way)
-- this tries to call the return value of the first line as if it were a function, with the paramter `shaderGiven or g3d.shader`
camera.viewMatrix:setViewMatrix(camera.position, camera.target, camera.down)(shaderGiven or g3d.shader):send("viewMatrix", camera.viewMatrix)

When LuaJIT encounters code like this, it errors, warning of ambiguous syntax (as shown above). However, the PUC Lua interpreter will happily go on and try to execute that bit of code, but in the unintended way, treating the second line as an extension of the first rather than as a new statement. This could be a gotcha if you weren't expecting this kind of behavior.