Why SGScript?

Native serialization

[+] SGScript, Python
[-] JavaScript, Lua, Squirrel

Without any extra work, most of the data can be converted to a byte buffer so that it could be stored in a file or sent over a network and later converted back again. Languages that don't have it will require extra effort to get it and make sure it works with all kinds of custom objects. How much extra effort? Well, try googling for "lua serialize userdata". I didn't find a single way. SGScript - easy: https://github.com/snake5/sgscript/blob/6e9349a5a1ef5210ee440301b889f9afd78291be/ext/sgsxgmath.c#L248

Reference counted memory management support

[+] SGScript, Python, Squirrel
[-] JavaScript, Lua

This is a preferred method to garbage collection since it releases resources as soon as possible, avoiding random stalls throughout the game and thus providing a smooth gameplay experience. There are algorithms that reduce these stalls (incremental/generational garbage collection) but, given enough objects, they will be noticeable again. Source: http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/

Custom native objects with complex links

[+] SGScript, Python, JavaScript (partial support)
[-] Lua, Squirrel

These are objects that can be created in C/C++, with special interfaces that support operator overloading, serialization, debug printing, conversions, cloning, type name and iterator retrieval, index and property retrieval. If not used, this feature has no cost, however it helps greatly with defining fast and accessible interfaces by encapsulating native resource management and access. To see what SGScript objects are all about, check the previous GitHub link, there's quite a lot of them.

Native arrays

[+] SGScript, Python, Squirrel, JavaScript (partial support)
[-] Lua

Native arrays (not to be confused with arrays that contain native data types, that is a subset of these) offer increased performance and memory-friendly storage over arrays made from hash tables. Array stores size as uint32, capacity as uint32 and values (16 bytes + extended data in SGScript) x size. A table would store all the same + keys (16 bytes + extended data) + hash array (size may differ but it's generally another array with size, capacity and a list of hash and index values). When arrays are considered, less (memory usage) is more (capacity).

Map support (all non-string/number keys)

[+] SGScript, Python, JavaScript (requires the support of an extension)
[-] Lua, Squirrel (some types are not supported in both)

The ability to map any variable to any other variable provides extended metadata storage possibilities - it can be stored without modifying the original variable.

m = map();
m[ sprite_obj ] = { high = 5 };

Game math library

[+] SGScript, Python, Lua, JavaScript
[-] Squirrel

A library with vector/matrix objects and functions for games. Not having to rewrite at least the bindings for it saves a lot of time.

Native debugging/profiling facilities

[+] SGScript, Python, JavaScript (support differs between JS engines)
[-] Lua, Squirrel

Introspective debugging and time/memory usage profiling can help resolve various issues found. SGScript supports call stack time, instruction time and call stack memory usage profilers out-of-the-box. At any point, all data can be dumped via the built-in output facilities that can be rerouted to any file or parser.

They are written in C to ensure a practically minimal performance impact while profiling. Significantly less than if the profiler was written in Lua, which is the main solution there. There's also access to some stats in SGScript so it is easy to see, for example, how many new allocations were done each frame.

Advanced native function argument parsing facilities.

[+] SGScript, Python
[-] Lua, Squirrel, JavaScript

Every modern scripting engine should have a function that parses and validates function arguments according to a specification and puts the data in the specified locations. With bigger functions it saves you from writing a lot of boilerplate code.

SGScript:
SGSFN( "fmt_string_parser" );
if( !sgs_LoadArgs( C, "?m|ii", &off, &bufsize ) ) // in case of type mismatch, emits a warning
    return 0; // ... and returns here to continue execution
Lua: (source: http://forums.tigsource.com/index.php?topic=36737.0)
float x  =luaL_checknumber(L,1); // in case of type mismatch, emits a fatal error, cannot continue script execution after this function call
float y  =luaL_checknumber(L,2); // same here
const char* str=luaL_checkstring(L,3); // same here

Non-fatal error messaging facilities without exceptions

[+] SGScript
[-] Python, Lua, Squirrel, JavaScript

This feature allows you to try and continue execution after a failed function call or intercept the error for debugging with the option of continuing later anyway. This is useful when code is published and there's a necessity to avoid going back to bug fixing immediately, before gathering more information about the state of the program.

Why exceptions don't fit the criteria: they force the code to break out of the original execution path, thus severely reducing the usefulness of error suppression with logging.

name = string_cut( other.name ); // warning: missing argument 2; after call, name = null
// name gets printed somewhere as 'null' or is invisible due to some other function not accepting null for a string
// everything else works

Built-in introspective pretty-printing (variable dumps)

[+] SGScript, Python, JavaScript
[-] Lua, Squirrel

This is a very useful feature to have when you need to debug data (i.e. always). Simply passing a variable to some function (for example, printvar) prints some useful information about it - the type, contents, linked resources.

Warning suppression on missing property access

[+] SGScript, Python (requires exception handling code)
[-] Lua, Squirrel, JavaScript (no warnings about it at all)

This feature allows to specify, per-read, whether the property is expected to be there or not.

a = obj.prop; // expected, emits a warning if not found
b = @obj.prop; // might not be there, no error

This also works for many other actions, like function calls and assignments.

Custom native iterators

[+] SGScript, Python
[-] JavaScript, Lua, Squirrel

An extension for custom native objects, it allows to create objects that can be foreach'ed through.

foreach( entry : io_dir( "." ) ) println( entry ); // prints the contents of current directory

Dual access dictionaries

[+] SGScript, Lua, JavaScript, Squirrel
[-] Python

The ability to access simple dictionaries just like any other object visually and syntactically reduces code complexity.

a.b = x; // simple
a["b"] = x; // not so simple

Explicit closures

[+] SGScript
[-] Lua, JavaScript, Squirrel, Python

Explicit closures (specifying which local variables to pass over to the newly defined function) make it easier to read code using closures and prevents closure-related accidents, like having a variable changed unexpectedly.

Multi-index/property-set operation without temporary tables

[+] SGScript
[-] Lua, JavaScript, Squirrel, Python

Simplifying code further without the introduction of sub-optimal memory access patterns. SGScript:

obj.{ // object name written only once, accessed only once
    a = 1, // property write
    b = 2, // property write
    c = 3, // property write
    d = 4, // property write
};

Lua, method 1:

obj.a = 1 // property write
obj.b = 2 // property write
obj.c = 3 // property write
obj.d = 4 // property write
// object name written four times, accessed possibly four times (depending on compiler)

Lua, method 2:

for k, v in pairs({ a = 1, b = 2, c = 3, d = 4 }) do // create table, property write x4, function call, create closure
    obj[ k ] = v // object access x4, property write x4
end

C-like syntax

[+] SGScript, JavaScript, Squirrel
[-] Lua, Python

With the overwhelming majority of code being written in C-like languages (http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html), having a compatible syntax helps when you need to copy code - there's simply less changes to perform.

Indices start at 0

[+] SGScript, JavaScript, Squirrel, Python
[-] Lua

Even though it is argued that it may help someone understand code better (which is actually hard to prove), I have a few arguments to make against it: