David Manura |
|
|
* [lua-file_slurp / file_slurp] - Easily read/write entire files or pipes from/to a string * [lua-requireany / requireany] - require any one of the listed modules * [lua-globtopattern / globtopattern] - Convert file glob to Lua string pattern - FileGlob * [lua-findbin / findbin] - Locate directory of original perl script * [lua-lib / lib] - Simple insertion of directories in package search paths * [lua-compat_env] - Lua 5.1/5.2 environment compatibility functions (load/loadfile/getfenv/setfenv) |
|
* [lua-file-slurp / file_slurp] - Easily read/write entire files or pipes from/to a string * [lua-require-any / requireany] - require any one of the listed modules * [lua-glob-pattern / globtopattern] - Convert file glob to Lua string pattern - FileGlob * [lua-find-bin / findbin] - Locate directory of original perl script * [lua-lib / lib] - Simple insertion of directories in package search paths * [lua-compat-env / compat_env] - Lua 5.1/5.2 environment compatibility functions (load/loadfile/getfenv/setfenv) |
|
* [makebuild.lua] - rudimentary Lua makefile generator in < 100 lines of code. LuaBuildSystems |
|
* HammingWeight - test of hamming weight implementations |
|
* LuaFiveTwo/LuaFiveThree === Lua 5.3 Wishlist === Here are few things bug me, though I'm not necessarily sure what to do about all of them. * Tracebacks might use some reform. * Refactoring f(...) to local ok, err = pcall(f, ...); if not ok then error(err) end or assert(pcall(f, ...)) has side-effects in traceback behavior. LuaList:2012-02/msg00858.html* other older more general comments: LuaList:2010-08/msg00481.html * Why truncate paths in tracebacks? LuaList:2006-03/msg00101.html * The level parameter used in the error function lacks maintainability since a function might be called from different levels and those levels might be refactored. Refactoring f() to (function() return f() end)() has side-effects in terms of level behavior, with no option to suppress the change in stack level. LuaCarp was a very early effort to improve this. Also see [3][4]. At least in 5.2 work, getfenv/setfenv are mostly removed and setfenv behavior in module is deprecated, so it's moving in the right direction.* The assert function is arguably misnamed: [5]. Also, the fail expression is always evaluated.* I have qualms about metamethods. Despite their uses, they make semantics more complicated. * Proliferation of raw v.s. nonraw functions and semantics. Also, where's "rawtostring"? [LuaFiveTwo]. * I don't get why the change was made in 5.2 table.* functions to partly honor metamethods. [6][7][8] * __index (unlike the proposed __getindex) doesn't fully intercept table accesses (hence proxy tables). * There were proposals to allow 'a:b()' not to depend on 'a.b' (e.g. __mcall or __mindex metamethod) [9] * NamedParameters as tables seem heavy. What effect does it have on LuaJit optimizations? Converting a function from non-named to named parameters is a fundamental change to its interface, not to be taken lightly. * Questions remain about versioning. ModuleVersioning/LuaVersionCompatibility. 5.2 is a breaking change and not fully supported in LuaJit. Other languages like Perl 6 have statements like "use v6;" to indicate the code is Perl6 rather than Perl 5. _ENV = require '_G53'?* Lua syntax is not always necessarily ideal as a DSL. Consider representing something like PHP, where control structures are embedded inside tree nodes, but StatementsInExpressions are not seamless in Lua. Lua commas can also clutter [10]. Compare to Lisp s-expressions or Ocaml. * Cleanup on scope exit (ResourceAcquisitionIsInitialization). The prototypical example involves file handles, like in file_slurp readfile [1]. One of the simpler solutions is a Google Go "defer" or D language "scope(exit). * local ok, err = f(); if not ok then return ok, err end is a common idiom. Should it be made shorter?* StringInterpolation for local variables has no really nice solution. Some type of compile-time preprocessing step that expands things like printf "${x},${y},${x}" into printf("${x},${y},${x}", x, y, x) that is then evaluated at runtime might be a good compromise.* Forwardly declared local functions look instead like global definitions. Commenting or semantic editors may help some though:
* package.path and package.cpath are strings rather than arrays. LuaList:2010-06/msg00214.html . This led to the "lib" module [2].* Debugging info lacks character positions (only has line numbers): LuaList:2010-08/msg00273.html * luac with multiple files could be generalized: LuaList:2010-11/msg00898.html * Lack of comments in the Lua source [11] (LuaSource) can make it more difficult to penetrate than otherwise. See LuaAnnotate though. * for _,v in ipairs(t) do is ugly, and it's less efficient than for i=1,#t do local v=t[i] do. The too forms do noth have the same behavior either in terms of __len. |
|
Caveat: The below list may not be entirely updated to reflect the final 5.2.0 release and may need cleaned up more. |
|
* Module system reforms - Make the module system more consistent - see LuaModuleFunctionCritiqued. 5.2 now deprecates the module function and its ilk. * Environment reforms - I support the _ENV proposal because of the simplifications it makes to lexical analysis (LuaInspect, LuaFish/luaanalyze) and compilation (LuaToCee). I think this is related to a more general problem though involving stack levels (see level parameter below). I agree though that _ENV is ugly and probably should not be used by most user code. |
|
* Module system reforms - Make the module system more consistent - see LuaModuleFunctionCritiqued. 5.2 now deprecates the module function and its ilk. Some wanted to improve rather than dispose of the module functions, but there was not consensus on precisely what that would be. * Environment reforms - I support the _ENV proposal because of the simplifications it makes to lexical analysis (LuaInspect, LuaFish/luaanalyze) and compilation (LuaToCee). I think this is related to a more general problem though involving stack levels (see traceback points above). I agree though that _ENV is ugly and probably should not be used by most user code. |
* BitwiseOperators standard library. 5.2 implements this now. I had thought the Lua community had already converged on Lua BitOp (supported by LuaJIT and superseding lbitlib). See BitwiseOperators/[1] Both the 5.2 and LuaJIT bit libraries are probably fine for most purposes, and you could likely write code that is compatible with both: `local band = bit.band or bit32.band` provided you avoid incompatible cases. Should get/set bitfield operations be added? [2] |
* BitwiseOperators standard library. 5.2 implements this now. I had thought the Lua community had already converged on Lua BitOp (supported by LuaJIT and superseding lbitlib). See BitwiseOperators/[1] Both the 5.2 and LuaJIT bit libraries are probably fine for most purposes, and it can be possible to write code that is compatible with both: `local band = bit.band or bit32.band` provided you avoid incompatible cases. Should get/set bitfield operations be added? [2] |
|
* Some ask for ContinueProposal. I tend to find breaking out of nested loops more common. Here's my proposal that generalizes nested break+continue into a single construct: LuaList:2010-11/msg00556.html . See also GotoStatement |
|
* Some ask for ContinueProposal. I tend to find breaking out of nested loops more common. Here's my proposal that generalizes nested break+continue into a single construct: LuaList:2010-11/msg00556.html . See also GotoStatement. |
|
* "package.loaders" misnomer [1][2] (package.loaders contains searchers not loaders). |
|
Here's other ideas (not currently addressed in 5.2 work releases): * Why truncate paths in tracebacks? LuaList:2006-03/msg00101.html * Small source code changes to reduce patching complexity? LuaList:2010-11/msg00899.html |
|
* `luac -l -l` is currently undocumented (done in 5.2.0) |
|
* Overcome implementation limits in number of locals [1] and concatenation AssociativityOfConcatenation is not done, but LuaFiveTwo is increasing "Maximum number of constants per chunk increased to 2^26 from 2^18" though. |
|
* Reference manual formatting suggestions: LuaList:2010-10/msg00350.html * luac with multiple files could be generalized: LuaList:2010-11/msg00898.html * `luac -l -l` is currently undocumented. * Cleanup on scope exit (ResourceAcquisitionIsInitialization) This is a biggie. JohnBelmonte has strongly advocated it, and various people have provided patches with various implementations (above link). There's ways to do it in 5.1 with wrapper functions utilizing pcall's and anonymous functions everywhere, but it's not very nice. Proper error handling in the presence of resource allocation in Lua can be clumsy without this. One of the simpler solutions is a "defer" statement like in the Google Go language (or D language "scope(exit)"). Compare:
* Traceback/error handling redesign: LuaList:2010-08/msg00481.html * The level parameter used in the error function lacks maintainability since a function might be called from different levels and those levels might be refactored. See LuaCarp for an old effort to improve this. Also see [1][2]. At least in 5.2 work, getfenv/setfenv are mostly removed and setfenv behavior in module is deprecated, so it's moving in the right direction.
|
|
Here's other older ideas not addressed in 5.2 and which I haven't decided to move them up to the 5.3 wishlist: |
|
* Include character positions (not line numbers) in debugging info: LuaList:2010-08/msg00273.html * StringInterpolation - There's no really good way interpolate local variables into strings. Some type of preprocessing step that expands things like printf "${x},${y},${x}" into printf("${x},${y},${x}", x, y, x) is perhaps the ideal technical solution. |
|
* Add efficient tests for existence of operators on objects [1][2] * File handle virtualization - Sometimes you can pass a custom table that looks like a file handle to functions that expect a file handle, but this doesn't work all the time (e.g. if the function tests with io.type). * Maybe add versions of lua_pushstring and lua_newuserdata that don't longjump. May be useful for mixing C++ exception code and C API longjump code. * Small source code changes to reduce patching complexity? LuaList:2010-11/msg00899.html * Reference manual formatting suggestions: LuaList:2010-10/msg00350.html |
|
|
|
|
|
* Maybe add versions of lua_pushstring and lua_newuserdata that don't longjump. May be useful for mixing C++ exception code and C API longjump code. |
|
|
|
* Add efficient tests for existence of operators on objects [1][2] * On DetectingUndefinedVariables, my current opinion is that it is best handled by the text editor. I find runtime analysis (strict.lua) interior to static bytecode analysis (globals.lua) interior to static source analysis (LuaInspect). Furthermore globals.lua and the (hybrid) checkglobals don't work as well in 5.2 due to _ENV changes. * Add more comments to the source [3] (LuaSource). The Lua code is small but can be difficult to penetrate. See LuaAnnotate though. * The assert function is somewhat misnamed: [4]. check may be better.* Fix "package.loaders" misnomer [5][6] (package.loaders contains searchers not loaders). * Forwardly declared local functions look instead like global definitions. Currently the best solution may be commenting:
|
|
* On DetectingUndefinedVariables, my current opinion is that it is best handled by the text editor. I find runtime analysis (strict.lua) inferior to static bytecode analysis (globals.lua) inferior to static source analysis (LuaInspect). Furthermore globals.lua and the (hybrid) checkglobals don't work as well in 5.2 due to _ENV changes. |
|
* Allow 'a:b()' to not depend on 'a.b' (e.g. __mcall or __mindex metamethod) [1] * Overcome implementation limits in number of locals [2] and concatenation AssociativityOfConcatenation. (LuaFiveTwo is increasing "Maximum number of constants per chunk increased to 2^26 from 2^18" though.) * Allow pragmas in source to inject debugging info into the bytecode. [3] (useful for preprocessors of Lua source) (note: Metalua currently uses its own bytecode generator because of such limitations). There is a workaround but it is not fully general: LuaList:2010-06/msg00311.html . * for _,v in ipairs(t) is ugly, with the main complaint is that the meaning is not immediately apparent to users less familiar with Lua (Lua users can get used to it). The preferred syntax is for v in values(t), but the Lua for statement doesn't allow that to work with nil values. |
|
* Allow pragmas in source to inject debugging info into the bytecode. [1] (useful for preprocessors of Lua source). Metalua currently uses its own bytecode generator because of such limitations. There is a workaround but it is not fully general: LuaList:2010-06/msg00311.html . I suspect, however, that rather than injecting debug info, it may be better to just rewrite the message handler. |
|
* The inability to incorporate statements inside expressions limits the expressibility of Lua. Well, technically you can do this via an anonymous function, but allocating anonymous functions as such is not as speed efficient (although 5.2 function caching improves it some sometimes) nor the syntax that concise (without improvements to ShortAnonymousFunctions). This can be useful in metaprogramming, and Metalua recognizes this (see "Statements in expressions" in the Metalua Manual) and extends the Lua parser/compiler to allow it while requiring no change to the Lua VM. See also the "let" statements mentioned below on this page and "Stored Expressions" in LuaDesignPatterns. The SourceOptimizer provides an automated way to inline anonymous functions into standard Lua 5.1 source code, but the transformation wasn't straightforward. |
|
* Lua has the dichotomy of statements and expressions (StatementsInExpressions/ExpressionsAsStatements). The loophole in this are anonymous functions, but this involves a heap allocation, unless it triggers 5.2 function caching, bug that's not always triggered, and syntax can be verbose (ShortAnonymousFunctions). This can be useful in metaprogramming, and Metalua recognizes this (see "Statements in expressions" in the Metalua Manual) and extends the Lua parser/compiler to allow it while requiring no change to the Lua VM. See also the "let" statements mentioned below on this page and "Stored Expressions" in LuaDesignPatterns. The SourceOptimizer provides an automated way to inline anonymous functions into standard Lua 5.1 source code, but the transformation wasn't straightforward. |
|
* File handle virtualization - Sometimes you can pass a custom table that looks like a file handle to functions that expect a file handle, but this doesn't work all the time (e.g. if the function tests with io.type). Some other things, not necessary related to Lua core development: * Lua needs more standardization of quality control of libraries covering non-ANSI C functionality. ExtensionProposal and LuaRocks may help here. Related concerns involve documentation, testing, and packaging. * Strength access to existing library frameworks in other platforms like .NET, Java, and Python. Lua acquires the vast resources of these other developer communities. |
|
* Some other things, not necessary related to Lua core development: * Lua needs more standardization of quality control of libraries covering non-ANSI C functionality. ExtensionProposal and LuaRocks may help here. Related concerns involve documentation, testing, and packaging. * Strength access to existing library frameworks in other platforms like .NET, Java, and Python. Lua acquires the vast resources of these other developer communities. |
There are Lua wiki pages and projects I've been involved in.
Code and Projects:
BitOp 'bit' compatibility interfaces.
checkglobals function is an alternative to etc/strict.lua and luac -p -l - | lua test/globals.lua.
General Topics, Patterns, Tricks, and Design:
module function
Library module loading
nil not being explicitly stored in tables
function() ... end less verbose
o:f() v.s. o.f()
Comments/Annotations on Other Documents:
Here are few things bug me, though I'm not necessarily sure what to do about all of them.
f(...) to local ok, err = pcall(f, ...); if not ok then error(err) end or assert(pcall(f, ...)) has side-effects in traceback behavior. LuaList:2012-02/msg00858.html
level parameter used in the error function lacks maintainability since a function might be called from different levels and those levels might be refactored. Refactoring f() to (function() return f() end)() has side-effects in terms of level behavior, with no option to suppress the change in stack level. LuaCarp was a very early effort to improve this. Also see [6][7]. At least in 5.2 work, getfenv/setfenv are mostly removed and setfenv behavior in module is deprecated, so it's moving in the right direction.
assert function is arguably misnamed: [8]. Also, the fail expression is always evaluated.
_ENV = require '_G53'?
local ok, err = f(); if not ok then return ok, err end is a common idiom. Should it be made shorter?
printf "${x},${y},${x}" into printf("${x},${y},${x}", x, y, x) that is then evaluated at runtime might be a good compromise.
local two local function one() two() end function two() one() end -- forward declared local (misleadingly looks like global)
package.path and package.cpath are strings rather than arrays. LuaList:2010-06/msg00214.html . This led to the "lib" module [4].
for _,v in ipairs(t) do is ugly, and it's less efficient than for i=1,#t do local v=t[i] do. The too forms do noth have the same behavior either in terms of __len.
Caveat: The below list may not be entirely updated to reflect the final 5.2.0 release and may need cleaned up more.
These changes I want are included in the 5.2 work releases (LuaFiveTwo):
Op (supported by LuaJIT and superseding lbitlib). See BitwiseOperators/[5] Both the 5.2 and LuaJIT bit libraries are probably fine for most purposes, and it can be possible to write code that is compatible with both: `local band = bit.band or bit32.band` provided you avoid incompatible cases. Should get/set bitfield operations be added? [17]
hex 'cdef' or binary '0101', but why need that.
os.date. IMO, the standard library (except maybe debug) should never crash on bad input.
Here's other older ideas not addressed in 5.2 and which I haven't decided to move them up to the 5.3 wishlist:
... are somewhat awkward unless you copy it in a table (not as efficient) and handle nils correctly. See also VarargTheSecondClassCitizen. Something like the proposed #... and ...[i] would help, although that particular syntax has problems. The dilemma is summarized by Roberto here: LuaList:2010-06/msg00434.html. Some small improvements are likely possible though.
lua_createtable [34]. See TablePreallocation for the preallocation (does not discuss clearing).
x*x is generally faster than x^2 since Lua cannot reduce the latter to the former at compile time (think: x might have a __pow metamethod). Macro processing could alleviate this (e.g. "transforming "y = SQUARE(x+y) + 1" into "y = (let t1 = x+y in t*t) + 1"). See also LuaJIT and LuaToCee. Global, or at least whole-file, flow analysis can help here.