Idea for a new kind of require

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

Idea for a new kind of require

Rob Hoelz-2
Hello fellow Lua users,

Over my experience reading e-mails on this mailing list, as well as
helping people on #lua, I've decided to write a library that implements
and enhances the functionality of require().
I have snippets of code from over the years, so the work will really
just be assembling them into something useful and coherent.  Here are
some proposed usages of this library:

  -- local drop-in replacement
  local require = require 'robs.require'

  require 'foo' -- works just like _G.require!

This example introduces nothing new; in fact, it *should* be possible to
just do _G.require = require 'robs.require'.  However, I wouldn't
recommend it.

  -- Loading modules with arguments

  require('foo.with.config', { ... }) -- the arguments are passed
directly to the chunk

I've seen this requested a few times, and I've also wished for it in my
own modules.

  -- Loading modules in a custom environment

 require:withfenv(custom_env)('foo') -- sets the environment for the
loaded chunk

  -- Loading modules in their own environment

  require:isolated('foo')

This may be nice for simple sandboxing, or imposing "good module
behavior" onto modules that don't have it.

  -- Loading modules relative to one another

  require:relative('bar') -- loads foo.bar

This is one of the most frequently asked questions I see regarding require.

The "extended" forms are also re-usable, if you prefer a different syntax:

  local require_relative   = require.relative
  local pythonic_require = require.isolated

  require_relative 'bar' -- loads foo.bar

Turn off loading of C modules for the given loader (of course, you can
also add your own):

  require.loaders.c_loader               = nil
  require.loaders.all_in_one_loader = nil

Or for a single invocation:

  require:withloaders('preload_loader', 'lua_loader')('foo')

Or for a special loader:

  local lua_only_loader = require:withloaders('preload_loader',
'lua_loader')('foo')

Or with custom loader functions:

  require:withloaders(loader_func_1, loader_func_2)('foo')

Of course, you can chain these:

  local pythonic_lua_only_require =
require.isolated:withloaders('preload_loader', 'lua_loader')

So, what are the community's thoughts on this library?  Is it a good
idea?  A terrible one?  Any suggestions on syntax, or further feature
enhancements?  I'll try to make it as extensible as can be.

The feedback I really want to get is regarding the name.  'robs.require'
is a terrible name, and I'm open to suggestions.  I just suck at naming
things. =)

Thanks,
Rob

Reply | Threaded
Open this post in threaded view
|

Re: Idea for a new kind of require

Duncan Cross
On Fri, Aug 24, 2012 at 1:53 PM, Rob Hoelz <[hidden email]> wrote:
> Hello fellow Lua users,
>
> Over my experience reading e-mails on this mailing list, as well as
> helping people on #lua, I've decided to write a library that implements
> and enhances the functionality of require().
> I have snippets of code from over the years, so the work will really
> just be assembling them into something useful and coherent.

Hi Rob. Interesting idea! Thanks for sharing it.

>   -- Loading modules with arguments
>
>   require('foo.with.config', { ... }) -- the arguments are passed
> directly to the chunk
>
> I've seen this requested a few times, and I've also wished for it in my
> own modules.

So how does this work, given that normally the module table is stored
and returned each time that require() is called -- does the loader now
get re-run each time instead, or are arguments ignored after the first
time, or what?

> The feedback I really want to get is regarding the name.  'robs.require'
> is a terrible name, and I'm open to suggestions.  I just suck at naming
> things. =)

How about something like 'necessity'?

-Duncan

Reply | Threaded
Open this post in threaded view
|

Re: Idea for a new kind of require

Rob Hoelz-2
On 8/24/12 3:09 PM, Duncan Cross wrote:

> On Fri, Aug 24, 2012 at 1:53 PM, Rob Hoelz <[hidden email]> wrote:
>> Hello fellow Lua users,
>>
>> Over my experience reading e-mails on this mailing list, as well as
>> helping people on #lua, I've decided to write a library that implements
>> and enhances the functionality of require().
>> I have snippets of code from over the years, so the work will really
>> just be assembling them into something useful and coherent.
> Hi Rob. Interesting idea! Thanks for sharing it.
>
>>   -- Loading modules with arguments
>>
>>   require('foo.with.config', { ... }) -- the arguments are passed
>> directly to the chunk
>>
>> I've seen this requested a few times, and I've also wished for it in my
>> own modules.
> So how does this work, given that normally the module table is stored
> and returned each time that require() is called -- does the loader now
> get re-run each time instead, or are arguments ignored after the first
> time, or what?
Excellent question!  I think that the extra arguments feature would
mainly be used as a configuration mechanism, and authors of modules
utilizing the feature would have to do so
under the understanding that the chunk is only evaluated once.
>
>> The feedback I really want to get is regarding the name.  'robs.require'
>> is a terrible name, and I'm open to suggestions.  I just suck at naming
>> things. =)
> How about something like 'necessity'?
>
> -Duncan
>


