XMLRPC 0.0 for Lua

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

Re: unified methods

Edgar Toernig
[hidden email] wrote:
> 
> As I understand it from the correspondence (and no doubt Edgar will correct
> me if I'm wrong), in his unified methods implementation,
> 
> a:foo(x)
> 
> is "syntactic sugar" for:
> 
> methods(a).foo(a,x)
> 
> where methods(a) is some sort of metamethod, I would guess.

It's a low level function that extracts the associated method table
that _each_ object has (it's a field in the low level data structures).
You can set it with methods(x, table).

> (Or perhaps it works recursively, which might be cool if confusing.)

Of course.  methods(methods(x)) works well and is actually used in Sol's
class system:

methods(x) is the "class table" that describes what can be done with x.
method(method(x)) is the "super class table" that describes what can be
done with "class tables" (creating instances and subclasses, perform
inheritance, ...).  And the "super class table" itself is a regular table
with no fancy features so methods(methods(methods(x))) is the same as
methods({}).  Confusing, isn't it ;-)


> Another alternative would be for
> 
> a:foo
> 
> to be "syntactic sugar" for:
> 
> curry1(methods(a), a)
> 
> where curry1 is a language primitive

Actually, the ':' is the low level primitive to access the method table.
Where a.x access field x from a, a:x access field x from methods(a).  So
this is valid:

a:x = a:x + 1
a:x:y.z = 42
a:x = function(...)...end
function a:x(...)...end

The syntactic sugar comes in when a:x is used as for a function call.
In that case, a self is automagically added as the first argument.  To call
a method without inserting the object as arg1 you have to use parenthesis.


>[...]
> a<<x>>         is defined as  getmethod_event(a, x)
> a<<x>> = v     is defined as  setmethod_event(a, v, x)
> 
> Taking this additional step makes the optimisation referred to above a
> little harder to do, since we can no longer rely on a->x returning a curry.

Actually, for Sol's first version I really started to introduce a
getmethod and setmethod event for this (and indexmethod and newmethod).
Put I dropped it pretty fast.  While it allows you to differentiate how
the access to a table is done it introduces much too much complications
and inconsistencies.

You get all these fancy features with a 3 level architecture as described
above (object, class table, super class table).  When you try to read a:x
you check the gettable and index methods for a's method table; it's a
regular table after all, so why not check it's index/gettable method
when a field is requested?  So a:x invokes Super.index(a,x) if x is not
present (Super is the super class table) or even Super.gettable(a,x)
for every x if Super.gettable is present. [1]


Ciao, ET.


[1] One is tempted to allow multiple consecutive ':' to access the
n'th method of x (so a:x invokes a::gettable(a,x)).  But I found
that you don't access the n'th method of an object very often and
then, having some kind of 'self' field in method tables (the super
class enforces this) is more versatile.  If this field is called
this_class, you can i.e. write a:this_class:gettable(x) and you can
get the method table without using the methods function by writing
a:this_class .

Reply | Threaded
Open this post in threaded view
|

Method Tables - a modified Lua 4.1 Work Beta implementation

Joshua Jensen
In reply to this post by Joshua Jensen
After the discussion about unified methods, I have copied just the
method table code from the LuaState distribution and put it in a clean
Lua 4.1 Work Beta implementation.

Credit for the method tables implementation goes to Edgar Toernig, who
created the method tables for Sol.  Except for the parser changes and
new VM opcodes, this is 100% Edgar's work.

Documentation can be found in the "Unified Methods" and "Standard
Unified Method Callbacks" sections of
http://www.workspacewhiz.com/Other/LuaState/LuaState.html with the
following differences:

* The LuaState :: operator is now a .> operator, so it more closely
mirrors the regular . table indexing operator.
* The LuaState -> operator is now a :> operator, so it more closely
mirrors the regular : function calling operator.
* Due to parser changes in Lua 4.1 Work Beta (as opposed to Lua 4.1
Alpha), it is no longer possible to:

print(4:>sqrt())

The modified directories can be found here.  Just do a diff of the
original Lua 4.1 Work Beta code and this code to see the small number of
differences.

http://workspacewhiz.com/Other/LuaState/Lua41BetaWorkMethodTables.zip

Changes:
===============================

lauxlib.*:

* Added luaL_openlibintotable() helper function (Sol).

lua.h:

* Added LUA_NTYPES #define. (Sol)
* Added lua_getmethods(). (Sol)
* Added lua_getdefaultmethods(). (Sol)
* Added lua_setmethods(). (Sol)

lapi.c:

* Implements lua_getmethods(). (Sol)
* Implements lua_getdefaultmethods(). (Sol)
* Implements lua_setmethods(). (Sol)

lcode.*:

* Added a case for the new VINDEXEDMETHOD type in luaK_dischargevars().
* Added function luaK_selfmethod().
* Added function luaK_indexedmethod().

ldebug.c:

* Added functions travtable() and travmethods().  (Sol)
* In function getname(), a travmethods() call has been added.  (Sol)

lgc.c:

* Function marktable() has been upgraded to check the methods table.
(Sol)
* markobject() has been upgraded to wander user data's methods.  (Sol)
* checkMbuffer() has been fixed to compile under VC6.

lbaselib.c:

* Added function luaB_methods().  (Sol)
* Default method tables are created.  (Sol)

liolib.c:

* File method table created.  (Sol)

lmathlib.c:

* Number method table created.  (Sol)

lstrlib.c:

* String method table created.  (Sol)

llex.*:

* In luaX_lex(), the cases for a . (period) and : (colon) have been
upgraded
  to check for > (greater than) symbols following.

lobject.h:

* The struct Udata has a Table* methods member added.  (Sol)
* The struct Table has a Table* methods member added.  (Sol)

lopcodes.*:

* Upgraded to handle the new opcodes OP_GETMETHOD and OP_SELFMETHOD.

lparser.c:

* Function luaY_methodsfield() added.
* In primaryexp(), cases for TK_COLONGT and TK_PERIODGT have been added.

lparser.h:

* VINDEXEDMETHOD enum added to expkind.

lstate.c:

* In function f_luaopen(), method tables are built into the global
state.  (Sol)

lstate.h:

* struct global_State has Table* methods[LUA_NTYPES] array added.  (Sol)

lstring.c:

* luaS_newudata() assigns the default userdata method table.  (Sol)

ltable.c:

* luaH_new() assigns the default table method table.  (Sol)
* In function newkey(), settableval() was fixed to compile under VC6.

ltm.*:

* Functions luaT_getmethods() and luaT_setmethods() added.  (Sol)

lvm.c:

* Function luaV_getmethod() added.
* Virtual machine opcodes OP_GETMETHOD and OP_SELFMETHOD implemented.

-Josh



Reply | Threaded
Open this post in threaded view
|

Re: unified methods

Edgar Toernig
In reply to this post by Joshua Jensen
Joshua Jensen wrote:
>
> And, for what it is worth, here is an implementation of a "method table"
> using tags in the current LuaState distribution:

Just for completion, the Sol version ;-)  (and some comments)

-----Sol version-----
require "classes"  -- only thing to know: Table=methods({})

methodTable = Table:class {  -- inherit methods from Table (append, ...)
	function func(self)
		print("Hi", self.a)
	end

	function func2()
		print("Hi")
	end
}

methodTable2 = methodTable:class {  -- inherit methods from methodTable
	function func3(self)
		printf("Hello", self.b)
	end
}

myTable = methodTable { a=5 }  -- create instance
myTable:func()
myTable:func2()		-- passes myTable, but how cares? ;->
-- rational: you have to write (myTable:func2)() but Sol does not
-- allow () as the start of a statement.  But this is ok:
--   x = (myTable:func2)()
-- anyway, a method that doesn't take a self (static class function?)
-- shouldn't be called via an instance.  this should be used:
--   methodTable.func2()
-- or, going back to a "PS:" of one of my previous posts:
--   myTable:this_class.func2()


myTable2 = methodTable2 { a=10, b=20 }

function myTable2.func(self)	-- an instance's private function
	print("In myTable2.func()", self.b)
end

methodTable2.func2()	-- actually redirected to methodTable by inheritance
-- x = (myTable2:func2)()  would work too, but see comment above.
myTable2.func(myTable2)	-- yes, this one has to be handcoded...
myTable2:func()
myTable2:func3()
-----------------------------

IMHO, having 4 different field access operators is confusing!
I could understand that one want's another operator to preserve backward
compatibility.  So make it '->' (will give the minimum confusion) and mark
the ':' as "for compatibility use only" (remember, it was ment as a method
operator to give OO look'n'feel in the first place).  I think that you won't
need it very often anyway.  And about your fourth one see the comments in
the code above.

Ciao, ET.

Reply | Threaded
Open this post in threaded view
|

Re: unified methods

RLak-2
In reply to this post by John Belmonte-2


[hidden email] escribió una vez:
> >
> > As I understand it from the correspondence (and no doubt Edgar will
correct
> > me if I'm wrong), in his unified methods implementation,
> >
> > a:foo(x)
> >
> > is "syntactic sugar" for:
> >
> > methods(a).foo(a,x)
> >
> > where methods(a) is some sort of metamethod, I would guess.

y replicó Edgar Toernig <[hidden email]>:

> It's a low level function that extracts the associated method table
> that _each_ object has (it's a field in the low level data structures).
> You can set it with methods(x, table).


> > (Or perhaps it works recursively, which might be cool if confusing.)

> Of course.  methods(methods(x)) works well and is actually used in Sol's
> class system:

Umm, that's iteratively, not recursively. But it's still cool :-)

> methods(x) is the "class table" that describes what can be done with x.
> method(method(x)) is the "super class table" that describes what can be
> done with "class tables" (creating instances and subclasses, perform
> inheritance, ...).  And the "super class table" itself is a regular table
> with no fancy features so methods(methods(methods(x))) is the same as
> methods({}).  Confusing, isn't it ;-)

Yup, a little. I would have thought that methods(methods(methods(x))) would
be the same as methods(methods(x)), but that's probably because I'm
thinking in another language. (that is, if classes are themselves
first-class objects then the class of any class should be Class, and
therefore the class of Class is Class, so you should reach a fixed point in
the iteration.)

What I meant by recursive was the method(x) might itself be a method so one
could define an object which represented class tables in some other manner
(perhaps computing them on the fly) using the unified method equivalent of
a getclassmethod tag method.

> > Another alternative would be for
> >
> > a:foo
> >
> > to be "syntactic sugar" for:
> >
> > curry1(methods(a), a)
> >
> > where curry1 is a language primitive

> Actually, the ':' is the low level primitive to access the method table.
> Where a.x access field x from a, a:x access field x from methods(a).  So
> this is valid:

> a:x = a:x + 1
> a:x:y.z = 42
> a:x = function(...)...end
> function a:x(...)...end

> The syntactic sugar comes in when a:x is used as for a function call.
> In that case, a self is automagically added as the first argument.  To
call
> a method without inserting the object as arg1 you have to use
parenthesis.

I'm not sure that I'm crazy about that. But I understand the motivation. I
assume that when you say "you have to use parenthesis", you mean something
like:

(a:x)(b, c)


> >[...]
> > a<<x>>         is defined as  getmethod_event(a, x)
> > a<<x>> = v     is defined as  setmethod_event(a, v, x)
> >
> > Taking this additional step makes the optimisation referred to above a
> > little harder to do, since we can no longer rely on a->x returning a
curry.

> Actually, for Sol's first version I really started to introduce a
> getmethod and setmethod event for this (and indexmethod and newmethod).
> Put I dropped it pretty fast.  While it allows you to differentiate how
> the access to a table is done it introduces much too much complications
> and inconsistencies.

Interesting... I'll have to think about it some more...

> You get all these fancy features with a 3 level architecture as described
> above (object, class table, super class table).  When you try to read a:x
> you check the gettable and index methods for a's method table; it's a
> regular table after all, so why not check it's index/gettable method
> when a field is requested?  So a:x invokes Super.index(a,x) if x is not
> present (Super is the super class table) or even Super.gettable(a,x)
> for every x if Super.gettable is present. [1]

That makes sense. In fact, I have somewhere kicking about some C code which
pretty well does that without altering the grammar of Lua (however without
altering the grammar of Lua you can't divide namespaces, so it's really
only practical for userdata).

The catch is the "automagic" of a:x(..) which is pragmatic but a bit odd.
The solution I presented is probably more complicated to implement
efficiently, but involves less magic. Or at least different magic. Anyway,
it was neither an implementation nor a fully-thought-out concept, just an
idea so I won't argue for it.

Have you looked at NewtonScript at all? Or even AppleScript? (AppleScript
is/was(?) one of the great undersold ideas that came out of that benighted
company; NewtonScript has its own charm, too.) Much earlier than Chash, and
in common I think with some other OO implementations, NewtonScript
implemented a really interesting method/field inheritance structure which
allowed one to build up individual and idiosyncratic objects without
incurring huge overheads (particularly memory, given the context in which
it was intended to run).

R.


Reply | Threaded
Open this post in threaded view
|

RE: unified methods

Peter Prade
In reply to this post by Edgar Toernig
> IMHO, having 4 different field access operators is confusing!
> I could understand that one want's another operator to preserve backward
> compatibility.  So make it '->' (will give the minimum confusion) and mark
> the ':' as "for compatibility use only" (remember, it was ment as a method
> operator to give OO look'n'feel in the first place).  I think
> that you won't need it very often anyway.

I have to agree on the confusion arising from all the operators!
Used so far in this thread: . : .. :: -> .> :>
Ouch! what about ;) :-> and  .-> ?? *g*

but why use another operator at all?
it should be easy to provide backward compatibility with appropriate
methods, or am i missing something?
so you can stick to . and :

Regards,
Peter


Reply | Threaded
Open this post in threaded view
|

RE: unified methods

Joshua Jensen
In reply to this post by Edgar Toernig
> Just for completion, the Sol version ;-)  (and some comments)
> 
> methodTable2 = methodTable:class {  -- inherit methods from 
> methodTable
> 	function func3(self)
> 		printf("Hello", self.b)
> 	end
> }

