lua-users home
lua-l archive

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


On Monday 31 January 2005 01.42, skaller wrote:
[...]
> However the idea would not be to replace the existing
> type dispatch mechanism, just encapulate it in a *single*
> function eg: to add two things toegether call 'add' function.
> Just one function for all types.
>
> That function would have to do the 'try doubles, if not
> try metamethods' that  the bytecode interpreter does right now.

I see. That's pretty similar to what I just did in EEL, except I have 
only one function for all operators and all types. As it is, that 
function cannot be replaced, but that would be trivial to implement. 
It would also be trivial (and possibly slightly faster) to split it 
into one call for each operator - which would make it a whole lot 
more interesting to do what you suggest; allow that function to be 
replaced. It should also be pretty easy to add a user hook in the 
error handling, so you can add operators that are note built into the 
core.


> This would simplify the core, slow down processing due
> to the indirection, and make things extensible,
> since you can replace the 'add' function.

Dunno if it would slow things down all that much, actually... Calls 
through function pointers are slightly slower, but switches and other 
conditionals aren't exactly free either. A "nice" switch statement 
becomes some arithmetics, one or two bound checks and jump through an 
indexed table, and I don't think that's much faster than an explicit 
jump through a table of function pointers. (Note that the dispatching 
conditionals in a VM tend to be impossible for any CPU to predict due 
to the scale of things, so they become *very* expensive, especially 
on modern deep pipelining CPUs.)


> The add function itself could also be designed to
> be extensible, for example using a multi-dimensional
> array as you suggest, would allow adding new
> addition submethods without changing the actual add
> function.

Considering the amount of code needed to implement a single operator 
just for a few simple tupes and an object fallback, I think that 
would be more or less required to make the feature practically 
usable... *hehe*

I was actually planning on using one big array of function pointers at 
first; one call for each type/operator/type combo, driven directly 
from the VM. (You could of course point a bunch of those pointers at 
the same function, if you have a catch-all for 
some_type/some_operator/<anything> or whatever.)

But, for some (more or less valid) reasons, I decided it was easier to 
do it in a gigantic switch()... Whether or not it was a good idea, I 
got a ~12% total *speedup* after that refactoring job (*), and it 
does the job, it's easy to hack, and I'm in too much of a hurry right 
now to do any further research, so it'll do for now. :-)

(*) ...which means EEL actually beats Lua in some benchmarks now,
    despite my really rather stupid compiler! ;-D In the grand
    total though, I still need some +50% or so to be on par with
    Lua.


[...]
> > The problems gather when you get to operations on objects...
> 
> Of course. It's impossible. This is the covariance
> problem I referred to in another post.
> 
> YOu need n^2 routines for n types, which doesn't fit
> into the n methods OO allows... this kills OO as a
> programming methodology with a one line argument.
> 
> Time to move on.. :)

Well, that's a minor problem, the way I see it. (As the designer of a 
language + implementation.) If a bunch of metamethods per class isn't 
the right tool, I'll just use something else.

The problem is how to actually implement each operation. I can hook 
the implementations up to the VM one way or another, but I need to 
have them first. It's no problem inside the core, with a "small" set 
of types, but encapsulation goes out the window already at that 
point.

Alternatively, one has to figure out various high level interfaces and 
wrap everything, slowing any non-core types down to a crawl as soon 
as they interoperate with core types. It would be über kewl to figure 
out some way around that problem, but I guess it's pretty much 
impossible without implementing some sort of "operator definition 
language" that compiles to native.


Now that I think of it, I'm actually doing something like that with 
the "voice mixers" in Audiality. There are 6 quality levels, mono 
samples, stereo samples, 8 and 16 bit samples and two "output 
structures" (single send and dual sends), so there's a total of 48 
inner loops - but I only actually coded 6 of them. I guess that idea 
could be taken much further.

Still, it might be hard to export this outside the core. Need to think 
more about this...


> > The second major problem with operations on objects is when doing 
> > things like
> > 
> >  v = 1 / v;
> > 
> > Now what? 
> 
> You need a method
> 
>  div: float * vector -> vector

Yep, no way around that, really.


> so look it up in the table, if you can't find it
> give a runtime error, otherwise apply it.

Yeah. For now, it's hardwired to a runtime error for all objects, as 
there are no reverse versions of any metamethods. (Yet.)

The VM reverses commutative and "swappable" operators and calls the 
forward metamethods, though. Switching to a huge LUT would lose that 
feature, but I'm not sure that's a Bad Thing...

Actually, I think I found a sleeping bug! :-D If you implement an 
operator <string> ADD <integer> which concatenates the string 
representation of the integer to the string, you'd not get what you 
expect if you type something like

 s = 9 + " is the number.";

the VM would see that the left hand operand is not an object and apply 
the normal ADD operator of the right hand operand instead - which 
results in

 " is the number. 9".

*hehe*

Another argument for dropping the operator metamethods altogether and 
just have the classes register "detached" operators for relevant 
type/operator/type combinations. As it is, *all* operators need both 
forward and revers metamethods for everything to work as intended 
without ugly hacks. :-/


//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
|  Free/Open Source audio engine for games and multimedia.  |
| MIDI, modular synthesis, real time effects, scripting,... |
`-----------------------------------> http://audiality.org -'
   --- http://olofson.net --- http://www.reologica.se ---