lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


A number of these tweaks are simple spelling and grammar fixes the rest
are various tweaks which make things flow better, read better, sound
better, or explain better (at least if you ask me). Feel free to ignore
any changes you don't like.

The first, fourth, tenth, thirteenth, fourteenth, eighteenth, and
nineteenth X hunks are typo and grammar fixes.

Second hunk, clarification of the pairs/ipairs sentences and explanation
of what '#t' means.

Third hunk, tries to explain that # is unreliable for sparse arrays
(without giving a potentially misleading length).

Fifth hunk, s/Nil/Sentinel/ I think 'Nil' is too likely to be confusing.

Sixth hunk, removes 'indeed' I think it reads better.

Seventh hunk, removes reference to 'self' as I think that's a bit too
magic for the moment (and hasn't been mentioned before).

Eighth hunk, adds 'only' to '... and are [only] local if ...'.

Ninth hunk, moves the emphasis to 'cannot' as opposed to 'find a key'.

Eleventh hunk, setting a field will not error if the field doesn't exist,
but will error if the table is not a table.

Twelfth hunk, clarifies why the env "contortions" are desired... the code
is potentially untrusted.

Fifteenth hunk, removes (an incorrect as far as I'm aware) reference to
porting history.

Sixteenth hunk, grammar fixes and removes an unnecessary comparison to
python.

Seventeenth hunk, replaces the old luaL_openlib with the current
luaL_register.

I hope my hunk counts are right. =)

    -Etan
--- FAQ.md.orig	2009-08-04 11:15:48.000000000 -0400
+++ FAQ.md	2009-08-05 16:57:32.510520200 -0400
@@ -16,9 +16,9 @@
 
 One scenario is that you already have big C/C++/Java/C# (etc) applications and wish to let your users script those applications. Lua will only add about 170K, which gets you a modern extension language which understands your special needs (like sandboxing) and can be easily integrated with your code.
 
-The other is that you have a lot of components which you use in your workflow and you are looking for a [glue language](http://en.wikipedia.org/wiki/Glue_language) to easily bind them together quickly without messy recompilation. (See [Ousterhout's Dichomomy](http://wiki.tcl.tk/9865).)
+The other is that you have a lot of components which you use in your workflow and you are looking for a [glue language](http://en.wikipedia.org/wiki/Glue_language) to easily bind them together quickly without messy recompilation. (See [Ousterhout's Dichotomy](http://wiki.tcl.tk/9865).)
 
-Another powerful use case which combines these two is embedding Lua as a _aid to debugging_.  It is possible to provide an intelligent debug console (even for GUI applications, such as Java/Swing) running Lua, which can let you operate _inside_ an application, querying state and running little test scripts.
+Another powerful use case which combines these two is embedding Lua as an _aid to debugging_.  It is possible to provide an intelligent debug console (even for GUI applications, such as Java/Swing) running Lua, which can let you operate _inside_ an application, querying state and running little test scripts.
 
 
 ### Any good editors and debuggers?
@@ -30,13 +30,13 @@
 
 ### What is the difference between pairs and ipairs?
 
-Lua tables are general data structures that have an 'array-like' and a 'map-like' part. The idea is that you can use them efficiently as resizeable arrays with integer indices, but can also index them with any other value as a hashmap.  `pairs(t)` gives a general iterator over all the keys and values in a table, numerical or not, and in no particular order; `ipairs(t)` goes over the array part, in order.
+Lua tables are general data structures that have an 'array-like' and a 'map-like' part. The idea is that you can use them efficiently as resizeable arrays with integer indices, but can also index them with any other value as a hashmap.  `pairs(t)` gives a general iterator over all the keys and values in a table, numerical or not, in no particular order; `ipairs(t)` iterates over the array part, in numerical order.
 
 Tables can contain a mixture of array and map entries:
 
     t = {fred='one',[0]=1; 10,20,30,40}
 
-The semi-colon is not required, it can be used as an alternative separator in table constructors. Just because `0` is a numerical index does not mean it is an _array index_! By definition, these go from `1` to `#t`.
+The semi-colon is not required, it can be used as an alternative separator in table constructors. Just because `0` is a numerical index does not mean it is an _array index_! By definition, these go from `1` to `#t` (the length of the table).
 
 These are equivalent ways to access the array elements:
 
@@ -48,12 +48,12 @@
 
     t = {[1] = 200, [2] = 300, [6] = 400, [13] = 500}
 
-In this case, `#t` is just `2`, since it counts the number of elements up to the first `nil` value (or 'hole'). If you wish to keep track of the size of a sparse array, then it is best to keep and increment a counter:
+In this case, `#t` is unreliable, since then length operator `#` is only defined for non-sparse arrays (arrays without holes). If you wish to keep track of the size of a sparse array, then it is best to keep and increment a counter:
 
     t[idx] = val;
     t.n = t.n + 1
 
-It is a little awkward to iterate _only_ over the non-array part of a table:
+It is a little awkward to iterate over _only_ the non-array (non-sparse) part of a table:
 
     local n = #t
     for k,v in pairs(t) do
@@ -94,7 +94,7 @@
 
 ### How can one put a nil value in an array?
 
-Putting `nil` directly into an array causes a 'hole', and `nil` is always indicates the end of an array. There are two ways to get around this. One approach is a sparse array with an explicit size; the iterator must return the index and the value:
+Putting `nil` directly into an array causes a 'hole', and `nil` always indicates the end of an array. There are two ways to get around this. One approach is a sparse array with an explicit size; the iterator must return the index and the value:
 
     local sa = {n=0}
 
@@ -119,7 +119,7 @@
 
     for i,v in sparse_iter(sa) do ... end
 
-The other approach is to store a special unique value `Nil` in place of an actual `nil`; `Nil = {}` will do.
+The other approach is to use a unique value `Sentinel` in place of an actual `nil`; `Sentinel = {}` will do.
 
 ### How can I dump out a table?
 
@@ -147,7 +147,7 @@
 
 ### Why does print 'hello' work, and not print 42?
 
-The confusion arises because some languages (like Python 2.x) have a print _statement_, whereas `print` is a _function_ in Lua (as it is indeed in Python 3).
+The confusion arises because some languages (like Python 2.x) have a print _statement_, whereas `print` is a _function_ in Lua (as it is in Python 3).
 
 However, there are two cases where you can leave out the parentheses when calling a Lua function: you may pass a single value of either string or table type. So `myfunc{a=1,b=2}` is also fine. This little bit of 'syntactic sugar' comes from Lua's heritage as a data description language.
 
@@ -155,7 +155,7 @@
 
 `a.f` simply means 'look up f in a'. If the result is 'callable' then you can call it.  A common pattern is to keep functions in tables, which is the approach taken by the standard libraries, e.g. `table.insert` etc.
 
-`a:f` actually has no meaning on its own. `a:f(x)` is short for `a.f(a,x)` - that is, look up the function in the context of the object `a`, and call it passing an implicit `self` parameter.
+`a:f` actually has no meaning on its own. `a:f(x)` is short for `a.f(a,x)` - that is, look up the function in the context of the object `a`, and call it passing the object `a` as the first parameter.
 
 Given an object `a`, it is a common error to call a method using `.`. The method is found, but the `self` parameter is not set, and the method crashes, complaining that the first parameter passed is not the object it was expecting.
 
@@ -164,7 +164,7 @@
 
 ### How are variables scoped?
 
-By default, variables are global, and are local if they are function arguments or explicitly declared as `local`. (This is of course opposite to the Python rule.)
+By default, variables are global, and are only local if they are function arguments or explicitly declared as `local`. (This is of course opposite to the Python rule.)
 
     G = 'hello'  -- global
 
@@ -288,7 +288,7 @@
 
 Note a restriction on overloading operators like ==: both arguments must be of the same type.  You cannot create your own `SuperNumber` class and get `sn == 0` to work, unfortunately. You would have to create an instance of `SuperNumber` called `Zero` and use that in your comparisons.
 
-You can control the meaning of `a[i]` but this is not strictly speaking _overloading the [] operator_. `__index` fires when Lua cannot _find a key_ inside a table. `__index` can be set to either a table or to a function; objects are often implemented by setting `__index` to be the metatable itself, and by putting the methods in the metatable.   Since `a.fun` is equivalent to `a['fun']`, there is _no way_ to distinguish between looking up using explicit indexing and using a dot.  A naive `Set` class would put some methods in the metatable and store the elements of the set as keys in the object itself. But if `Set` a method 'set', then `s['set']` would always be true, even though 'set' would not be a member of the set.
+You can control the meaning of `a[i]` but this is not strictly speaking _overloading the [] operator_. `__index` fires when Lua _cannot_ find a key inside a table. `__index` can be set to either a table or to a function; objects are often implemented by setting `__index` to be the metatable itself, and by putting the methods in the metatable.   Since `a.fun` is equivalent to `a['fun']`, there is _no way_ to distinguish between looking up using explicit indexing and using a dot.  A naive `Set` class would put some methods in the metatable and store the elements of the set as keys in the object itself. But if `Set` a method 'set', then `s['set']` would always be true, even though 'set' would not be a member of the set.
 
 The size operator and action when garbage-collected can be overriden by C extensions, not by plain Lua. But there is an undocumented function, `newproxy` which creates a little piece of 'userdata'. Here is a useful trick for writing a module finalization function:
 
@@ -389,7 +389,7 @@
     local x
     if a then x = b else x = c end
 
-### Why no continue statement?
+### Why is there no _continue_ statement?
 
 This is a common complaint. The reason that the Lua authors resist its inclusion is that it breaks the semantics for the `repeat..until` statement:
 
@@ -416,7 +416,7 @@
 Of course, we know that in large applications it is often better to let the error immediately break execution and then to catch it outside. This allows us to write code that is not so cluttered with conditional error checking. Lua does allow a function to be called in a protected environment using `pcall`. Wrapping up the code in an anonymous function gives us the equivalent to a `try/catch` construct:
 
     local status,err = pcall(function()
-      t.alpha = 2.0   -- will throw an error if t is nil or doesn't have a field alpha
+      t.alpha = 2.0   -- will throw an error if t is nil or not a table
     end)
     if not status then
       print(err)
@@ -565,7 +565,7 @@
 
 A new contender is [Squish](http://matthewwild.co.uk/projects/squish/home) which s a tool to pack many individual Lua scripts and their modules into a single Lua script, which can then be embedded using `srlua`.
 
-### How do I load and run Lua code?
+### How do I load and run (potentially untrusted) Lua code?
 
 The task is to execute some code that comes from a (possibly) untrusted source.
 
@@ -816,7 +816,7 @@
 
 Sometimes a [lexical scanner](http://penlight.luaforge.net/penlight.html#T21) gives a cleaner solution than pattern matching. This works particularly well if your 'complex structured text' is Lua or C code.
 
-### Mathematical libraries like complex numbers, higher-precision arithmetic, matrices, etc?
+### Are there mathematical libraries for complex numbers, higher-precision arithmetic, matrices, etc?
 
 There are several ways to bring complex arithmetic into Lua. [lcomplex](http://penlight.luaforge.net/packages/lcomplex.html) allows you to write code like this:
 
@@ -1213,7 +1213,7 @@
 
 Another approach is [LuaRocks](http://www.luarocks.org) which provides a cross-platform repository for downloading Lua packages. Like apt-get, it understands dependencies so that if you want LuaLogging it will also fetch LuaSocket; unlike apt-get, it works for Unix, OS X and Windows.
 
-Another option is [LuaDist](http://luadist.sourceforge.net) which is pretty much an 'executable crticism' of LuaRocks. This may appeal to you if you're a fan of CMake.
+Another option is [LuaDist](http://luadist.sourceforge.net) which is pretty much an 'executable criticism' of LuaRocks. This may appeal to you if you're a fan of CMake.
 
 ### What GUI toolkits are available?
 
@@ -1221,7 +1221,7 @@
 
 Probably the most full-featured and well-maintained binding is [wxLua](http://wxlua.sourceforge.net)
 
-An easy and lightweight alternative for more casual scripting is [IUP](http://www.tecgraf.puc-rio.br/iup/); both IUP and wxLua are part of[Lua for Windows](http://luaforwindows.luaforge.net) but they have been ported to all major platforms. A little tutorial is available [here](http://penlight.luaforge.net/iupx).
+An easy and lightweight alternative for more casual scripting is [IUP](http://www.tecgraf.puc-rio.br/iup/); both IUP and wxLua are available as part of [Lua for Windows](http://luaforwindows.luaforge.net) but are also available on their own. A little tutorial is available [here](http://penlight.luaforge.net/iupx).
 
 Here is a simple plotting program:
 
@@ -1278,16 +1278,16 @@
 
 [Lua-GD](http://lua-gd.luaforge.net) is a binding to the [gd](http://www.boutell.com/gd) library. GD is particularly useful for Web applications, since it creates output in common formats like PNG, JPEG or GIF.
 
-[luagraph](http://luagraph.luaforge.net) is a binding to the Graphviz library, which allows you to analyze visualize complex graphs - that is, in the sense of a set of connected nodes.
+[luagraph](http://luagraph.luaforge.net) is a binding to the Graphviz library, which allows you to visualize complex graphs - that is, in the sense of a set of connected nodes.
 
 This [simple interface](http://luaforge.net/projects/gnuplot) to gnuplot is useful if you are already somewhat familiar with this package and want to integrate it closer with your Lua code.
 
 
 ### How to interface to my C/C++ Libraries?
 
-It is straightforward to bind Lua to C code, compared to say Python. One reason is that Lua only has one complex data type, so once you have learnt to manage tables from the C side, you have mostly mastered the art of binding to Lua.
+It is straightforward to bind Lua to C code. One reason is that Lua only has one complex data type, so once you have learned to manage tables from the C side, you have mostly mastered the art of binding to Lua.
 
-Arguments are taken off a stack, and return results are pushed on the stack, and the C function must return the number of items pushed.
+Arguments are taken off the stack, return results are pushed on the stack, and the C function returns the number of items it intends to return to the caller.
 
     // build@ gcc -shared -I/home/sdonovan/lua/include -o mylib.so mylib.c
     // includes for your code
@@ -1333,7 +1333,7 @@
 
     LUALIB_API int luaopen_mylib(lua_State *L)
     {
-        luaL_openlib (L, "mylib", mylib, 0);
+        luaL_register (L, "mylib", mylib);
         return 1;
     }
 
@@ -1357,7 +1357,7 @@
 
 As a general rule, only go down to C if you have something that needs special optimization, or have an existing library that already does the job well.
 
-Using the raw API is mostly straightforward, but can be tedious. There are several tools that will semi-automatically do the hard work for you, and they understand C++ as well. [tolua++](http://www.codenix.com/~tolua/tolua++.html) is an attractive solution because it can parse  'cleaned' C/C++ headers and generate the bindings.
+Using the raw API is mostly straightforward, but can be tedious. There are several tools that will semi-automatically do the hard work for you, and they understand C++ as well. [tolua++](http://www.codenix.com/~tolua/tolua++.html) is an attractive solution because it can parse 'cleaned' C/C++ headers and generate the bindings.
 
 A very simple example: say we have a burning need for the C function `strstr`; given this file `lib.pkg`:
 
@@ -1365,7 +1365,7 @@
 
 then `tolua -o lib.c lib.pkg` will generate a binding file `lib.c` which can be compiled and linked against the `tolua` library.
 
-`require 'lib'` may result in a suprise, since there is no table `lib` generated, only a global function `strstr`. To put the function into a tble `lib`, `lib.pkg` must look like this:
+`require 'lib'` may result in a suprise, since there is no table `lib` generated, only a global function `strstr`. To put the function into a table `lib`, `lib.pkg` must look like this:
 
     module lib
     {