Reply | Threaded
Open this post in threaded view
|

Re: Idea for a new kind of require

Duncan Cross
On Fri, Aug 24, 2012 at 2:35 PM, Rob Hoelz <[hidden email]> wrote:
>> So how does this work, given that normally the module table is stored
>> and returned each time that require() is called -- does the loader now
>> get re-run each time instead, or are arguments ignored after the first
>> time, or what?
> Excellent question!  I think that the extra arguments feature would
> mainly be used as a configuration mechanism, and authors of modules
> utilizing the feature would have to do so
> under the understanding that the chunk is only evaluated once.

One convention I've seen used is to provide an "init" function that
does necessary setup then returns the module itself, like this:

  local mymodule = require 'mymodule'.init { fancy_mode = true, timeout = 5000 }

It's then the module's responsibility to handle re-initialization in
whatever way is appropriate. Maybe integrating with this convention
somehow would be something to consider.

-Duncan

Reply | Threaded
Open this post in threaded view
|

Re: Idea for a new kind of require

Rena

On Aug 24, 2012 10:15 AM, "Duncan Cross" <[hidden email]> wrote:
>
> On Fri, Aug 24, 2012 at 2:35 PM, Rob Hoelz <[hidden email]> wrote:
> >> So how does this work, given that normally the module table is stored
> >> and returned each time that require() is called -- does the loader now
> >> get re-run each time instead, or are arguments ignored after the first
> >> time, or what?
> > Excellent question!  I think that the extra arguments feature would
> > mainly be used as a configuration mechanism, and authors of modules
> > utilizing the feature would have to do so
> > under the understanding that the chunk is only evaluated once.
>
> One convention I've seen used is to provide an "init" function that
> does necessary setup then returns the module itself, like this:
>
>   local mymodule = require 'mymodule'.init { fancy_mode = true, timeout = 5000 }
>
> It's then the module's responsibility to handle re-initialization in
> whatever way is appropriate. Maybe integrating with this convention
> somehow would be something to consider.
>
> -Duncan
>

I really like how you can do "require 'foo'" or "require:xyz 'foo'". I may have to steal that idea.

Reply | Threaded
Open this post in threaded view
|

Re: Idea for a new kind of require

Javier Guerra Giraldez
On Fri, Aug 24, 2012 at 1:55 PM, Rena <[hidden email]> wrote:
> I really like how you can do "require 'foo'" or "require:xyz 'foo'". I may
> have to steal that idea.

why i don't get is why to use  "require:xyz 'foo'" instead of
"require.xyz 'foo'"

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Idea for a new kind of require

Rob Hoelz-2
That *could* end up being the final syntax; I haven't decided yet.
Consistency would be nice, but I'll end up mixing if it means the
implementation is simpler.

On Fri, 24 Aug 2012 18:46:43 -0500
Javier Guerra Giraldez <[hidden email]> wrote:

> On Fri, Aug 24, 2012 at 1:55 PM, Rena <[hidden email]> wrote:
> > I really like how you can do "require 'foo'" or "require:xyz
> > 'foo'". I may have to steal that idea.
>
> why i don't get is why to use  "require:xyz 'foo'" instead of
> "require.xyz 'foo'"
>


signature.asc (205 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Idea for a new kind of require

Rob Hoelz-2
On Sat, 25 Aug 2012 10:32:22 +0200
Rob Hoelz <[hidden email]> wrote:

> That *could* end up being the final syntax; I haven't decided yet.
> Consistency would be nice, but I'll end up mixing if it means the
> implementation is simpler.
>
> On Fri, 24 Aug 2012 18:46:43 -0500
> Javier Guerra Giraldez <[hidden email]> wrote:
>
> > On Fri, Aug 24, 2012 at 1:55 PM, Rena <[hidden email]> wrote:
> > > I really like how you can do "require 'foo'" or "require:xyz
> > > 'foo'". I may have to steal that idea.
> >
> > why i don't get is why to use  "require:xyz 'foo'" instead of
> > "require.xyz 'foo'"
> >
>
For interesting parties, I have started development:

https://github.com/hoelzro/lua-require

signature.asc (205 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Idea for a new kind of require

Doug Currie
On Aug 25, 2012, at 1:21 PM, Rob Hoelz <[hidden email]> wrote:
> For interesting parties, I have started development

An option to force re-load of the module would be nice. During development, I sometimes find it useful to set the package.loaded to false so the module is re-loaded, but I usually have to confirm what exactly has be be cleared to avoid using the already-loaded/cached version(s).

e


Reply | Threaded
Open this post in threaded view
|

Re: Idea for a new kind of require

Dirk Laurie-2
In reply to this post by Rob Hoelz-2
2012/8/25 Rob Hoelz <[hidden email]>:

> For interesting parties, I have started development:
>
> https://github.com/hoelzro/lua-require

You ask for a name.  What about "from"?

local from = require"from" -- we don't want to zap the standard "require"
-- module "from" returns a function that constructs and memoizes
-- module objects, so another "from" with the same name returns
-- the same object

source = from "mymodule"
-- at least the following
--    source.module = require "mymodule"
--    source.dest = _G
source: import "myfunc" -- source.dest.myfunc = source.module.myfunc
source: into(myenv) -- source.dest = myenv (returns source)

Or if you love Python:

from "mymodule": import "myfunc"
from "mymodule": into(myenv): import "myfunc"

Reply | Threaded
Open this post in threaded view
|

Re: Idea for a new kind of require

Tom N Harris
In reply to this post by Rob Hoelz-2
On Friday, August 24, 2012 08:53:05 AM Rob Hoelz wrote:
>   -- Loading modules with arguments
>
>   require('foo.with.config', { ... }) -- the arguments are passed
> directly to the chunk
>
> I've seen this requested a few times, and I've also wished for it in my
> own modules.
>

To allow a module to be loaded with different arguments, why not store the
module in a table keyed on the serialized argument?

    require 'foo'
    -- does this internally
    package.loaded['foo'][''] = load('foo', ...)('foo')

    require('foo', {"a", 5})
    -- does this
    package.loaded['foo']['1="a";2=5'] = load('foo', ...)('foo',{"a",5})

Or something like that.

--
tom <[hidden email]>

Reply | Threaded
Open this post in threaded view
|

require+localizing=frustrating (was Re: Idea for a new kind of require)

Jay Carlson
In reply to this post by Doug Currie
On Aug 25, 2012, at 2:07 PM, Doug Currie wrote:

> On Aug 25, 2012, at 1:21 PM, Rob Hoelz <[hidden email]> wrote:
>> For interesting parties, I have started development
>
> An option to force re-load of the module would be nice. During development, I sometimes find it useful to set the package.loaded to false so the module is re-loaded, but I usually have to confirm what exactly has be be cleared to avoid using the already-loaded/cached version(s).

Although the modern all-local model for imports has saved much frustration, it's kinda nasty about two things:

1) It fails "Don't Repeat Yourself", and fails it in programs two steps beyond "hello, world". local ml,sqlite=require"ml",require"sqlite". This is not a pretty thing to show off to beginners. The alternative is ml=require"ml", and we seem to be trying to discourage that. Or as proposed, go back to a require-replacement which sets _G.ml.

2a) Interactive development of modules. Single-module reload is hopeless. Everybody has a local pointer to your table, and they'll be using the old table. This is fixable by starting all modules with:

  local mymodule = {}
  local modulename = select(1,...)
  if modulename then
      mymodule = packages.loaded[modulename] or {}
      for k in next,mymodule,nil do mymodule[k] = nil end
  end
  function mymodule.write() end

which is kinda like what the deprecated module() did. Then you just need a require() which can be overridden to ignore packages.loaded.

2b) As things moved from _G into modules (like table.*), a lot of code got big lists of abbreviations at the top, in the name of efficiency, conciseness, and immunity to _G poisoning. local tinsert=table.insert. If anybody has stashed a local copy of mymodule.write, it doesn't matter if you updated the mymodule table in-place.

2c) Random closures floating around will have lexically localized old versions of mymodule.write.

Issue #2 seems to be telling me "get a real debugger if you don't want to restart on change". I don't find that very satisfactory, but the alternatives seem worse. Being able to mutate the procedure part of closures is a classic debug-and-go trick, but...yuck.

I think much of both #1 and #2 is a desire to use short names for references--and not take the efficiency hit of traversing _ENV.packages.loaded.mymodule.write in an inner loop. If modules had an aliases block which could be triggered on change-of-environment, that'd cover most of it. I dunno, hoisting inner declarations into that block is the logical next step, maybe.[1]

alias do
   import mymodule -- not quoted; is a variable declaration
   tinsert=table.insert
   in mymodule alias read, merge end
end
for i =1,1e3 do
  alias write=mymodule.write
  for j=1,1e6 do write() end
end

could be rewritten into

local mymodule, read, merge, tinsert, gensym$4321
local function __init()
  mymodule=require"mymodule"
  tinsert=table.insert
  read = mymodule.read
  merge = mymodule.merge
  gensym$4321=mymodule.write
end
__init()
for i=1,1e3 do
  for j=1,1e6 do gensym$4321() end
end

A whole bunch of trickery seems like it would benefit from a general hoist-to-top-chunk syntax, allowing relatively constant expressions to be declared in a lexical scope close to use, but not evaluated every time the loop goes 'round. (This is similar to C function-context "static" declarations.) But that's pretty radical, and I think I'd want to try it in metalua or something for a while before endorsing it.

I don't think this is "as simple as possible but no simpler," but probably unlike most people, don't-repeat-yourself has been driving me nutty lately.[2] This is yet another lexical environment problem--if you think it's a problem at all. Nobody is going to chop off your head for using _ENV.

Jay

[1]: The long form would be something like "alias function init()" but that's enough Christmas tree syntax for one day. Oh, and inner aliases could be hoisted to the first surrounding context with an alias block...wait, that means adding an alias block at level 2 can screw an alias four pages later and 9 levels deep. Bleh.

[2]: I went on a Project Lombok rampage last year and deleted a few thousand lines of Java getFoo()/setFoo() accessors. That commit had a very satisfying diffstat.
Reply | Threaded
Open this post in threaded view
|

Re: require+localizing=frustrating (was Re: Idea for a new kind of require)

David Manura
On Mon, Aug 27, 2012 at 2:09 PM, Jay Carlson <[hidden email]> wrote:
> 2a) Interactive development of modules. Single-module reload is hopeless.

I'd also like to hear what others do about hot swapping code.  Has it
already been discussed before?  Some options include

(O1) Disable caching in `require`.  For possible problems with this,
consider the example of a module dependency chain like (A ->B, A->C,
B->D, C->D).  The require 'A' would load two instances of D in memory,
so any objects instantiated from classes defined in those two D's
could get different metatables (unless the programmer explicitly
caches them somewhere in the global state), and __eq checks for
metatable equality.

(O2) Pass a special version of `require` to A and any modules A
transitively loads via that `require`.   This special `require`
maintains a private module cache (separate from package.loaded).  If
you edit any file in that private cache, reload all those files.
Alternately, record the module dependency chain (inferred by
executions of nested require calls) and their checksums or timestamps
for more selective reloading, like makefiles.  We assume here that
modules behave nicely: they don't introduce dependencies other than
expressed with require.  Optionally add some type of data persistence
API to modules to allow transferring state between old and new
modules.

(O3) Do something like Jay said where modules themselves say how they
should react when their dependencies change.  Even if this could be
practical, I don't think it will be so for novice users.

(O4) Do something on the VM level by walking Lua's internal GC memory
(and likewise LuaJIT's :/ ).

> 1) It fails "Don't Repeat Yourself",

