Re: object system...
- From: "Dmitry A. Kazakov" <mailbox@xxxxxxxxxxxxxxxxx>
- Date: Tue, 13 Jan 2009 10:33:58 +0100
On Mon, 12 Jan 2009 22:50:28 +1000, cr88192 wrote:
"Dmitry A. Kazakov" <mailbox@xxxxxxxxxxxxxxxxx> wrote in message
news:au6iq7quarsb$.196jbwbwvvafi.dlg@xxxxxxxxxxxxx
On Mon, 12 Jan 2009 11:49:12 +1000, cr88192 wrote:
none the less, it is a lot easier to optimize code with loops or
if-then-else, than code written via gotos (optimizing if a given branch
is always true or false, unrolling loops, ...), however it is also the case
that nearly every compiler I am aware of converts over to the use of
gotos fairly early on (and I am not aware of any IL which uses high-level
control flow rather than labels and gotos/jumps...).
[...]
so, yes, although one can use prototype features, they should not, as the
additional overhead costs are high.
Also, in a typed system you do not need to store any specific type
information at run-time. The type tag is needed in only two cases:
1. The object is polymorphic and its specific type is unknown until
run-time
2. The representation of a non-polymorphic object is same as the
representation of a polymorphic object rooted in the specific type of the
former.
The case 2 is usually deployed by when objects are by-reference.
3. when "reflective" abilities are needed, for example, when writing more
code that can use the object outside its original context.
Not in a typed system. You cannot have an object in a context where its
type is unknown. If the type is known, no reflection is needed. [ If we
considered upward closures, which allow objects to propagate out of its
type declaration and pulling the latter with it. That in effect would
eliminate the notion of context, and necessarily make type the first-class
object. In short, this way or another, you do not need reflection in this
form.]
4. when rebuilding the code. in this case, usually the type information is
kept purely as sideband or scaffolding, and once the code is built it ceases
to matter, or at least until more code needs to be built around it..
Same as 3, the context must know the type where an operation on it should
happen. Context /= object /= type.
but, yes, if nearly all of the code can see itself as its own data, it can
utilize itself in building new code and features.
That is self-referential and thus inconsistent. To make it consistent such
systems need to be split into two, neither of which is self-referential.
For example, into interpreter and the code to interpret. For the
interpreter the code is data. The types are still static for the code and
do not need to be known there.
a function which takes abstract data and converts it into code, and converts
this code into native machine code, and then this code can be integrated
with the running app, and with most of it performing just as well as if it
came out of a static compiler...
these can be powerful tools...
But still outside objects. The point is that without a clear separation of
what belongs where, you will get an inconsistent, very inefficient system.
There is no reason why a Boolean object has to carry type description with
it. It is just one bit, there is no place for additional information.
Interface deals with the type, not an object of. As any base type it
adds nothing being a separate type from the result. Inheritance is an
algebraic operation that takes some arguments, like interface, and
produces the result, the type or interface.
we use interfaces against instances / objects, not against classes...
Yes I see. This is what I certainly do not want to have = object of same
type implementing different interfaces! That looks like schizophrenia.
this is common practice though, and actually one of the major uses of
interfaces. well, that and allowing different classes to be used in the
same place (AKA: a poor man's duck typing...).
One does not need to be schizophrenic, it is no problem for an object to
have a type to be a member of many classes. The relationship is:
an object <--1:1--> the type <--1:n---> classes of
An object has exactly one type. Interfaces deal with types not objects. An
interface declares some set of operations defined on some set of values.
It is meaningless to apply this to an individual object. It is like to have 1
integer without 2. How + is supposed to work? Integer interface applies to
all integers.
it applies to an object, which is an instance of a class implementing an
interface...
Object is an instance of its type. It is not an instance of the class
rooted in the type. An instance of the class is the object's type. Other
instances are types derived from it.
it is declared against a class but it uses the instance.
This is another case. If a polymorphic object is declared, then it is an
instance of the type which is a transitive closure of the class. I don't
know which case you mean, polymorphic or a non-polymorphic one.
it is not declared against the instance, nor is it used against the class...
When object is not declared to have a type related to the interface, then
any operation of the interface applied to the object is a type error.
In a consistent strong typed system, you just cannot do these things. That
is the idea of strong typing, not to allow this mess.
class A {
int xi;
...
}
class B1: A {
...
}
class B2: A {
...
}
class C: B1, B2 {
...
}
what of xi in C?...
C *c;
we have c->B1::xi and c->B2::xi, which may potentially have different
state...
if these are separate, then the variable is fragmented, and I originally
thought this was a fault or artifact. now, I realize that this has a few
potential uses...
Right, it makes a lot of sense to leave that to the programmer. The
language shall flag a conflict, and the programmer must resolve it in an
appropriate to hin way. He can say that xi getter/setter pair is to be
overridden in all parents by one pair or else by a set of pairs. There are
lots of combinations, especially when taking into account public/private
views.
I say, the purpose of a higher level language is to get more work done
more effectively, and if this is by hiding or exposing the machine is not
important, only that more work be done, that it be done faster, and that
it be done better...
It cannot be unimportant, because exposing machine prevents some vital
optimizations. For example, if you handle register allocation manually,
you prevent the compiler to do it for you. And with most of optimizations the
compiler will beat you by margin.
That is apart from the issues of code reuse, portability, safety,
maintainability etc.
maybe so, but if there were useful optimizations that could be done here,
almost invariably it would have been done.
This is done in Ada, where use of built-in types is strongly discouraged.
That gives you a lot of optimization unavailable in C. Consider a simple
example:
procedure Foo (A : in out Some_Array) is
subtype Index is Integer range A'Range; -- Constrained to the range of A
I : Index := ...;
...
A (I) := 23;
No index range check here is necessary, because the compiler knows that I
may not be outside the index range of A. It is declared to be inside it.
That the implementation would use a 64-bit hardware integer for it does not
matter.
anyways, it is also the case that in many language specifications, such as
the C standard, it never really says what exact size the types are anyways,
only that they are "at least this big" (little else being said about
representation).
Which makes C programs non-portable. We are developing platform-independent
networking middleware for hard real time (dozens of µs). Surely we do not
do it in C. Ada does not have preprocessor, yet we compile the same code on
different platforms *without* modifications.
When you expose machine types, you cannot describe their semantics in a
machine-independent way, obviously.
doesn't matter when the machines in question implement more-or-less the
same semantics...
How do you define "more or less same semantics?" Computing is discrete,
1+1 is either 2 or else wrong. Does 15326+35221 overflow?
you know... 2+2=5...
whether or not numbers overflow depends on their sizes and other factor.
It depends on the type of. If you lack this information in types you cannot
write a program with defined semantic.
In Ada I write:
type T is range 1..2;
this instructs the compiler to implement a semantics that makes impossible
to assign 2+2 to a variable of the type T.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
.
- Follow-Ups:
- Re: object system...
- From: cr88192
- Re: object system...
- References:
- object system...
- From: cr88192
- Re: object system...
- From: Dmitry A. Kazakov
- Re: object system...
- From: cr88192
- Re: object system...
- From: Dmitry A. Kazakov
- Re: object system...
- From: cr88192
- Re: object system...
- From: Dmitry A. Kazakov
- Re: object system...
- From: cr88192
- Re: object system...
- From: Dmitry A. Kazakov
- Re: object system...
- From: cr88192
- Re: object system...
- From: Dmitry A. Kazakov
- Re: object system...
- From: cr88192
- Re: object system...
- From: Dmitry A. Kazakov
- Re: object system...
- From: cr88192
- Re: object system...
- From: Dmitry A. Kazakov
- Re: object system...
- From: cr88192
- object system...
- Prev by Date: Re: please answer these questions as soon as possible. because i have exam
- Next by Date: A hopefully interesting design question ...
- Previous by thread: Re: object system...
- Next by thread: Re: object system...
- Index(es):
Relevant Pages
|