This is a great approach.  Just cross your fingers that nobody ever
removes the function class() from the method table!  :)

> myTable = methodTable { a=5 }  -- create instance
> myTable:func()
> -- anyway, a method that doesn't take a self (static class function?)
> -- shouldn't be called via an instance.  this should be used:
> --   methodTable.func2()

Or possibly just:

methods(myTable).func2()

> IMHO, having 4 different field access operators is confusing!
> I could understand that one want's another operator to 
> preserve backward compatibility.  So make it '->' (will give 
> the minimum confusion) and mark the ':' as "for compatibility 
> use only" (remember, it was ment as a method operator to give 
> OO look'n'feel in the first place).  I think that you won't 
> need it very often anyway.  And about your fourth one see the 
> comments in the code above.

I am in agreement with this and the confusion.  I see, then, the need
for 3 operators.

myTable.func()                       -- No implicit self.
myTable:funcWithSelf()               -- Implicit self passed.  Backwards
compatible, but still useful.
myTable->methodTableFuncWithSelf()   -- Implicit self passed through to
a method table function.
      Which is the same as:
           methods(myTable).methodTableFuncWithSelf(methods(myTable))
and
           methods(myTable):methodTableFuncWithSelf()

And from Peter's response:

>I have to agree on the confusion arising from all the operators!
>Used so far in this thread: . : .. :: -> .> :> Ouch! what about
>;) :-> and  .-> ?? *g*

