subtle differences between JavaScript and Lua

JavascriptLua

Javascript Problem Overview


I simply love JavaScript. It's so elegant.

So, recently I have played with Lua via the löve2d framework (nice!) - and I think Lua is also great. They way I see it, those two languages are very similar.

There are obvious differences, like

  • syntax
  • problem domain
  • libraries
  • types (a bit)

but which are the more subtle ones? Is there anything a JavaScript coder would take for granted that works in Lua just slightly different? Are there any pitfalls that may not be obvious to the experienced coder of one language trying the other one?

For example: in Lua, arrays and hashes are not separate (there are only tables) - in JavaScript, they are numerical Arrays and hashed Objects. Well, this is one of the more obvious differences.

But are there differences in variable scope, immutability or something like this?

Javascript Solutions


Solution 1 - Javascript

Some more differences:

  • Lua has native support for coroutines.
  • UPDATE: JS now contains the yield keyword inside generators, giving it support for coroutines.
  • Lua doesn't convert between types for any comparison operators. In JS, only === and !== don't type juggle.
  • Lua has an exponentiation operator (^); JS doesn't. JS uses different operators, including the ternary conditional operator (?: vs and/or), and, as of 5.3, bitwise operators (&, |, etc. vs. metamethods ).
  • UPDATE: JS now has the exponentiation operator **.
  • JS has increment/decrement, type operators (typeof and instanceof), additional assignment operators and additional comparison operators.
  • In JS, the ==, ===, != and !== operators are of lower precedence than >, >=, <, <=. In Lua, all comparison operators are the same precedence.
  • Lua supports tail calls.
  • UPDATE: JS now supports tail calls.
  • Lua supports assignment to a list of variables. While it isn't yet standard in Javascript, Mozilla's JS engine (and Opera's, to an extent) has supported a similar feature since JS 1.7 (available as part of Firefox 2) under the name "destructuring assignment". Destructuring in JS is more general, as it can be used in contexts other than assignment, such as function definitions & calls and loop initializers. Destructuring assignment has been a proposed addition to ECMAScript (the language standard behind Javascript) for awhile.
  • UPDATE: Destructuring (and destructuring assignment) is now part of the spec for ECMAScript - already implemented in many engines.
  • In Lua, you can overload operators.
  • In Lua, you can manipulate environments with getfenv and setfenv in Lua 5.1 or _ENV in Lua 5.2 and 5.3.
  • In JS, all functions are variadic. In Lua, functions must be explicitly declared as variadic.
  • Foreach in JS loops over object properties. Foreach in Lua (which use the keyword for) loops over iterators and is more general.
  • UPDATE: JS has Iterables now too, many of which are built into the regular data structures you'd expect, such as Array. These can be looped over with the for...of syntax. For regular Objects, one can implement their own iterator functions. This brings it much closer to Lua.
  • JS has global and function scope. Lua has global and block scope. Control structures (e.g. if, for, while) introduce new blocks.
    • Due to differences in scoping rules, a closure's referencing of an outer variable (called "upvalues" in Lua parlance) may be handled differently in Lua and in Javascript. This is most commonly experienced with closures in for loops, and catches some people by surprise. In Javascript, the body of a for loop doesn't introduce a new scope, so any functions declared in the loop body all reference the same outer variables. In Lua, each iteration of the for loop creates new local variables for each loop variable.

       local i='foo'
       for i=1,10 do
         -- "i" here is not the local "i" declared above
         ...
       end
       print(i) -- prints 'foo'
      

      The above code is equivalent to:

       local i='foo'
       do
         local _i=1
         while _i<10 do
           local i=_i
           ...
           _i=_i+1
         end
       end
       print(i)
      

      As a consequence, functions defined in separate iterations have different upvalues for each referenced loop variable. See also Nicolas Bola's answers to Implementation of closures in Lua? and "What are the correct semantics of a closure over a loop variable?", and "The Semantics of the Generic for".

      UPDATE: JS has block scope now. Variables defined with let or const respect block scope.

  • Integer literals in JS can be in octal.
  • JS has explicit Unicode support, and internally strings are encoded in UTF-16 (so they are sequences of pairs of bytes). Various built-in JavaScript functions use Unicode data, such as "pâté".toUpperCase() ("PÂTÉ"). Lua 5.3 and up have Unicode code point escape sequences in string literals (with the same syntax as JavaScript code point escape sequences) as well as the built-in utf8 library, which provides basic support for the UTF-8 encoding (such as encoding code points into UTF-8 and decoding UTF-8 into code points, getting the number of code points in a string, and iterating over code points). Strings in Lua are sequences of individual bytes and can contain text in any encoding or arbitrary binary data. Lua does not have any built-in functions that use Unicode data; the behavior of string.upper depends on the C locale.
  • In Lua, the not, or, and keywords are used in place of JS's !, ||, &&.
  • Lua uses ~= for "not equal", whereas JS uses !==. For example, if foo ~= 20 then ... end.
  • Lua 5.3 and up use ~ for binary bitwise XOR, whereas JS uses ^.
  • In Lua, any type of value (except nil and NaN) can be used to index a table. In JavaScript, all non-string types (except Symbol) are converted to strings before being used to index an object. For example, after evaluation of the following code, the value of obj[1] will be "string one" in JavaScript, but "number one" in Lua: obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • In JS, assignments are treated as expressions, but in Lua they are not. Thus, JS allows assignments in conditions of if, while, and do while statements, but Lua does not in if, while, and repeat until statements. For example, if (x = 'a') {} is valid JS, but if x = 'a' do end is invalid Lua.
  • Lua has syntactic sugar for declaring block-scoped function variables, functions that are fields, and methods (local function() end, function t.fieldname() end, function t:methodname() end). JS declares these with an equals sign (let funcname = function optionalFuncname() {}, objectname.fieldname = function () {}).

Solution 2 - Javascript

A couple of subtle differences that will catch you out at least once:

  • Not equal is spelled ~= in Lua. In JS it is !=
  • Lua arrays are 1-based - their first index is 1 rather than 0.
  • Lua requires a colon rather than a period to call object methods. You write a:foo() instead of a.foo()

you can use a period if you want, but have to pass the self variable explicitly. a.foo(a) looks a bit cumbersome. See Programming in Lua for details.

Solution 3 - Javascript

To be honest it would be easier to list the things which are common to Javascript and Lua than to list the differences. They are both dynamically-typed scripting languages, but that's about as far as you can go really. They have totally different syntax, different original design goals, different modes of operation (Lua is always compiled to bytecode and run on the Lua VM, Javascript varies), the list goes on and on.

Solution 4 - Javascript

JavaScript arrays and objects are closer than you might think. You can use array notation to get at the elements of either of them, and you can add non-numeric indices to arrays. Individual array elements can hold anything, and the array can be sparse. They are nearly identical cousins.

Solution 5 - Javascript

I liked this question and the answers provided. Additional reasons the two languages seem more alike than not to me:

Both assign functions to variables, can build functions on the fly, and define closures.

Solution 6 - Javascript

Off the top of my head

Lua ...

  1. supports coroutines
  2. has no restriction to just string/number as key for a table. Everything works.
  3. the error handling is somewhat clumsy. Either you don't handle anything or use the pcall method
  4. I think I read something about differences in the lexical scope and that Lua has the better one.
  5. If I recall correctly regular expression support in lua is limited

Solution 7 - Javascript

Lua and JavaScript are both prototype base languages.

Solution 8 - Javascript

A test reveals that current Javascript also returns objects, or at least strings from logic expressions like lua does:

function nix(){
    alert(arguments[0]||"0");
} 
nix();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionstefsView Question on Stackoverflow
Solution 1 - JavascriptoutisView Answer on Stackoverflow
Solution 2 - JavascriptrichqView Answer on Stackoverflow
Solution 3 - JavascriptDaveRView Answer on Stackoverflow
Solution 4 - JavascriptNosrednaView Answer on Stackoverflow
Solution 5 - JavascriptWeakPointerView Answer on Stackoverflow
Solution 6 - JavascriptjitterView Answer on Stackoverflow
Solution 7 - JavascriptAnonymousView Answer on Stackoverflow
Solution 8 - JavascriptAdderView Answer on Stackoverflow