I'm not so bothered with this syntactic point.  Sure, we may do `local
ml = require 'ml'`, but `local ml = require 'foo.bar.bar.ml'` and can
reduce repetition too, and one can think of other variants (e.g.
`local _ENV = requireunion("_G", "ml", "lfs"` returning a table that
is the union of the given modules, sort of how _G is itself the union
of math, string, etc.).

Reply | Threaded
Open this post in threaded view
|

Re: require+localizing=frustrating (was Re: Idea for a new kind of require)

Dirk Laurie-2
In reply to this post by Jay Carlson
2012/8/27 Jay Carlson <[hidden email]>:
> The alternative is ml=require"ml", and we seem to be trying
> to discourage that.

Are we? Even in Lua 5.2, we still have "lua -i -l mymodule"
and hey presto, there's something in the global namespace called
"mymodule".

No, what we are trying to discourage is modules assigning things
directly to global names, instead of the user program doing it.
There's nothing evil about global variables.  What is evil, is code
that you can't see in front of your nose assigning stuff to them.

I absolutely agree with the title of your post, but I disagree with
the imputation that it's a weakness of the current require. I believe
the notion that module names should be local variables all the time is
misguided.  Sometimes maybe, for special reasons, such as sandboxing,
but not regularly.

Personally I never assign a module to a local variable.  The members
actually use out of the module, yes, not only for efficiency, but
because it's a PITA to type math.exp and table.sort and io.open all
the time.

Reply | Threaded
Open this post in threaded view
|

Re: require+localizing=frustrating (was Re: Idea for a new kind of require)

Patrick Donnelly
On Tue, Aug 28, 2012 at 7:15 AM, Dirk Laurie <[hidden email]> wrote:

> 2012/8/27 Jay Carlson <[hidden email]>:
>> The alternative is ml=require"ml", and we seem to be trying
>> to discourage that.
>
> Are we? Even in Lua 5.2, we still have "lua -i -l mymodule"
> and hey presto, there's something in the global namespace called
> "mymodule".
>
> No, what we are trying to discourage is modules assigning things
> directly to global names, instead of the user program doing it.

Uh, so the Lua interpreter assigning a module to a global variable is
okay but for require() it's not okay?

> There's nothing evil about global variables.  What is evil, is code
> that you can't see in front of your nose assigning stuff to them.

No, global variables are indeed very evil. We regularly have problems
with them in the Nmap Scripting Engine where code is threaded (in the
Lua sense) and threads unintentionally overwrite each other's
variables.

> I absolutely agree with the title of your post, but I disagree with
> the imputation that it's a weakness of the current require. I believe
> the notion that module names should be local variables all the time is
> misguided.  Sometimes maybe, for special reasons, such as sandboxing,
> but not regularly.

Again, an example from the Nmap Scripting Engine:

Scripts would require libraries, many written in plain Lua, such as
http.lua. These would be done quite simply and in the encouraged
fashion:

require("http")

Because the library is stored in a global, all subsequent access would
be correct. This quickly deteriorates into a situation where the
script writer depends on a library which depends on another library
that the script uses incidentally but forgets to require:

-- script.nse --
require("http")

function foo (...)
  local a = base64.encode(str)
end

-- http.lua --
require "base64"


This script.nse will "just work" but is going to fail when http.lua
for whatever reason no longer needs base64.

What's an even worse (and not necessarily NSE specific) example, if
you have a script which depends on a library but does not require it,
it may have that library loaded via another script. And, because
scripts are run in an arbitrary and random looking order, you won't
know the library wasn't required until a user comes back complaining
with an error: 'attempt to index global 'get' (a nil value)'.

All of this is prevented by *forcing* code to localize a copy to the
library. It doesn't have access otherwise and so it cannot
accidentally forget to require. This problem is so insidious and
annoying that we (Nmap) have nixed globals in almost every instance in
favor of locals. A local is always predictable.

--
- Patrick Donnelly

Reply | Threaded
Open this post in threaded view
|

Re: require+localizing=frustrating (was Re: Idea for a new kind of require)

Sam Roberts
On Tue, Aug 28, 2012 at 12:40 PM, Patrick Donnelly <[hidden email]> wrote:
> Because the library is stored in a global, all subsequent access would
> be correct. This quickly deteriorates into a situation where the
> script writer depends on a library which depends on another library
> that the script uses incidentally but forgets to require:

Did you consider loading every script into its own environment, so its
"globals" go into a table just for it, rather than _G?

You'd have to modify require to understand this convention, but it
would allow people to not do explicit local, and still get script
isolation.

Sam

Reply | Threaded
Open this post in threaded view
|

Re: require+localizing=frustrating (was Re: Idea for a new kind of require)

Patrick Donnelly
On Tue, Aug 28, 2012 at 3:49 PM, Sam Roberts <[hidden email]> wrote:
> On Tue, Aug 28, 2012 at 12:40 PM, Patrick Donnelly <[hidden email]> wrote:
>> Because the library is stored in a global, all subsequent access would
>> be correct. This quickly deteriorates into a situation where the
>> script writer depends on a library which depends on another library
>> that the script uses incidentally but forgets to require:
>
> Did you consider loading every script into its own environment, so its
> "globals" go into a table just for it, rather than _G?

We already do this for threaded scripts to eliminate the problem for
global accesses. For libraries, you must use locals as there is only
one "instance" of the code.

> You'd have to modify require to understand this convention, but it
> would allow people to not do explicit local, and still get script
> isolation.

It's not a bad idea. We've only recently converted to using locals to
store the result of require; this was part of our conversion to Lua
5.2. Since the official idiom solved the problem, I didn't explore
other options.

--
- Patrick Donnelly

Reply | Threaded
Open this post in threaded view
|

Re: require+localizing=frustrating (was Re: Idea for a new kind of require)

James Graves-2
In reply to this post by Jay Carlson

Jay Carlson <[hidden email]> wrote:

> Although the modern all-local model for imports has saved much frustration, it's kinda nasty about two things:
>
> 1) It fails "Don't Repeat Yourself", and fails it in programs two steps beyond "hello, world". local ml,sqlite=require"ml",require"sqlite". This is not a pretty thing to show off to beginners. The alternative is ml=require"ml", and we seem to be trying to discourage that. Or as proposed, go back to a require-replacement which sets _G.ml.

Another option would be to have some means of creating local variables by the require directly... but that may be introducing too much magic into the language.

> 2a) Interactive development of modules. Single-module reload is hopeless. Everybody has a local pointer to your table, and they'll be using the old table. [...]
>
> 2b) As things moved from _G into modules (like table.*), a lot of code got big lists of abbreviations at the top, in the name of efficiency, conciseness, and immunity to _G poisoning. local tinsert=table.insert. If anybody has stashed a local copy of mymodule.write, it doesn't matter if you updated the mymodule table in-place.
>
> 2c) Random closures floating around will have lexically localized old versions of mymodule.write.
>
> I think much of both #1 and #2 is a desire to use short names for references--and not take the efficiency hit of traversing _ENV.packages.loaded.mymodule.write in an inner loop. If modules had an aliases block which could be triggered on change-of-environment, that'd cover most of it. I dunno, hoisting inner declarations into that block is the logical next step, maybe.[1]
>
> I don't think this is "as simple as possible but no simpler," but probably unlike most people, don't-repeat-yourself has been driving me nutty lately.[2] This is yet another lexical environment problem--if you think it's a problem at all. Nobody is going to chop off your head for using _ENV.

Jay:

You've managed to sum up my own disquiet about the existing module system for Lua 5.2.

I've been thinking about this issue on and off for nearly a year. And I don't have a solution, but I do have some ideas.

---------------------------------------

From what I understand, a considerable part of the motivation for moving imported modules and their individual functions into local variables is performance, as you allude to.

What if we tried to fix this issue from the other direction, and make accessing frequently used table values as quick as a local reference? What if this also worked for OO programming, so that even when accessing a method from a parent class through the object's metatable, it was just as fast as a local?

Certainly we want people to keep using local variables when appropriate, and we don't want to encourage pollution of the global name space.

LuaJIT can detect and hoist these table accesses outside of tight loops and other places where it would matter. Can this sort of thing be implemented in Lua, without a heavy penalty in terms of code size and complexity?

---------------------------------------

In a different but related direction, I'm thinking about a more general mechanism to cache table contents accessed via a chunk of code. I would also like this done when the lookup is going through metatables.

The results would be cached in a fashion similar to local variables. The cache would be invalidated when the table is changed. Since the Lua state is single-threaded, I don't see any theoretical difficulty to implementing this.

Practically speaking, I'd see this as being tricky to do.  However, it could really speed up many kinds of programs, especially OO ones.

---------------------------------------

There were also some productive discussions last year about re-implementing the 'module' function for Lua 5.2.

I thought maybe we were headed towards a consensus there, but the discussion just died off.

---------------------------------------

So, I'm not satisfied with the current situation, but I hope we can keep talking about it, and figure out something better.

James Graves