[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Re: Still cryptic OOP syntax
- From: David Olofson <david@...>
- Date: Mon, 31 Jan 2005 03:20:39 +0100
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
> 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
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
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
> > 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
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
" is the number. 9".
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 ---