about the next version

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

about the next version

Roberto Ierusalimschy
As several people have suggested, the next version will be 5.0. We are
still planning to realease it (at least an alpha version) by May, but we
are not sure we will be able to do that. Anyway, we are trying to fix
some decisions. So, following is a list of the main differences from
lua4.1w4 to Lua 5.0. Most of them have been discussed in the list
already.

- "generic for": will have an implicit state, so that for several common
uses you don't need a new closure for each `for'.

- co-routines: basically as it is, but we will try to allow for `yield's
inside linehooks.

- metatables: as it is now, but the keys will be prefixed with '__'
(e.g. __gettable, __settable, etc.) The main ideia is to facilitate
finding parts of the code that deal with metatables.

- error handling: we will probably change functions related to error
handling (dostring/dofile, call, etc.). We will have a proposal soon.

- standard libraries: standard libraries now use "namespaces". So,
strfind now is str.find, sin is math.sin, fileopen is io.open. Some
basic functions (type, assert, error, etc.) are still global. We also
changed the io library; e.g. files act as objects (f = io.open(...);
f:read(...); f:write(...)).

- declaration of globals: we introduced global declarations:

    global a,b,c
    global a,b,c in T
    global in T        -- change the default

So, "global in nil" forces declarations for every variable;
"global in {}" puts all undeclared variables into a private table;
"global sin, cos in math" allows the unqualified use of the
names "sin" and "cos".

- we introduced a "lightweight userdata", which is a value and not an
object.

- require: the path now specifies "templates", instead of directories.
For instance, require "A" with path "./?.lua;./?.lc;/usr/local/?/init.lua" 
will look for "./A.lua", "./A.lc", and "/usr/local/A/init.lua".


What is still missing?

- "partial orders": the bug in comparisons with NaN must be solved. That
implies in not reducing other comparisons to "lt", and so probably the
solution will also change the "lt" tag method.

- the declaration "global in nil" forces the declaration of *all* names.
So, even basic functions like "type" and "error" should be declared. It
would be good to have some scheme to "pre-declare" some identifiers...

-- Roberto

Reply | Threaded
Open this post in threaded view
|

RE: about the next version

Curt Carpenter
> - declaration of globals: we introduced global declarations:
> 
>     global a,b,c
>     global a,b,c in T
>     global in T        -- change the default

I can't remember if this has been discussed before, but I would very
much like an option (either in Lua or C) that changes the default scope
of variable declarations from global to local.

Thanks,

Curt

Reply | Threaded
Open this post in threaded view
|

RE: about the next version

Luiz Henrique de Figueiredo
In reply to this post by Roberto Ierusalimschy
>I can't remember if this has been discussed before, but I would very
>much like an option (either in Lua or C) that changes the default scope
>of variable declarations from global to local.

"global in {}" does (almost) this.
--lhf

Reply | Threaded
Open this post in threaded view
|

RE: about the next version

Curt Carpenter
In reply to this post by Roberto Ierusalimschy
>>I can't remember if this has been discussed before, but I would very 
>>much like an option (either in Lua or C) that changes the default
scope 
>>of variable declarations from global to local.
>
>"global in {}" does (almost) this.

I don't really understand this. Actually, maybe "global in nil" does
what I really want (no accidental globals). Can you provide more details
on the global keyword, and especially "in"? I'm wondering, for example,
whether it only affects variables that already exist vs variables
created later, etc.

Thanks,

Curt

Reply | Threaded
Open this post in threaded view
|

RE: about the next version

Luiz Henrique de Figueiredo
In reply to this post by Roberto Ierusalimschy
"global in nil" means no accidental globals: every variable needs a declaration,
either local or global. However, "global in nil" is very restrictive. For
instance, to use the sine function you'd have to write "global math" so that
you can then write "math.sin(x)". Or write "global math; global sin in math",
so that you can then write "sin(x)".

"global in {}" means all undeclared variables are stored in an anonymous table;
there can be accidental reading or writting of "real" globals. So, they are
(almost) local variables in this sense, except that access to them is still
via indexing a table (not a fast array, as locals are).

In general, the syntax is "global a,b,c in T" where a,b,c are names and T is
an expression that is evaluated at runtime. Access to a,b,c is translated to
TT.a, TT.b, TT.c, where TT is the value of T.

If the "in T" part is omitted, then the current global table (at runtime)
is used. If the name list is omitted, then all undeclared variables are routed
to T.

Several "global" declarations can be active at any moment. The latest one
that fits an undeclared name is used. For instance, the code

 global a,print
 local T={b=2}
 local S={c=3}
 a=10 b=20 c=30 d=40
 do
  global in T
  global c in S
  a=1
  d=4
  print(a,b,c,d)
 end
 print(a,b,c,d,T.d)

outputs

 1	2	3	4
 1	20	30	40	4

that is, in the first print statement, a is a "real" global, because it has been
declared global; b and d are got from T, because that's the default in the
do-end block; c is got from S, because it has been explicitly declared so. Note
that none of this affects the values of b,c,d, which are global outside the
do-end block, but a 'd' has been added to T.

Finally, note that there are subtle details here: S must be declared explicitly
as local (or global); otherwise, since it's used after "global in T", S would
be got from T, where it does not exist.

The global declaration is a powerful thing (specially when the routing tables 
have get/set methods) but is not to be used lightly.

I hope this helps.
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: about the next version

John Belmonte-2
In reply to this post by Roberto Ierusalimschy
Is there any update on the possibility of changing to a standard license?


-John



--
OpenPGP encrypted mail welcome.



Reply | Threaded
Open this post in threaded view
|

Re: about the next version

Blair Zajac
In reply to this post by Roberto Ierusalimschy
Roberto Ierusalimschy wrote:
> 
> - standard libraries: standard libraries now use "namespaces". So,
> strfind now is str.find, sin is math.sin, fileopen is io.open. Some
> basic functions (type, assert, error, etc.) are still global. We also
> changed the io library; e.g. files act as objects (f = io.open(...);
> f:read(...); f:write(...)).

Not looking to be flame bait here, but what about using an existing
class hierarchy and naming for objects and methods?  Python's may be a
good one given that Lua and Python are closely related.  Perl could also
be used since a lot of work has gone into developing CPAN and organizing
all the 1000's of modules there, but care would have to be taken because
many of Perl's functions are from the pre-OO days (such as open).  Java
may be another one to consider.

This would make it easy to reduce the amount of time to think about how
to lay out a hierarchy and concentrate on other things.  Also, porting
from the model language would would be easier.

Best,
Blair

-- 
Blair Zajac <[hidden email]>
Web and OS performance plots - http://www.orcaware.com/orca/

Reply | Threaded
Open this post in threaded view
|

Re[2]: about the next version

Denis Andreev
In reply to this post by Luiz Henrique de Figueiredo
Oh! Big move for OOP-like programming style.

<lua>

class_instance = Class{parameter = value}

function class_instance:initialize()
         --...
end

function class_instance:method()
         globals in self

         initialize()
end

</lua>

--Denq


Reply | Threaded
Open this post in threaded view
|

Re: Re[2]: about the next version

Luiz Henrique de Figueiredo
In reply to this post by Roberto Ierusalimschy
>Oh! Big move for OOP-like programming style.
>
>function class_instance:method()
>         globals in self
>
>         initialize()
>end

That was not the primary motivation for introducting "global", but it works.
Just note that "globals in self" routes *all* undeclared variables to "self":
you'd have to declare global functions and such if you use them.
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: about the next version

Edgar Toernig
In reply to this post by Roberto Ierusalimschy
Roberto Ierusalimschy wrote:
> 
> - declaration of globals: we introduced global declarations:
> 
>     global a,b,c
>     global a,b,c in T

I'm just curious when the first people ask for an include statement
to import globals.

> It would be good to have some scheme to "pre-declare" some identifiers...

Oh, you are the first one ;-)


>     global in T        -- change the default

Just some clarifications: I assume that 'global in T' is a pure lexical
declaration and not the same as 'globals(T)'.  Right?

And the other one: is 'global in nil' detected at compile time and
gives errors for undeclared variables? (At least in this special form
where nil is explicitely given?)


Another possible feature that comes up is a variant that searches a
list of tables for a global (like 'global ... in T,U,V') but I think
that can easily be done with something like

  global ... in dictionary { T,U,V } -- [1]

so it's already possible and even pretty versatile.


But...,

I'm not sure if the global statement is the right thing.  It looks
nice for simple things but IMHO it does not help in bigger apps
where it would be mostly needed.  You _have_ to declare all globals
and doing that in each and every file could become annoying.  I guess
every file would start like this:

	global in nil
	global table, string, math, ...
	global require, error, assert, ...

	require "foo"	global foo
	require "bar"	global bar,bar2,bar3

I think, some day a combined 'require and global' (i.e. import) statement
is needed to make real use of it.  (like Modula?!?)

And at last: it doesn't make the lanugage easier...

Ciao, ET.



[1] with dictionary being:

local dict_meta = {
  __index = function(tbl, name)
    for i=1,getn(tbl)
      local val = tbl[i][name]
      if val then return val end
    end
  end
}

function dictionary(tbl)
  -- If a name is not present in tbl search for it in tbl[1..n].
  -- New names are stored in tbl itself.
  -- [Obbug: tbl.n]
  return metatable(tbl, dict_meta)
end

Reply | Threaded
Open this post in threaded view
|

RE: Re[2]: about the next version

Peter Prade
In reply to this post by Luiz Henrique de Figueiredo
Hi,
how about beeing able to set more than one table:

globals in self, globals()

which means:
- on write access, self is used
- on read access, first self, then globals() is used.

i know i can setup something similar with tagmethods, but that would change
the first table for all accesses.
hmm, maybe set a proxy table like this:

function proxytable(t, t2)
	local ret = {t, t2}
	-- setup tag methods, so that indexing ret routes those accesses to the
included tables
	return ret
end

then you can write:

function class_instance:method()
	globals in proxytable(self, globals())
	initialize() -- calls class_instance.initialize() (and not
class_instance:initialize(), doh)
	print() -- calls globals().print()
end

but this will create a new proxytable every time the function is called...
would be hard to hardwire this into lua (without the gc littering)?

Peter Prade

Another thought:
:initialize() -- this could use the table that is set up as global table as
a first parameter

> -----Original Message-----
> From: [hidden email]
> [[hidden email] Behalf Of Luiz Henrique de
> Figueiredo
> Sent: Wednesday, April 17, 2002 12:16 PM
> To: Multiple recipients of list
> Subject: Re: Re[2]: about the next version
>
>
> >Oh! Big move for OOP-like programming style.
> >
> >function class_instance:method()
> >         globals in self
> >
> >         initialize()
> >end
>
> That was not the primary motivation for introducting "global",
> but it works.
> Just note that "globals in self" routes *all* undeclared
> variables to "self":
> you'd have to declare global functions and such if you use them.
> --lhf


Reply | Threaded
Open this post in threaded view
|

Re: about the next version

Luiz Henrique de Figueiredo
In reply to this post by Roberto Ierusalimschy
>Just some clarifications: I assume that 'global in T' is a pure lexical
>declaration and not the same as 'globals(T)'.  Right?

Yes, it's purely lexical.

>And the other one: is 'global in nil' detected at compile time and
>gives errors for undeclared variables? (At least in this special form
>where nil is explicitely given?)

Yes, it's detected at compile time.

>I'm not sure if the global statement is the right thing.

It's a new thing, and certainly not simple (or at least capable of being used
in quite complicated ways), but we thing it does address a need. Or doesn't it?
(The only snag right now is the need for "predeclarations".) Like all new things
it will take some time until we really know how useful it is. So, let's hear
about possible applications and suggestions.

>And at last: it doesn't make the lanugage easier...

The default remains easy (globals do not need declaration).
The "global" declaration is for sophisticated uses, but I don't think it makes
the language more difficult: it just let's you do complicated scope control.
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: about the next version

Roberto Ierusalimschy
In reply to this post by John Belmonte-2
> Is there any update on the possibility of changing to a standard license?

No, but now Lua is classified as "free software" by the FSF (which means
that its license was verified by them). See

   http://www.gnu.org/directory/lua.html

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: about the next version

Peter Loveday-2
In reply to this post by Roberto Ierusalimschy
> - "generic for": will have an implicit state, so that for several common
> uses you don't need a new closure for each `for'.

Cool.
 
> - co-routines: basically as it is, but we will try to allow for `yield's
> inside linehooks.

Cool.
 
> - metatables: as it is now, but the keys will be prefixed with '__'
> (e.g. __gettable, __settable, etc.) The main ideia is to facilitate
> finding parts of the code that deal with metatables.

Cool.
 
> - error handling: we will probably change functions related to error
> handling (dostring/dofile, call, etc.). We will have a proposal soon.

Any thoughts of some form of exception system for this?
 
> - standard libraries: standard libraries now use "namespaces".

Excellent.
 
> - declaration of globals: we introduced global declarations:

Hooray!  My number one gripe with Lua answered :)

Looks like a very clever and versatile solution to the problem.

What is the scope of the "global in x" statement ?  ie if some
idiot writes a function that says "global in x" then returns, I
am hoping if I call that function it will not alter what my current
global scope is set to?

Also, how do you reset globals to be truly global... something like
global in global ?

> - we introduced a "lightweight userdata", which is a value and not an
> object.

I don't really understand what the difference is, as userdata is simply an
arbitrary 32 bit value anyway?  Does this just imply the lightweight
userdata cannot have a metatable?
 
> - require: the path now specifies "templates", instead of directories.

Cool.  Obviously the question is, when is work5 out ? :)

- Peter




Reply | Threaded
Open this post in threaded view
|

Re: about the next version

Luiz Henrique de Figueiredo
In reply to this post by Roberto Ierusalimschy
>What is the scope of the "global in x" statement ?  ie if some
>idiot writes a function that says "global in x" then returns, I
>am hoping if I call that function it will not alter what my current
>global scope is set to?

Like everything else in Lua (now!), scope is purely lexical. So your hopes
are founded.

>Also, how do you reset globals to be truly global... something like
>global in global ?

The closest thing is "global in globals()" but the best solution is to
use do..end scopes.

>I don't really understand what the difference is, as userdata is simply an
>arbitrary 32 bit value anyway?  Does this just imply the lightweight
>userdata cannot have a metatable?

Yes, lightweight userdata cannot have a metatable. They're much like numbers.
Some people were using doubles to store pointers to overcome perceived
"inefficiencies" in userdata. Lightweight userdata avoids these uglys hacks.
 
>Cool.  Obviously the question is, when is work5 out ? :)

It would be 5.0 work0, but probably will be 5.0 alpha.
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: about the next version

Edgar Toernig
In reply to this post by Luiz Henrique de Figueiredo
Luiz Henrique de Figueiredo wrote:
> 
> >I'm not sure if the global statement is the right thing.
> 
> It's a new thing, and certainly not simple (or at least capable of being used
> in quite complicated ways), but we thing it does address a need. Or doesn't it?
> (The only snag right now is the need for "predeclarations".)

It does more.  As I see it, people want some kind of protection against mistyped
variable names.  One fundamental part of that is a way to easily know which
globals are exported by a module/file/library.  That is not addressed with the
current global statement (the 'snag' you mention: the core wants to export
globals without the need to import each one individually).

> The "global" declaration is for sophisticated uses, but I don't think it makes
> the language more difficult: it just let's you do complicated scope control.

And that is what I fear.  The simple 'global <name>' is easy and I have no
problem with that.  A method to let the compiler check for undefined names.

But the 'global ... in <table>' is something completely different.  It doesn't
address the mentioned 'need'.  It introduces a method for complicated dynamic
variable bindings and my fear is that you get even more complex rules (Which
identifier accesses which object?) than the rules in C++.  Reading sources
may become a nightmare.

In fact, I think that the 'global ... in <table>' has nothing to do with globals
any more.  It's a shorthand to access table fields (Pascal's with-statement).
A completely different topic.

Maybe it would be better to add only the simple 'global <name>'.  Then, for
Lua 6.0, think for some way to export globals to other files and add that.

My 2 cent, ET.

Reply | Threaded
Open this post in threaded view
|

Re: about the next version

Roberto Ierusalimschy
> But the 'global ... in <table>' is something completely different.  It doesn't
> address the mentioned 'need'.  It introduces a method for complicated dynamic
> variable bindings and my fear is that you get even more complex rules (Which
> identifier accesses which object?) than the rules in C++.  Reading sources
> may become a nightmare.

I did not understand your point. The binding rules seem quite simple to me:

1) look for an explicit declaration for that variable, using the usual
scope rules.

2) if there is no explicit declaration, look for the inner default
declaration.

3) if there are no default declarations, the variable is a "free" global.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: about the next version

John Belmonte-2
In reply to this post by Roberto Ierusalimschy
Roberto wrote:
Is there any update on the possibility of changing to a standard license?

No, but now Lua is classified as "free software" by the FSF (which means
that its license was verified by them). See

   http://www.gnu.org/directory/lua.html

I would like an important question answered: Is the Lua license compatible with the GPL? (I know the GPL is not well liked on this list, but I hope not to prompt another round of bashing.) It would be a simple question to answer if Lua was under a standard license. Having the FSF acknowledge Lua as free software does not shed light on things.

-John



--
OpenPGP encrypted mail welcome.



Reply | Threaded
Open this post in threaded view
|

RE: about the next version

John Passaniti-4
> I would like an important question answered:  Is
> the Lua license compatible with the GPL?  (I know 
> the GPL is not well liked on this list, but I 
> hope not to prompt another round of bashing.)  It 
> would be a simple question to answer if Lua was 
> under a standard license.  Having the FSF 
> acknowledge Lua as free software does not shed 
> light on things.

The last time I asked about the Lua license, I was confused over why
some people seemed to care so much about the issue.  A few people
responded to me, explaining why they cared.  And as I read their
responses, I noticed a consistent theme.

Someone used the example of a software distribution incorporating Lua.
With a standard license, any ambiguity on if Lua could be distributed is
answered.  Someone else used the example of making Lua a generic
dynamically linked library for any application.  Apparently that
specific case isn't explicitly addressed by the Lua license, and so a
standard license would address that ambiguity as well.

So what a standard license really appears to provide is a means to know
if one can use Lua without asking for permission from the Lua authors.
Is that a good thing?  Maybe I'm nutty, but when I find something
ambiguous, I ask.  When I considered putting Lua into a commercial
embedded embedded Ethernet switch, I wasn't 100% sure if I could.  So I
wrote to Luiz.  I explained what I wanted to do, asked if he had any
concerns, and in just a few hours had the response.

If Lua had a standard license, I wouldn't have had to write to the Lua
authors.  Again, is that a good thing?  It's my understanding that
funding for continuing development on Lua is based in part on how much
interest there is in Lua to the Pontifical Catholic University of Rio de
Janeiro.  By writing to the Lua authors, I told them about yet another
use of Lua in the world, which they could use to justify future funding
for Lua.  That helps them, and it helps the larger Lua community.

So what's the real concern here (in opposition to a theoretical
concern)?  Are you intending to use Lua in a way that
http://www.lua.org/copyright.html doesn't already cover?  I'm sure the
Lua authors would love to hear about it.

I guess I should expose my bias.  I think most licenses are stupid.  I'm
not a lawyer.  I'm a programmer, and if I want to use someone else's
work in my code, I'm not going to waste my time pretending that I
understand the sometimes subtle turns of phrase that lawyers use in
those licenses.  Instead, I'm going to go to the source, tell them what
I want, and see if they say it is okay.  If they have any concerns or
questions, they can write back and ask.  Otherwise, they'll probably say
"okay" and I'm good to go.



Reply | Threaded
Open this post in threaded view
|

Re: about the next version

Edgar Toernig
In reply to this post by Roberto Ierusalimschy
Roberto Ierusalimschy wrote:
> 
> > But the 'global ... in <table>' is something completely different.  It doesn't
> > address the mentioned 'need'.  It introduces a method for complicated dynamic
> > variable bindings and my fear is that you get even more complex rules (Which
> > identifier accesses which object?) than the rules in C++.  Reading sources
> > may become a nightmare.
> 
> I did not understand your point. The binding rules seem quite simple to me:
> 
> 1) look for an explicit declaration for that variable, using the usual
> scope rules.
> 
> 2) if there is no explicit declaration, look for the inner default
> declaration.
> 
> 3) if there are no default declarations, the variable is a "free" global.

The scope rules (which define which declaration to take for a name) are
not what I meant (although there are some subtleties, too - see below).
I meant the dynamic binding of a name (which storage location is accessed
by that name).  [My comparison with C++ was bad - it has complex scope rules.]

Sure, with 'old' globals table you could play tricks too (redirecting
names to different tables, generate calculated values, etc).  But that
was considered to be some special heavy magic.  The 'global in <table>'
is different.  The simple form (i.e. global in T) is normally not enough.
You need some symbols from other tables.  So I think that what you'll
normally find is something like 'global in <function>' where a function
will create a table to be used (see my dictionary example some posts ago
or Peter's try to use if for C++-like field access).  And suddenly you no
longer know what you'll access with a 'global variable'.  It becomes a
run-time decision.

About the scope rules: the fact that 'precise declarations' (global <name>)
take precedence over 'default declarations' (global in <table>) can create
strange situations.  A block of code that works well in one context no
longer works in a different one.  I.e. you can't cut'n'paste a function
from one file to another if it uses 'default declarations'.  You have
to copy the required 'precise declarations' too or you may get hard to
find bugs.

And then, as far as I understand it, 'default declarations' do not nest
in the sense that all of them are used for the binding.  Only the inner-
most one is taken.  That gives some kind of 'undefining' a global within
a block.

Ciao, ET.

12