Hey, the more smileys you can build into your code, the better!  :)

>but why use another operator at all?
>it should be easy to provide backward compatibility with
>appropriate methods, or am i missing something? so you can stick
>to . and :

Another operator is necessary to keep code looking simple and existing
code behaving the same.  In the case of:

myTable->methodTableFuncWithSelf()   -- Implicit self passed through to
a method table function.
      Which is the same as:
           methods(myTable).methodTableFuncWithSelf(methods(myTable))
and
           methods(myTable):methodTableFuncWithSelf()

The use of the -> operator hides the [ methods(myTable): ].  Plus, there
is no question that the method came from the method table at that point.

It would be possible to make the : operator first check myTable and then
methods(myTable), but at the very least, you have the cost of the
myTable hash lookup, which could be a waste of time.  To make the :
operator just look at methods(myTable) would be bad, because it would
break existing code, in addition to not allowing an implicit self to be
passed through to a myTable function (although it's debatable how
important that is).

-Josh



Reply | Threaded
Open this post in threaded view
|

RE: Method Tables - a modified Lua 4.1 Work Beta implementation

Joshua Jensen
In reply to this post by Joshua Jensen
After the discussion with Edgar, I have made a couple changes (see
below).  The amount of modified Lua code is now even less.

-Josh

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

After the discussion about unified methods, I have copied just the
method table code from the LuaState distribution and put it in a clean
Lua 4.1 Work Beta implementation.

Credit for the method tables implementation goes to Edgar Toernig, who
created the method tables for Sol.  Except for the parser changes and
new VM opcodes, this is 100% Edgar's work.

Documentation can be found in the "Unified Methods" and "Standard
Unified Method Callbacks" sections of
http://www.workspacewhiz.com/Other/LuaState/LuaState.html with the
following differences:

* The LuaState :: operator is now gone.
* Due to parser changes in Lua 4.1 Work Beta (as opposed to Lua 4.1
Alpha), it is no longer possible to:

print(4->sqrt())

The modified directories can be found here.  Just do a diff of the
original Lua 4.1 Work Beta code and this code to see the small number of
differences.

http://workspacewhiz.com/Other/LuaState/Lua41BetaWorkMethodTables.zip

Changes:
====================

lauxlib.*:

* Added luaL_openlibintotable() helper function (Sol).

lua.h:

* Added LUA_NTYPES #define. (Sol)
* Added lua_getmethods(). (Sol)
* Added lua_getdefaultmethods(). (Sol)
* Added lua_setmethods(). (Sol)

lapi.c:

* Implements lua_getmethods(). (Sol)
* Implements lua_getdefaultmethods(). (Sol)
* Implements lua_setmethods(). (Sol)

lcode.*:

* Added function luaK_selfmethod().

ldebug.c:

* Added functions travtable() and travmethods().  (Sol)
* In function getname(), a travmethods() call has been added.  (Sol)

lgc.c:

* Function marktable() has been upgraded to check the methods table.
(Sol)
* markobject() has been upgraded to wander user data's methods.  (Sol)
* checkMbuffer() has been fixed to compile under VC6.

lbaselib.c:

* Added function luaB_methods().  (Sol)
* Default method tables are created.  (Sol)

liolib.c:

* File method table created.  (Sol)

lmathlib.c:

* Number method table created.  (Sol)

lstrlib.c:

* String method table created.  (Sol)

llex.*:

* In luaX_lex(), the case for a - (minus) has been upgraded to check for
a >
  (greater than) symbol following.

lobject.h:

* The struct Udata has a Table* methods member added.  (Sol)
* The struct Table has a Table* methods member added.  (Sol)

lopcodes.*:

* Upgraded to handle the new opcode OP_SELFMETHOD.

lparser.c:

* In primaryexp(), the case TK_POINTSAT has been added.

lstate.c:

* In function f_luaopen(), method tables are built into the global
state.  (Sol)

lstate.h:

* struct global_State has Table* methods[LUA_NTYPES] array added.  (Sol)

lstring.c:

* luaS_newudata() assigns the default userdata method table.  (Sol)

ltable.c:

* luaH_new() assigns the default table method table.  (Sol)
* In function newkey(), settableval() was fixed to compile under VC6.

ltm.*:

* Functions luaT_getmethods() and luaT_setmethods() added.  (Sol)

lvm.c:

* Function luaV_getmethod() added.
* Virtual machine opcode OP_SELFMETHOD implemented.



Reply | Threaded
Open this post in threaded view
|

Re: Lua XML Parser (LuaXML-0.0.0)

Jay Carlson
In reply to this post by Paul Chakravarti
"Paul Chakravarti" <[hidden email]> writes:

> I have been tinkering with a native XML parser in Lua for a
> while but ended up leaving it in a 'not-quite completed' state
> over the last couple of months - the recent flurry of XML
> related activity on Lua-L has prompted me to get this working
> and put together an initial release at least to save any
> possible duplication. This is a bit rushed and not as well
> documented as I would like but is relatively robust/compliant
> and certainly usable.

Well, one of my friends keeps on shouting

SHIP
THE
BETA

We still don't know how serious he is about this, but it would make a great
t-shirt.

> Jay's expat based parser would probably be a better choice
> when available however this seems to be pretty reasonable both
> in speed & compliance. It would be good to come up with a
> common event & tree based API which would allow these to
> be used interchangably however.

Yes, absolutely.  I see no reason to lock into a single implementation,
especially when it's so avoidable.

It will be harder to get agreement on the tree API, so I'd suggest we work
on the event-based one first---"Lua SAX"?

expat sets an upper bound on how much functionality we can expect.  For
instance, expat won't distinguish <foo></foo> from <foo/>.

I really like interfaces where you set up callbacks with function
o.callback() end, as you can probably tell from Lua FLTK and Lxp :-)

> Interesting I also had a go at an XML-RPC marshaller &
> unmarshaller and got this to the point of working as a CGI
> server but this implementation isnt as complete as Jay's
> (and quite a lot uglier from looking at the code).

I've implemented a bunch of RPC systems, so this is old hat for me now....

> Hopefully this might be useful - I am happy to take
> suggestions/comments on how to merge this with Jay's
> work if anyone is interested.

I'd rather take *your* suggestions on the merge.  The last serious work I
did with XML was like 2-3 years ago, and I don't use it enough day-to-day to
understand what people need these days to get things done.  At this point,
all I can do is try to offer clever (well, at least I think they're clever)
suggestions on tricks to make the API more Lua-friendly.

BTW, I don't feel particularly possessive of Lxp---other people are welcome
to pick it up, take it over, etc.  XMLRPC I feel possessive of until it's
correct.  :-)

Jay


Reply | Threaded
Open this post in threaded view
|

Re: unified methods

Jay Carlson
In reply to this post by Peter Prade
> I have to agree on the confusion arising from all the operators!
> Used so far in this thread: . : .. :: -> .> :>
> Ouch! what about ;) :-> and  .-> ?? *g*

As a test of a proposed MOO type extension mechanism, we were working out
how a new boolean type would work.  There were a bunch of proposed syntax
choices for true and false, but I think what was decided on was Ken Fox's

(-: true :-)
)-: false :-(

There were some holdouts for :-( false )-: of course.  Sadly, it was never
implemented, even as a test.  But it *was* an unambiguous parse....

Jay


Reply | Threaded
Open this post in threaded view
|

Re: unified methods

Jay Carlson
In reply to this post by John Belmonte-2
"John Belmonte" <[hidden email]> writes:

> Jay Carlson wrote:
>
> > Look, I haven't made up my mind yet about unified methods.  They
> > offer a lot of nice features that seem useful in day-to-day
> > programming.  But it's a significant enough change that I need to
> > think about it, a lot---because it *is* an interesting and thoughtful
> > proposal.
>
> Actually unified methods doesn't offer many features at all.  It's just
> taking Lua's internal tag method system an exposing it as tables (this is
> why Edgar was shocked by your comment about everything-as-tables).  Lua's
> tag method interface is spotty and hard to follow, so unified methods just
> make you think you're getting a whole lot more.  It's an illusion.

Although this post has been overtaken by events, I thought it might be cool
to do this in base Lua 4.0.  Another hour of my life wasted by tag
methods---help help it's SO MUCH FUN TO WRITE THIS STUFF

Jay

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

dofile("tag.lua")

hellotag = Tag.new()

function hellotag.gettable(table, index)
  return "Hello from "..tostring(index)
end

print("hellotag.gettable", hellotag.gettable)

-- had to rename this event from "function" to "func"...
function hellotag.func(...)
  print("hello, world!")
end

hello = {}
hellotag:applyTo(hello)

hello()
print("hello.Jay", hello.Jay)

-- You can get a Tag from any value you're got lying around:

hellotag2 = Tag.fromValue(hello)
print("hellotag == hellotag2", hellotag == hellotag2)

-- Or for existing types:

numtag = Tag.fromValue(1)
numtag2 = Tag.fromValue(2)
print("numtag == numtag2", numtag == numtag2)

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

-- tag.lua

if Tag then return end

local Public, Private = {}, {}
Tag = Public

Private.tagtag = newtag()

Private.tagnum_to_Tag = {}

function Public.new()
  local tagnum = newtag()
  local t = {tag=tagnum}
  settag(t, %Private.tagtag)
  %Private.tagnum_to_Tag[tagnum]=t
  return t
end

function Private.makeOld(tagnum)
  local t = {tag=tagnum}
  settag(t, %Private.tagtag)
  %Private.tagnum_to_Tag[tagnum]=t
  return t
end

function Public.fromTagNumber(n)
  local tag = %Private.tagnum_to_Tag[n]
  if not tag then
    tag = %Private.makeOld(n)
  end
  return tag
end

function Public.fromValue(v)
  local tagnum = tag(v)
  return %Public.fromTagNumber(tagnum)
end

Private.event_set = {
  add="add", sub="sub", mul="mul", div="div", pow="pow",
  umm="umm",
  lt="lt",
  concat="concat",
  index="index",
  getglobal="getglobal", setglobal="setglobal",
  gettable="gettable", settable="settable",
  func="function" -- because you can't say foo.function = bar
}

function Private:applyTo_method(v)
  settag(v, self.tag)
end

Private.method_table = {applyTo=Private.applyTo_method}

function Private.gettable_handler(table, index)
  local method = %Private.method_table[index]
  if method then return method end
  local event = %Private.event_set[index]
  if event then
    return gettagmethod(rawget(table, "tag"), event)
  else
    return rawget(table, index)
  end
end

function Private.settable_handler(table, index, value)
  local event = %Private.event_set[index]
  if event then
    settagmethod(rawget(table, "tag"), event, value)
  else
    rawset(table, index, value)
  end
end

settagmethod(Private.tagtag, "gettable", Private.gettable_handler)
settagmethod(Private.tagtag, "settable", Private.settable_handler)

function Public:copyMethodsFrom(tag)
  for i,v in %Private.event_set do
    settagmethod(self.tag, v, tag[v])
  end
end





Reply | Threaded
Open this post in threaded view
|

Re: unified methods

Edgar Toernig
In reply to this post by Joshua Jensen
Joshua Jensen wrote:
> 
> > Just for completion, the Sol version ;-)  (and some comments)
> >
> > methodTable2 = methodTable:class {  -- inherit methods from
> [...]
> This is a great approach.  Just cross your fingers that nobody ever
> removes the function class() from the method table!  :)

Please note that it's :class, a method from Super!


> Or possibly just:
> 
> methods(myTable).func2()

I consider methods() a low level function that shouldn't be used
for regular programming tasks.


> myTable->methodTableFuncWithSelf()   -- Implicit self passed through to
> a method table function.
>       Which is the same as:
>            methods(myTable).methodTableFuncWithSelf(methods(myTable))
> and
>            methods(myTable):methodTableFuncWithSelf()

Uh, no ;-)   methods(myTable).methodTableFuncWithSelf(myTable)

Using shorter names:
  a->x()   would be   methods(a).x(a)

[But using the colon for this looks much much better! SCNR ;-)]

Ciao, ET.

Reply | Threaded
Open this post in threaded view
|

RE: unified methods

Joshua Jensen
> > > Just for completion, the Sol version ;-)  (and some comments)
> > >
> > > methodTable2 = methodTable:class {  -- inherit methods from
> > [...]
> > This is a great approach.  Just cross your fingers that nobody ever 
> > removes the function class() from the method table!  :)
> 
> Please note that it's :class, a method from Super!

Ah, been a while since I've delved into Sol internals (and honestly, I
don't remember any of this).  I'll have to look closer.

> > methods(myTable).func2()
> 
> I consider methods() a low level function that shouldn't be 
> used for regular programming tasks.

If the :class support is there, then the use of methods() should be
limited.

> > myTable->methodTableFuncWithSelf()   -- Implicit self 
> passed through to
> > a method table function.
> >       Which is the same as:
> >            
> methods(myTable).methodTableFuncWithSelf(methods(myTable))
> > and
> >            methods(myTable):methodTableFuncWithSelf()
> 
> Uh, no ;-)   methods(myTable).methodTableFuncWithSelf(myTable)

My bad...

> Using shorter names:
>   a->x()   would be   methods(a).x(a)
> 
> [But using the colon for this looks much much better! SCNR ;-)]

Than the -> symbol?  Yep, it does.

Josh



Reply | Threaded
Open this post in threaded view
|

RE: unified methods

Peter Prade
In reply to this post by Joshua Jensen
> >but why use another operator at all?
> >it should be easy to provide backward compatibility with
> >appropriate methods, or am i missing something? so you can stick
> >to . and :
>
> It would be possible to make the : operator first check myTable and then
> methods(myTable), but at the very least, you have the cost of the
> myTable hash lookup, which could be a waste of time.  To make the :
> operator just look at methods(myTable) would be bad, because it would
> break existing code, in addition to not allowing an implicit self to be
> passed through to a myTable function (although it's debatable how
> important that is).

i guess i was not clear enough...

i suggest to make the : operator just as in Sol (no additional cost):
o:f() becomes methods(o).f(o)

and then provide a methods() function that in the case it doesn't know
anything about the passed object, switches to "backward-compatibility-mode"
(her comes the additional cost):

function methods(o)
	if not recognized(o) then
		return proxy_table
	end
end

the proxy_table is a table with a tag_method set for gettable:

function gettable_event (table, index)
	return function(self,...) call(self[%index],arg) end
end

so when you write
	o:f(...)
and o isn't registered with the new unified methods,
it is still expanded to:
	gettable(o).f(o,...)
this results in:
	proxy_table.f(o,...)
which is equal to:
	call(o["f"],{...})

which is exactly what you want for backwards compatibility.

granted, there is an additional cost, but only for old code, and not too
bad, i think.

Cheers,
Peter


Reply | Threaded
Open this post in threaded view
|

RE: unified methods

Peter Prade
> function gettable_event (table, index)
> 	return function(self,...) call(self[%index],arg) end
> end
> 
> which is equal to:
> 	call(o["f"],{...})

oops, i lost the self as first parameter with my example.

change the gettable_event to return this instead:
	return function(self,...) self[%index](self,unpack(arg)) end

then
o:f(...)
which is expanded to:
methods(o).f(o,...)
becomes:
o["f"](o,...)

(which now really is what you want for backwards compatibility)

Cheers,
Peter

Reply | Threaded
Open this post in threaded view
|

Re: unified methods

Edgar Toernig
In reply to this post by Peter Prade
Peter Prade wrote:
> 
> so when you write
>         o:f(...)
> and o isn't registered with the new unified methods,

Here's a problem: there's no such thing as "isn't registered".
_Every_ object, even nil, has a method table.

And if there would be something like that, you could get the
"old" behaviour much simpler: just make methods(x) return x.
That is what current Lua does, use the object itself as the
method table.

Ciao, ET.

Reply | Threaded
Open this post in threaded view
|

Re: Lua XML Parser (LuaXML-0.0.0)

Paul Chakravarti
In reply to this post by Jay Carlson
Jay Carlson writes:

It will be harder to get agreement on the tree API, so I'd suggest we work
on the event-based one first---"Lua SAX"?
expat sets an upper bound on how much functionality we can expect.  For
instance, expat won't distinguish <foo></foo> from <foo/>.
I really like interfaces where you set up callbacks with function
o.callback() end, as you can probably tell from Lua FLTK and Lxp :-)

