lua-users home
lua-l archive

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


David Manura <dm.lua@math2.org>:
> The performance problems might be solved via a table that is lazily copied on use.

Yes, this would be a nice way to implement it.  Alas, I was worried
about something that you also noted:

> Incompatibilities with existing code may remain though.

Some code (like "strict") relies on being able to manipulate the
environment's metatable.  So I replicate the environment faithfully so
that each module believes it is loaded into _G and is free to use
"strict" and do other metatable tricks.

> OTOH, regular
> copying might in some cases also cause incompatibilities: It's not
> possible to copy all aspects of an object, such as its identity, i.e.
> address, or some transient structure.

I don't copy objects, just bindings(*).  The 'print' function from _G
is the same one (has the same identity) for every module.  But since
each module has its own copy of _G, each module has its own binding to
'print' and can change it to point to some other function without
disturbing other modules.

(*) What is copied is the location of things whose denoted value is a
reference in Lua, such as tables and functions, and the value of
things whose denoted value is a Lua value, such as numbers.

If a module X exports an object A, that (singleton) object, A, is
intended to be shared.  (Otherwise, the module should implement a
factory.)  So the binding to A is copied, not A itself.  Every module
that requires X will get a binding to A through which they can
communicate, coordinate, or in other ways share state.  This is no
different than the case when Darwin is not used, i.e. with the
out-of-the-box Lua modules.

Jim

PS -- A side note:  A Lua module table can include sub-tables of
functions and values, so Darwin supports that as well.  By default,
sub-tables are assumed to contain bindings that should also be copied
(so the copying of bindings is deep).  But Lua objects can also have
type "table", so you must declare the items that are objects in your
Darwin module declaration.  At first, I thought this was ugly.  Now I
like it, because it forces the declaration of state that is shared
across all the users of a particular module.

For example, my "list" module has an object called "null" that denotes
the empty list.  It is exported by "list" as an object, because every
piece of code that uses "list" should share the same value for "null".
 The structure declaration for my "list" module looks like this:

structure.declare { name="list";
                              location=".";
                              open={"_G"};
                              objects={"null"};
                              files="list.lua";
		 }

The optional "location" field specifies where to import the bindings
of the "list" module, and "." is a special value meaning "at top
level" (because I want to use the list functions without writing, e.g.
"list.car").  The "open" field specifies the initial environment into
which "list.lua" must be loaded -- and _G is typically in that list,
but need not be.

Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
Darwin 1.0.3 Copyright (c) 2009 James S. Jennings
Current package is 'user'.
> structure.declare { name="list";
                                 location=".";
                                 open={"_G"};
                                 objects={"null"};
                                 files="list.lua";
		 }
> =null
nil
> =list
nil
> require "list"
> =null, list
{}	function: 0x1574220
> =list(1, 2, "Hello")
{1, 2, Hello}
> =cdr(list(1))==null
true
> x=10
> =structure.instructure("list", "return x")
> =structure.instructure("list", "return x")==nil
true
> =x
10
> =structure.instructure("list", "return print")
function: 0x1537a40
> =print
function: 0x1537a40
> for k,v in ipairs(structure.signature("list")) do print(v) end
last
set_cdr
length
listref
map
append
listtail
apply
car
reverse
cddr
reduce
make_iterators
filtermap
filter
cadr
elements
listtotable
foreach
cdr
set_car
isnull
ispair
islist
list
cons
member
null
caddr
tabletolist
>