I don't think an implementation that just returns nil by default is what we want. Certainly this provides a standard interface (which I agree would be entirely beneficial), but so does a simple document listing function prototypes. I think rather than add empty weight to the API, the lua.org team should release a set of documents describing how libraries should be written and defining a set of common interfaces to such system dependent functions as setenv or putenv. Maybe I am too much of a purist, but I think this is the absolute most that should be done to Lua, since it accomplishes our goals but doesn't modify the API.

Also, the standard interface should be absolutely as thin as possible. Rather than providing a table as an abstraction of getenv and setenv (as Rici proposes), the standard interface should define a one-to-one mapping from Lua functions to C functions such as getenv, setenv, putenv, and ChangeEnvironmentVariableToString (or whatever C functions implement the desired task). If a function isn't provided by the current OS, then the function is left undefined in the environment. This provides optimal performance and maintains portability:

Using a one-to-one map such as this, the user can define whatever high-level abstractions she wants. Also, this approach doesn't bring the interface down to the "lowest common denominator" when different platforms provide more or less functionality. For example, if some OS provides ChangeEnvironmentVariableToNumber in addition to ...ToString, this functionality is not lost in the standard. This implementation is entirely blind to what OS it is running under; it cares only which functions are defined in the current environment.

Writing a standard library that morphs based on the OS is extremely hard or impossible to write. The only common denominator is C 89, which Lua already implements decently. A one-to-one mapping is the only way to safely provide system dependent functionality to all platforms. Anything else will only be portable to a finite set of OS, which is not acceptable.

On Sun, 2006-01-08 at 12:12 -0500, Rici Lake wrote:

On 8-Jan-06, at 11:00 AM, Chris Marrin wrote:> This is all good discussion. But let me say that my original intent > was to say that there are many capabilities that Lua has built in > (file I/O, a few os functions). But this set is incomplete and > therefore other libraries need to be brought in.Leaving aside loadlib, the facilities Lua offers are essentially those guaranteed in standard C (89). So it's not an arbitrary choice, really.However, I strongly agree with this:> The choice of libraries is many and often conflicting and I think this > hurts Lua development.Lua should not, in my opinion, include as standard libraries which require OS interfaces which may not exist on a conforming C implementation [Note 1]. However, there are many OS interfaces which are commonly available on popular platforms, and it would be nice if the Lua API for such interfaces were consistent. (For example, the name of the Lua function os.setenv should not depend on whether the underlying platform uses setenv, putenv, or ChangeEnvironmentVariableToString.)So I (continue to) believe that an important step is to define (and achieve consensus on) the library APIs which should be used to bind such OS features. That way, we could at least know that if there were a way of setting environment variables, it would be called in the same way, say os.setenv(varname, value) where both varname and value are strings [Note 2]; and furthermore that os.setenv should not do something else. (In fact, in this particular case, it could be included in the standard distribution with a default implementation which returned nil; a particular os library could then replace that with an implementation that did change the environment variable and returned a true value.)The case of loadlib() provides an example of how this model can work: it is an OS-specific facility, but the interface is well-defined in the language, and the default implementation simply returns an error indication.There is always the temptation to create shallow wrappers around OS-dependent facilities, which mimic the low-level OS API. This is usually a mistake; it makes it harder to write cross-platform code, and it often results in APIs which are "un-Lua-like". As a case in point, a directory iterator is much more consistent with Lua style than would be a shallow wrapper around opendir(), readdir(), etc.------------------Note 1: In fact, it is possible that Lua already includes too much in the standard distribution. For example, embedding Lua often requires replacing I/O implementations.It often comes as a surprise to embedders that print() and io.write() are unrelated, and that loadfile() cannot accept a file object returned by io.open(). It would be worth thinking about how to make it possible to synchronize the implementations of I/O between the base library and the io library, so that, for example, when the io library is included, base library implementations are redefined to use it.Note 2: Personally, I'm not convinced by the function call interface to getenv and setenv; it seems to me that it would be more natural to implement this directly as a table-like object which implements __index (by default) and __newindex (if that facility is available). This would allow the possibility of simulating setenv with an ordinary Lua table, in the case that the underlying platform does not provide any setenv capability.