This sounds like a good plan - I would be willing to put some effort
into defining this and modifying both my LuaXML and lxp (if you have no
objections) to support this once we have rough consensus.
The API for LuaXML is loosely based on the expat/sax callback api but
slightly restructured to make the handler code easier - so I think it
meets your criteria (!). To define a handler you can just do something
like -
myHandler = {}
myHandler.starttag = function (t,a) ... end
mtHandler.endtag = function (t,a) ... end
xmlParser(myHandler):parse("<xml>...")
The biggest difference is in text handling where LuaXML will generate a
single callback for the text (optionally ignoring non-significant
whitespace) unlike the expat CharacterDataHandler which can generate
multiple calls.
I dont know if you have had a chance to take a look at the API -
is documented in xml.lua and I would be interested in whether you think
this is the right approach - assuming so I will look at merging in
any changes to allow expat to be used as a backend as well and use this
as the basis of the solution. I should hopefully be able to put something
together this weekend (modulo household distractions).
I'd rather take *your* suggestions on the merge. The last serious work I did with XML was like 2-3 years ago, and I don't use it enough day-to-day to understand what people need these days to get things done. At this point, all I can do is try to offer clever (well, at least I think they're clever) suggestions on tricks to make the API more Lua-friendly.

I dont claim to be an XML expert but in the absence of anyone else am
willing to have a go. I would appreciate any feedback on the LuaXML
code - this is my first attempt to do anything particularly serious in
Lua) Regards, PaulC

Reply | Threaded
Open this post in threaded view
|

Lua Manual

Eric Tetz-2
In reply to this post by Peter Prade
I'm incorporating Lua into a Windows multimedia authoring application.  Soon, I will need to write
end-user documentation for the language.  Lua's manual is geared towards programmers, describing
the syntax in BNF, and making references to the C API throughout.

I was wondering if (a) it would be OK to borrow heavily from this manual in the creation of my own
and (b) if someone has already created an end-user friendly version of the Lua manual.

Cheers,
Eric

__________________________________________________
Do You Yahoo!?
Yahoo! GeoCities - quick and easy web site hosting, just $8.95/month.
http://geocities.yahoo.com/ps/info1

Reply | Threaded
Open this post in threaded view
|

Re: Lua XML Parser (LuaXML-0.0.0)

Jay Carlson
In reply to this post by Paul Chakravarti
> The API for LuaXML is loosely based on the expat/sax callback api but
> slightly restructured to make the handler code easier - so I think it
> meets your criteria (!). To define a handler you can just do something
> like -
>
> myHandler = {}
> myHandler.starttag = function (t,a) ... end
> mtHandler.endtag = function (t,a) ... end
> xmlParser(myHandler):parse("<xml>...")

The way I handled this was to require that myHandler be initialized from a
function call:

myHandler = makeParser()
myHandler.starttag = function (t, a) end
myHandler:parse("<xml>")

But in some ways your solution is superior in that you can build the
myHandler table once and use it for multiple parses, where in mine I have to
add the entries to the table each time I call makeParser().  It's easy
enough to switch back and forth between the styles, I suppose, but you can't
do "for i,v in jaysParser" as jaysParser is userdata---have I mentioned that
I like ExtendingForAndNext?  So it's easier to emulate your style than it is
to emulate mine.

I'm sorry I didn't respond earlier---I got sucked off into spec lawyering on
the xml-rpc list.

Jay


Reply | Threaded
Open this post in threaded view
|

Re: Lua Manual

Luiz Henrique de Figueiredo
In reply to this post by Eric Tetz-2
>I was wondering if (a) it would be OK to borrow heavily from this manual in the creation of my own

Yes, it's ok -- the copyright notice explicitly says that the package includes
the documentation and that the whole package is free. Nevertheless, you should
respect the restrictions listed in the copyright notice: reproduction of
the copyright line, avoid misrepresentation, explicit mark modified versions
as such.

>if someone has already created an end-user friendly version of the Lua manual.

Try the Yindo documentation at http://www.yindo.com/docs/ specially
http://www.yindo.com/docs/GettingStarted.html .
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: Lua Manual

Jim Mathies-2
FYI im working on some additions to GettingStarted. With a little bit of
work you could easily strip out any yindo specific stuff from these docs.
Feel free to use these docs for you own purposes if you find them useful.
I'm targeting Javascript hackers with these, they tend to be "beginners"
when it comes to programming. Hence the very basic starting point.

Regards,
Jim


----- Original Message ----- 
From: "Luiz Henrique de Figueiredo" <[hidden email]>
To: "Multiple recipients of list" <[hidden email]>
Sent: Monday, December 03, 2001 5:19 PM
Subject: Re: Lua Manual


| >I was wondering if (a) it would be OK to borrow heavily from this manual in the creation of my own
| 
| Yes, it's ok -- the copyright notice explicitly says that the package includes
| the documentation and that the whole package is free. Nevertheless, you should
| respect the restrictions listed in the copyright notice: reproduction of
| the copyright line, avoid misrepresentation, explicit mark modified versions
| as such.
| 
| >if someone has already created an end-user friendly version of the Lua manual.
| 
| Try the Yindo documentation at http://www.yindo.com/docs/ specially
| http://www.yindo.com/docs/GettingStarted.html .
| --lhf
| 
| 


123