I referenced that Wiki item in my first reply. :)
Quote:
... an otherwise good language (scripting or otherwise) is missing *basic* functions ...
Well, C doesn't fully support it either, and I hope you aren't going to say C drives you batty. Take an example from the SMAUG source:
SPELL_FUN *spell_function( char *name )
{
if( !str_cmp( name, "spell_smaug" ) )
return spell_smaug;
if( !str_cmp( name, "spell_acid_blast" ) )
return spell_acid_blast;
if( !str_cmp( name, "spell_animate_dead" ) )
return spell_animate_dead;
if( !str_cmp( name, "spell_astral_walk" ) )
return spell_astral_walk;
... and so on ...
What is this doing? It is converting a name to a function, and it is doing it like this because the C switch statement doesn't handle strings, only numeric constants. There are 189 lines in this function (and it isn't the only one with this general design). Imagine how slow it is if the spell name you want is at the end of the list - or, not there at all.
In Lua you could have a simple table:
spellnames = {
spell_smaug = spell_smaug,
spell_acid_blast = spell_acid_blast,
spell_animate_dead = spell_animate_dead,
spell_astral_walk = spell_astral_walk,
-- and so on
}
This is Lua shorthand for keying a string literal to a value, in this case we assume a function. It is the same as:
spellnames = {
["spell_smaug"] = spell_smaug,
["spell_acid_blast"] = spell_acid_blast,
["spell_animate_dead"] = spell_animate_dead,
["spell_astral_walk"] = spell_astral_walk,
-- and so on
}
Now in Lua, you can do a direct table lookup, which is faster and neater. Plus, you can simply generate the "reverse" table in a couple of lines of code:
rev_spellnames = {}
for k, v in pairs (spellnames) do
rev_spellnames [v] = k
end
This generates, from the first table, a table which keys the function addresses to their names, so you can convert them back the other way.
You can't do that with a switch statement, which means that the C code (eg. SMAUG) tends to be a lot more cluttered, and stuff like adding new functions means you have to add them to a switch statement, *and* add them to the "reverse" function (a lengthy if statement) as well.
Effectively the table-driven approach forces you to think about what you are really trying to achieve and make a cleaner design. |