Re: object system...
- From: "cr88192" <cr88192@xxxxxxxxxxx>
- Date: Sat, 10 Jan 2009 15:22:23 +1000
"H. S. Lahman" <h.lahman@xxxxxxxxxxx> wrote in message
news:tKP9l.4733$BC4.1847@xxxxxxxxxxxxxxxxxxxxxxx
Responding to cr88192...
I'm afraid that is just not true. See my response to Riemenschneider. Cnot always the case.It's true that they aren't *designed* to be slower. But the price ofI disagree. General purpose languages of xGL are not desined toIf yes, then you are wrong, because there are even no one OOThere is no 3GL that provides perfect performance;
language
with perfect perfomance.
for that you need machine language.
decrease performance of previous (x-1)GL.
abstraction is performance. Any nontrivial C program with be 30-50%
slower than hand-tuned Assembly. Any C++ program will be 50-200%
slower than the C program.
C is usually fairly comparable to "mundane" assembly...
isn't even as fast as other systems programming languages.
yes, but then again, one can debate then what is "mundane" assembly...
OK. But somewhere along the line I specified "hand-tuned Assembly" as the
context of my comments.
yes, and I was talking about mundane assembly...
now, the main difference is one of scope:
hand-tuned assembly is very fast, but can usually only be produced in tiny
amounts by any "average" human...
to produce much more, the efficiency drops sharply due to human mental
limitations, and it becomes mundane assembly...
so, the solution is to use C and C++ for most things, and confine ASM mostly
to small parts they want to go fast.
or, in my case, lots of misc things, because were as my assembler can
convert fragments to machine code very fast, my C compiler can't.
an idea I have had is to add a few features to my RPNIL compiler to make it
more usable for hand-written fragments and macro-based composition (my
"macro" features if effect consisting of PS-like blocks and the addition of
a few limited interpreter-like features...).
actually, the addition of blocks, bindings / 'def', 'if', and making blocks
execute when loaded from references (technically, I will just try to compile
them inline). all the other actual "interpreter" parts will be a side-effect
of some of my existing features for optimizing the submitted RIL (it tries
to evaluate things at compile time if it can do so, only emitting ASM output
if an operation can only be performed at runtime, but if one limits
expressions to compile-time types, then this can be used as a plain
expression evaluator...).
well, anyways, the point is that RIL could be a good tradeoff between C and
ASM wrt run-time code generation (C-level semantics without all of that
preprocessor and parser crap getting in the way and making it slow...). RIL,
unlike CIL or JBC, is also "human readable"(1) and possible to type in its
raw form...
1: it is textual yes, but also can be compared to an uglier form of
PostScript which was even less intended for actual humans to use, and was
even only textual because that was less effort for my compiler to produce (I
find composing bytecode directly to be a hassle, and so used a textual
format so that it was more convinient to compose via a "printf"-like
API...).
much of the time, C++ is performance competitive with C (assuming ofThe only conceivable situation where this would be true is when one is
course that the C and C++ code operate similarly, for example, the C++
code looks like C, or the C code uses an object-based approach).
using C++ as a "Better C". In that situation one essentially has a C
program with strong typing and is not using any OO constructs more
complicated than a simple Class.
yes, this is actually what I meant...
in the case where one uses C++ almost exactly the same as C, the compiler
output is usually very similar...
OK. Not surprising since C++ was originally developed as a preprocessor
for C (cfront). In addition, Stroustrup's stated design goal was to enable
high performance. Unfortunately the thing he sacrificed for that was
OOA/D.
But this is an OO forum. Using C++ as a Better C is just bad OO
development. Effectively one is just doing C development so one would
expect comparable results.
well, technically, I do many things far worse than "bad OO"...
but, most often, one of the more major concerns is how fast something goes.
all manner of elegance or abstraction can be sacrificed for speed, but speed
may be sacrificed for convinience (so long as it is a minor speed cost for a
major convinience gain).
and, the common consensus of so many separate "agents"?... C, C++, Java, and
C#...
there are many other cases where "abstraction" can be leveraged to theThe very best an optimizing compiler could possibly do is write code
advantage of the compiler writer, allowing the production of more
efficient code than would have been produced otherwise.
a simple example of this would be compiler provided complexes or
vectors, where a compiler may be able to leverage the capabilities of
the processor (such as specific opcodes for vector handling, ...), and
thus generate faster code than would happen if the coder were to just
write a big mass of scalar code.
that is exactly as fast as that produced by a competent Assembly
developer. But the compiler can't understand the specific problem being
solved. So there will always some problem solutions where the Assembly
programmer can beat the optimizer by tailoring the Assembly to that
specific problem. Been there; done that.
The only reason those cycle-counting Assembly gurus are a vanishing
breed is that it takes them too long to do it. So the economics drives
putting money into optimizing compilers that *usually* do *almost* as
good as the Assembly guru.
yeah...
but, alas, this is back to the issue of said guru consistently applying
optimization, which is slow and requires lots of thinking.
the compiler does it faster, and a coder when faced with a larger problem
will usually resort back to slow-ass approaches (and/or huge amounts of
copy/paste).
the usual approach then is to do most of the codebase in a language like
C or C++, and only fall back to ASM when needed for performance reasons
(so, we use ASM for some tight vector-math code, but not for things like
the windows event callback, ...).
Right. It is a matter of economics, not computer science.
yeah.
but, the point was, for example, in C is it more efficient to make use of
the compiler-provided complexes (such as the "float _Complex" type), or
hand-write ones' own complexes using scalars, function calls, and
structs?...
in general, this compiler provided abstraction, will somewhat beat out
the performance of doing it manually.
for example:
c=a*b;
I can remember when one always wrote
x = a + a + a
instead of
x = 3 * a
because the FORTRAN compiler was too dumb to realize that a multiply
instruction took at least an order of magnitude more cycles than an
addition. B-) Those were the Good Old days when programmers were Real Men.
But I digress...
yep...
I actually use a similar trick in a few places, because there are still
cases (especially with 64 and 128 bit types) where doing a short chain of
additions or subtractions, is much faster than resorting to the helpers
associated with doing multiplications or divisions:
on x86 and long-long, mul is inline, but div is a helper (actually, ll/int
can be done inline, but ll/ll needs a helper), and for int128, both are
helpers (both of which I will probably need to port to x86-64, but
int128*int128 can probably be inline on x86-64, likely as an almost direct
adaptation of the x86 ll*ll sequence...).
may generate a chunk of specialized x87 or SSE instructions, but:
c=myapiMulComplex(a, b);
involves the function call overhead, the cost of copying the structs
around on the stack, much less efficiently crafted ASM output (since the
compiler may lack most of the context from the caller), ...
I'm not talking about the application developer providing better code.
(You could do this with a BLISS macro, though, as I explained elsewhere
and it would be inline.) I am talking about what the compiler does with
the constructs the language defines.
If the language provides abstract constructs like OO generalization to
solve routine problems, then the compiler will not be able to write
Assembly code that will run as fast as that of an experienced Assembly
programmer solving the same problem.
yes, true.
Similarly, if one uses a 4GL with abstract action language for things like
relationship navigation, the transformation engine cannot produce C++ code
that will be as fast as an experienced C++ programmer could produce
solving the same problem directly.
But the transformation engine will be close enough to the C++ programmer
and the C++ compiler will be close enough to the Assembly programmer so
that economically the 4GL will win hands down over manual C++ development
and manual C++ will win hands down over manual Assembly development.
yes...
none the less one may continue doing development at all levels, much like a
kind of tower...
in my case, I consider it more in this latter sense, or more specific,I figured that out when I realized you were a type maven. B-)
as in the sense of "interface" as used in languages like Java or C#...
?...
You believe an interface defines what an object is. B-)
at least as far as the code is concerned...
but, alas, I tend to have difficulties with many things that people believe
to both "exist" and "not exist", and then the whole issue of "existence"
becomes damn confusing if one looks into it (a partial reason why me and
philosophy don't get along so well...).
so, I see the world as I see the world, trying to be careful not to fall
down the rabbit hole...
as well, if I try to describe the world as I see it from down in this hole,
then people promptly seem to think I am insane or similae. or, at least, I
get accusations of doublethink...
so, yeah, better to stay clear and let other people deal with philosophy it
seems...
so yes, as far as I consider it, the "physical" aspects of code are what are
"real" (the particulars of the implementation, APIs, classes and interfaces,
specific patterns and rules of usage, ...).
something then becomes "real" once it is built (or at least sufficiently
specified), but until then, it does not exist as far as I am concerned.
granted, specifications are sufficient, as they are a kind of faux reality
that one can build things around, and then once the structures exist (in the
form of written and working code), they have become "real" as well and then
one can build more structures and specifications on top of them...
however, as I have found, I have been pitifully unable to operate in
situations where I can't do this (I am almost incapable of "top down"
thinking, or of planning or designing things apart from considering
everything I already have...).
so, this is a practical hinderance of a similar nature to my philosophical
hinderance...
and so prove incapable at things like game design, ...
I also fail at actually managing to make anything happen in my life, like
whatever happens, everything goes on just as before, and it can cause doubt
that it is possible to actually "achieve" anything (or, at least, anything
much beyond the reach of my pre-existing approaches, which seem to just
"grab at the air" when it comes to "life issues"...).
and so, people may make jokes that I sit around all the time categorizing
and systemizing everything in life, rather than actually "living" life, ...
meanwhile, all my time is going to waste on this front... it is lame...
???and, some of us really value conventional value types as well...So "interface" defines all logical properties of its abstractionAh. I see. You are a type maven. B-) So we need a little primer here
(what
to do): responsibilities, access, protocols (sequences of usage) etc.
The dividing between interface ("what to do") and implementation
("how to do") is artificial, not natural of nature, but anyway
"object" never can "define its responsibilities", because "object" is
an instance of interface.
on OOA/D.
Types do not even exist in OOA/D (other than knowledge ADTs). OOA/D is
based on class systems rather than type systems. The 3GL type systems
are a compromise with the hardware computational models. As a result
they do not reflect a number of fundamental OO design issues.
this seemed like you were advocating dispensing with any of the built in
value types, and instead implementing "everything" as a class instance
(implying then, for example, that numerical types are pass-by-reference,
have methods, ... and that operations produce new instances of the
class).
Au contraire. for example, the computing space is full of things like
String, Array, Stack, etc. that are essentially just data holders. As a
result they are ubiquitous in object *implementations*.
But they are tactical solutions so one is not very interested in them at
the OOA/D level. So they tend to appear as scalar ADT knowledge attributes
in the design and one only gets interested in the details during OOP.
oh, ok.
usually, this quickly leads to a "slippery slope" of horrible performance
(and the garbage collector going berserk...).
even then, as I see it, even if the performance impact is avoided (value
types are implemented normally, but just fake having a class), I don't
feel this to be an ideal design (our built-in value types just don't need
huge masses of methods).
I am much more inclined to think of implying a generic manipulation to a
type, and not of having operactions be a method of the type.
so, I would much rather type:
sin(PI/2);
than:
(PI/2).sin();
even if it were possibly the case that the above were, in some cases,
implemented as a piece of syntactic sugar. such as no generic 'sin'
function existing, but the language having a trick to allow methods to be
called on an object following the same syntax as an ordinary function
call.
however, such a trick could lead to potential semantic issues (such as,
what is 2 'sin' functions exist, with one inside the object, but the
other in the caller's scope...).
class Foo
{
Foo foo_add(Foo this, Foo that);
}
'this' as a method argument implying that the method be called as if it
were a function accepting itself...
or whatever...
Wow. You and Kazakov really should get out more. B-) You need to get out
of the mud of 3GL type systems and smell the OOA/D roses where none of
this stuff matters. (More precisely, it matters to a different trade
union, like compiler or transformation engine designer, rather than the
application developer union.)
ok.
For example, in the MDA profile I use for OOA modeling, the entire
abstract action language syntax for describing behaviors is described
adequately in two pages and the UML elements used could be described in
another five pages (only a small subset of UML is necessary). That is, the
level of abstraction is high enough so that the notation syntax is so
simple that nuances such as yours simply don't arise.
ok.
Yet the models are rigorous enough that they can be executed to validate
that functional requirements have been resolved properly. (In translation
systems it is common practice to apply the same test cases for functional
requirements to the OOA models that one applies to the final executable;
just the test harness changes.)
yes, ok.
well, I code the way I code, with the things and information I have
available.
if I can't easily see the code and systems in use, then it proves difficult
to imagine...
The use of "call" here is very telling. One of the problems with 3GLThe most important such issue in this thread context is the separationyes, this is typically the case, but not always the case...
of message and method. Because 3GLs all employ procedural message
passing there is no distinction; the message is simply the procedure
signature. Since we name procedures by what they do, the message
becomes a very specific imperative to do something (Do This).
Unfortunately, that implies that the sender of the message knows (A)
that the receiver exists, (B) that the receiver does something
specific, and (C) that doing it is the next thing to do in the
solution. All of those things trash OO encapsulation and
implementation hiding because it makes it easy to construct the sender
so that it depends on what the receiver does.
for example, it is possible to implement a declarative API in terms of
linear calls, where each call serves to inform the callee of the next
element in the structure, rather than telling it what to do about it.
type systems is that they are married to procedural message passing.
That invites one into a procedural Do This view of the solution as a
sequence of operations to be decomposed. That leads to the hierarchical
dependencies of the legendary Spaghetti Code. The OO paradigm strives to
eliminate those hierarchical dependencies. But because of the 3GL type
system compromises the way one must do that is with a different mindset
towards design, not OOPL programming.
So it doesn't matter how the interface is defined. The critical mindset
for OO development is that an interface only defines messages, not
operations. Once one has that mindset, one can construct objects without
worrying about sequences of operations and messages can be announcements
(I'm Done) rather than procedural imperatives (Do This). That allows one
to connect the dots for flow of control later by routing messages.
oh, ok...
yes, I think I know what you are getting at now, only that this
particular style is often difficult in C apart from making dependency
issues worse (either the creation of bi-directionally dependent APIs, the
ugly use of lots of callbacks, ...).
I don't see it as a language issue. C++ was originally a preprocessor for
C so one can always get to an equivalent procedural representation.
(Translation transformation engines routinely do this going from an OOA
model to C, Assembly, or even MS Word documentation.) More to the point,
you don't need to implement OOA/D constructs literally. For example, when
implementing generalization the OOPLs apply a lot of baggage around
virtual jump tables because they need a general implementation of the
construct that includes things like polymorphic dispatch, implementation
inheritance, and complex constructors. But for a specific problem OOA/D
most of its generalizations can be implemented with a couple of nested
structs.
Also the business rules and policies from the problem space that dominate
the dynamics are going to get encoded pretty much the same way in C, C++
or an AAL. Thus everybody uses the same arithmetic, logical, and bitwise
operators while gluing them together with the same sort of expression
syntax. That's because in the end software is about computation and we've
had many centuries of experience describing algorithms.
yes...
sort of reminds me of last time I tried formalizing English grammar and
semantics into a reduced and "computationally accessible" subset. people may
well be building the tower, but are not yet up to the level I think, where
things like the semantics of natural languages can (even in a formalized
version) be made effectively computationally accessible (the use for
something like this being for automated dialog construction, being able to
emulate to a certain extent human reasoning ability, ...).
not that I would be trying to solve general AI problems (like, making
computers actually "understand" things), rather, things like "deductive
reasoning" could be useful programming constructs, in a manner similar to
how objects are a useful construct.
however, there are still many missing parts...
So I think the OOness is really a mindset issue. It is about how one
*organizes* the software. In an OO context we are concerned with
dependencies and coupling so we define little puddles of code in a fashion
that minimizes dependencies and coupling. To do that we have
methodological crutches like problem space abstraction, encapsulation,
implementation hiding, separation of message and method, yadda, yadda,
yadda.
yep...
As an example of what I mean, I recall an article for the '70s that
compared various Structured methodologies. Advocates of each methodology
actually solved a real problem and the results were compared. The
interesting conclusion was that all but one of them looked remarkably
similar. The odd man out was produced from Michael Jackson's JSD
methodology, which looked very different from the other solutions even
though it used all the same diagrams as everyone else.
it is probably because he walked the graph backwards...
The reason was that Jackson was ahead of his time because a lot of his
design techniques were very similar to later OOA/D methodologies even
though he had no notion of an 'object'. Thus he set great store in notions
like cohesion, functional isolation, API encapsulation, subject matters
extracted from the problem space, and whatnot. Though he didn't articulate
it the same way, he clearly had an understanding of coupling issues and
the problems of hierarchical dependencies in functional decomposition.
The bottom line is that one could take his design, update it for modern
UML bells & whistles, and one would be hard pressed to see how it differed
from good OOA/D practice today. But Jackson was a Structured Programming
guy, not an OO guy. Yet he somehow incorporated OO-like ideas in a
procedural design.
yes, ok.
So I would expect basically the same bubbles & arrows to be used in the
design (most of the UML diagrams are thinly veiled diagrams from
Structured Programming like DFDs) and the same syntactic elements in the
3GL when doing OOA/D/P. But I would expect the way boundaries were defined
and the way program units were organized to be quite different than in a
procedural development.
I think I mentioned that if one gets the OOA/D right, then the fact that
the OOPL marries message and method does not matter. That's because the
mindset of the OOA/D will prevent the message sender from hierarchically
depending on the message receiver before one ever gets to OOP. So the
compromises in the OOPLs become benign.
So I don't think one needs anything special in the way of syntax or
implementations. Recording an OO design in an OOPL will be easier but an
OOPL isn't a necessary condition for implementing the design. IOW, the
difference will lie not in the way one accesses program units but in the
content of the program units.
yes, ok...
well, in my case, I don't graph or diagram anything.
actually, on the large scale, I don't design anything either.
rather, I create components, refine them as needed, and often split them
when they become too large or complex (usually then, an API is designed for
one side, for the other, or both...) or when a natural "break" begins to
emerge (this being a place where interdependencies between one side and the
other begin to weaken as the code mutates, and so an API can be designed and
used as a "wedge" to drive the thing apart).
sometimes, if I am aware of existing standards or APIs, I will implement
them as they are described (usually on one side), but they will be connected
to other APIs or subsystems on the other.
sometimes, if two APIs exist that have sufficiently similar functionality, I
may just try to fuse them together in terms of their internals (or, in some
cases, make the functionality of both available via the same API).
other times, theoretically similar but otherwise different things may be
forced together forming a kind of "chimera" (my object system is this way,
as it actually implements 2 rather different styles of OO within the same
system, and so can look like either one depending on how a piece of code
decides to use it).
elsewhere, a wrapper exists, so the same object system is available via JNI
if for some reason one wants to use JNI instead (actually, they are similar
enough that it is a fairly thin wrapper, almost a 1:1 correlation in most
places...).
IOW, one does not think about sequences of operations (calls) until the
very last thing one does in an OO design. Nor does one think in terms of
one object doing something for another object. One designs object
methods in complete isolation from the solution context. It is only in
the DbC context of connecting the flow of control dots that one thinks
about contracts in terms of 'client' and 'service'. But then the
'client' is quite generic; it is *some* object that accesses the
service, not a particular object.
well, this is different...
It's classic OOA/D. Every OOA/D book I've seen starts with the static
description: objects, relationships, responsibilities. And every OOA/D
methodology I know stresses abstracting the *intrinsic* nature of the
problem space entity in terms of self-contained, cohesive
responsibilities.
Different authors put different wrappers on it. So Jacobson's designs are
driven by use cases and he has a special classification of objects while
Rebecca Wirfs-Brock's designs are driven by roles. But under the hood they
all abstract the problem space to provide static structure first and they
all advocate defining intrinsic properties. Flow of control and DbC
contracts (if used; a lot of authors just supply guidelines for
collaboration in Sermon On The Mount mode) are dealt with only after one
has all the ducks already on the pond.
To use my Tinker Toy analogy, one identifies which colored wheels
(objects) one needs and makes sure they have the right sockets
(properties) first. Then one connects them up to form a useful shape
(solution) by connecting them with spokes (messages). Thin as analogies
go, but cute.
yes, I guess this works a lot better if one designs the whole system in a
top down manner, rather than first doing lots of coding and then watch as a
system gradually starts to assemble itself from the mass of continuous
activity...
parts are duplicated, parts are modified and occasionally rewritten, and
eventually parts may die off (often because they are either useless or their
functionality gets taken up by something else), ...
granted, as the programmer, I design and implement each part and make any
changes I might decide to make, but the overall system design is not
something I really plan.
I am personally unable to keep the whole thing in memory at the same time,
so often I usually jump from place to place, refreshing memory by looking
over any docs or code I have left around, and making improvements or fixes
(as well as designing and implementing new features, ...).
I am also fairly good at skimming over and absorbing a lot of information
from the codebases of other projects, and am usually at least decently
capable of recreating anything of interest I saw along the way (but tend not
to like much of the code I see, most of it all looking like big tangled
messes...). (often I just sort of quickly scroll through a bunch of the
files from various parts of the codebase and have a "sense" of how it all
works, which usually transforms fairly easily into a piece of code that does
the same thing).
also usually fairly good at recreating code from APIs, behaviors, or
descriptions (what code will pull off the various behaviors as stated?...
well, I might have a vague sense, and just start writing whatever I am
thinking, and then it forms itself for me...).
but, sometimes it is difficult to have a complete "sense" of something large
and complicated, like, say, the entirety of ECMA-335 (it is a little bit
lacking over the sections describing the metadata representation, ...).
I guess, if I were to describe it, it could be compared to like a
"highlighter" or "fluid" which just sort of "glows" around various ideas,
and if one looks at a brightly glowing area, it just sort of "explodes" into
a whole bunch of new ideas and stuff (or, sometimes will just start
manifesting ideas on its own, but usually on random topics often not much
related to my main line of thought...), and one can then just sort of write
down most of what shows up.
it is also usually fairly good at determining what will work well and what
will not, and can be combined with mental simulation, ... as a way of
determining what the best possible design is likely to be, ...
ok, all this is a crappy description, but yeah...
but, alas, this kind of "sense" is not something I have been able to emulate
in code... (nor can either "I", or it itself, introspect its workings...).
if I get burnt out though, it tends to go largely away, and then my coding
output is reduced...
"I" am located elsewhere in my mind... much closer to the area which goes
about evaluating rules and information retrieval (this area of my mind tends
to be much more "sterile"...).
but, alas, this "sense" falls fairly flat if one tries to use it on "life
issues"...
Third, objects are not assembled into larger structures; that is much
more of a functional programming concept. There are only three basic
levels of abstraction in an OO application: subsystem, object, and
responsibility. The elements at each of those levels are peers and they
collaborate (send messages to one another) directly as peers. They are
logically indivisible at the containing level of abstraction. The only
"structures" one can form are through relationships (e.g., a GoF
Composite pattern).
ok, it may depend that I have a good deal of exposure to FP as well, and
so my thinking and coding practices often mix together FP and OO
approaches (along with good old imperative and procedural approaches,
...).
<Hot Button>
Alas, FP and OO approaches are vastly different -- so much so that the
approaches are fundamentally incompatible. Thus FP is inherently
hierarchical while a major goal of the OO paradigm is to eliminate such
hierarchies. FP militantly rejects persistent state while it is critical
to the OO paradigm. Those two things alone make the approaches
fundamentally incompatible.
I switch between whatever approaches best achieve the desired results...
One advantage FP has is that it is much more intuitive in a computational
environment. So you don't see a lot of FP design books because almost
everyone already knows how to do functional decomposition. Meanwhile there
is a steep learning curve for OO and one really can't do it properly
without following an OO design methodology.
OO methodologies are synergistic in that lots of things play together so
that the whole design approach is better than the sum of the parts. The
problem with that is that it is rather fragile because a lot of different
things have to play together. So when one tries to Mix & Match practices
from different methodologies one can break the synergy so that things stop
playing together well. Then one may end up with a hybrid methodology that
has none of the benefits of either of the source methodologies.
yes, ok.
So I get very nervous whenever someone starts suggesting things like
making functions first class objects or using composition inheritance to
create hybrid objects. Those things aren't in the OO paradigm because they
don't play together well with the elements that are already there. Doing
that sort of thing tends to break the synergy of the OO paradigm and one
loses the the key benefit: maintainability.
hmm...
so, you don't like C# delegates then?...
Both the OO paradigm and FP work very well in meeting their respective
goals. But if one tries to hybridize them I believe there is great risk
that none of the goals will be achieved satisfactorily.
</Hot Button>
well, both are sort of added on top of C in my case anyways, and both have
things they do well...
but, alas, I have never really been one for "large scale" design, more just
designing and implementing individual parts and then assembling them into
things later...
--
Life is the only flaw in an otherwise perfect nonexistence
-- Schopenhauer
H. S. Lahman
H.lahman@xxxxxxxxxxx
software blog: http://pathfinderpeople.blogs.com/hslahman/index.html
.
- Follow-Ups:
- Re: object system...
- From: H. S. Lahman
- Re: object system...
- References:
- object system...
- From: cr88192
- Re: object system...
- From: H. S. Lahman
- Re: object system...
- From: Grizlyk
- Re: object system...
- From: H. S. Lahman
- Re: object system...
- From: Grizlyk
- Re: object system...
- From: H. S. Lahman
- Re: object system...
- From: cr88192
- Re: object system...
- From: H. S. Lahman
- Re: object system...
- From: cr88192
- Re: object system...
- From: H. S. Lahman
- object system...
- Prev by Date: Re: object system...
- Next by Date: Re: object system...
- Previous by thread: Re: object system...
- Next by thread: Re: object system...
- Index(es):