When I was playing around with semi-colons( ; )
and commas( , )
I noticed when in variables
the second one(first variable
has a comma now) had an error( red underline ) local
, For Instance.
local a="string a", local b="string b" -- in studio it has a red underline
contrary to.
local a="string a"; local b="string b" -- in studio it has no red underline
The comma has two uses: separating arguments and parameters in a function call or definition, respectively; and separating elements in a Table.
The semicolon has two uses as well: separating elements in a Table, and 'ending' a line of code.
Both can be used interchangeably in Tables:
t = { member1 = true; alpha = "afS", super = script.Parent; t = {1, 2, 4; 26, 15, 124;} }
In a Table formatted like that, I almost exclusively use semicolons, with the exception of nested Tables such as t.t
in that example. The semicolon at the end of line 5 (inside t.t
) is not invalid. Lua's Tables can be thought as being marked by 'line ends' rather than having distinct, separate elements.
The inclusion of both there is purely for programmer-readability, and the use should be similar to how why I used the semicolon in the first sentence of this answer.
The other use of commas is obvious, but the other use of semicolons can seem weird to someone that started Scripting with Lua.
function funcName(params); print("doingStuff"); end;
The semicolon here is used to 'end' each line of code. It is important, because to the Lua interpreter, that code actually looks like this:
function funName(params); print("doingStuff"); end;
As anyone could tell you, that is technically also valid Lua, it's just difficult to read when the code gets more complex.
Used like this, the semicolon is purely used aesthetically (and maybe as practice for writing code in a language such as Java or C/C++), but there is a case where it is necessary to include it:
Functions in Lua are first-class values. Basically, this means that they are variables that can be passed around. Like Tables, function variables (i.e. the 'name' of the function) are pointers, pointing to the static code of the function itself.
A consequence of this is that you can return
a function! This is what loadstring()
does.
function gimmeAFunc() return function() print("doingStuff!!") end end print(gimmeAFunc()) -- Function: XXXXXXXX --[[This should change every time this code is run.]] print(gimmeAFunc()()) --[[ doingStuff!! --the print inside the function returned by gimmeAFunc nil --the second top-level print statement ]]
That double ()
on the last line there is the catch.
Take a look at this code:
(function() print("Anonymous function usage!")() (function() print("Anonymous function usage AGAIN!"))()
This is valid Lua code. By wrapping the entire anonymous function in parentheses, we are able to access the entire function as a 'whole', allowing us to actually call it, without needing a direct reference to it.
However, this gives us an error: "ambiguous syntax". Why?
Well, remember that Lua actually sees THIS:
(function() print("Anonymous function usage!")()--[[]](function() print("Anonymous function usage AGAIN!"))()
This prompts the interpreter to try and call (as a function) the return of the first anonymous function, passing in the second anonymous function as an argument, and then calling the return of that!
However, because there was a newline character where I marked with a comment, Lua could interpret this code either of two ways: two anonymous functions or a chain of function calls. Rather than make a (potentially dangerous) mistake, Lua throws an error. To fix this, we add a semicolon to end the first line:
(function() print("Anonymous function usage!"))(); (function() print("Anonymous function usage AGAIN!"))()
And there is no error!
You can also trigger this error by doing something stupid like this:
function f() end f ()
Lines 3 and 4 there are "ambiguous syntax".