The African Chief wrote:
Sounds reasonable. So should we just change "asmname" to "name"? Or keep both?
I think we should keep both. "Asmname" is intuitive, but "name" is good for Delphi compatibility.
Besides, removing "asmname" would break some existing programs (including a published one of mine)...
- [a] a Class instance becomes a pointer to the class; (or is it that the Class itself is a pointer to an object/class?);
I think the latter would be a more consistent interpretation (at least for us, even if Delphi does it otherwise). So "class" = "pointer to object", approximately...
e.g., "Var Foo : MyFoo" = "Var Foo : ^MyFoo" in the current OOP model
Saves declaring those "PFoo" types, OTOH makes it impossible to declare global or local objects variables (without the overhead of allocating memory). If we have objects and classes, the programmer can choose what (s)he prefers.
[b] the constructor does the heap allocation stuff, e.g., "Foo := MyFoo.Create" *allocates memory for Foo "(New, Foo)" *calls Foo^.Create (constructor)
So it's the same as "Foo := New(MyFoo, Create)" in BP? Why not! Shorter to type, perhaps easier to read (once one gets used to not looking for "New").
What about destructors? Does Delphi still use "Dispose", or has it another syntax too, or does it dispose of objects automatically. (C++, BTW, does the latter. It destroys e.g. local objects at the end of the function automatically. This is possible because in C++ every class has exactly one destructor. I guess they set the pointer to nil automatically at the beginning (and set it back to nil if the destructor is called manually), so they can easily find all local objects that "exist" and destroy them.)
*Foo now points to whatever "Foo.Create" - should generate an exception because Foo needs to be assigned to the constructor
AFAICS, calling a second constructor does not even have to be forbidden -- at least in gpc. Constructors can be called like normal methods from an initialized object, though this is certainly uncommon practice.
[c] deference it automatically; e.g., "Foo.Bar := 12" (instead of "Foo^.Bar := 12")
This reminds me of C++'s "reference types" (not only for objects, but for any types). I.e., a pointer internally, but dereferenced automatically when necessary. I think they could be quite useful sometimes, anyway, and if they'll be implemented (syntax?), we'd have "class" = "reference to object"...
- Allow virtual constructors (or at least, don't reject the
"virtual" directive in a "Class" constructor's definition)
AFAIK, this is planned, anyway.
- Virtual methods to be overridden must be overriden
with the "override" directive; the "virtual" directive merely creates a new method (or at least, don't reject the "override" directive in a "Class" definition)
Does this mean you have to use "virtual" for *every* method in Delphi, or what is meant by "create a new method"?
- Allow "Published" methods (or at least, don't reject the
"published" directive in a "Class" definition).
Is this the same as "public" in C++ (= visible to everyone)? I, personally, would prefer "public", "protected" (=visible only to descendants) and "private" (=visible only to the type/class itself -- BTW, BP does it a bit differently, and extend the visibility of private methods to the whole unit it's declared in. I don't see any reason or advantage of this). So, perhaps we could allow all those keywords, including "published", in any order, also possibly repeated (unlike BP).
- All classes to have the same ultimate ancestor object.
The same discussion as with objects recently... ;-) Is this really necessary (if so, for what?), or is it sufficient if all classes in a given library use the same ancestor by convention?
3-Jul-97 01:13 Frank Heckenbach wrote:
- Virtual methods to be overridden must be overriden
with the "override" directive; the "virtual" directive merely creates a new method (or at least, don't reject the "override" directive in a "Class" definition)
Does this mean you have to use "virtual" for *every* method in Delphi, or what is meant by "create a new method"?
In Delphi you can declare a method 'virtual' or 'dynamic' and when you want to override it in an descendant class, you must do it with 'override' directive.
- Allow "Published" methods (or at least, don't reject the
"published" directive in a "Class" definition).
Is this the same as "public" in C++ (= visible to everyone)? I, personally, would prefer "public", "protected" (=visible only to descendants) and "private" (=visible only to the type/class itself -- BTW, BP does it a bit differently, and extend the visibility of private methods to the whole unit it's declared in. I don't see any reason or advantage of this). So, perhaps we could allow all those keywords, including "published", in any order, also possibly repeated (unlike BP).
In Delphi there are four such directives:
public - like in BP - visible for everyone private - like in BP - visible only for this unit (I don't see any advantages too) protected - visible for this class and its descendants published - same as public, but also accessible at the design time (in Object Inspector) - I don't program Delphi, but as I remember only properties were placed here.
- All classes to have the same ultimate ancestor object.
The same discussion as with objects recently... ;-) Is this really necessary (if so, for what?), or is it sufficient if all classes in a given library use the same ancestor by convention?
I think it's only needed for Delphi compatibility, where TObject is the ultimate ancestor of all objects. Perhaps another compiler switch (for Delphi compatibility)?
-- Marius Gedminas E-mail: mgedmin@pub.osf.lt WWW: http://www-public.osf.lt/~mgedmin
On Thu, 3 Jul 1997, Frank Heckenbach wrote:
The African Chief wrote:
I think the latter would be a more consistent interpretation (at least for us, even if Delphi does it otherwise). So "class" = "pointer to object", approximately...
e.g., "Var Foo : MyFoo" = "Var Foo : ^MyFoo" in the current OOP model
Delphi does do it otherwise as in this example
type
TMyObject = Class(TObject) . .
var VarMyObject : TMyObject;
Saves declaring those "PFoo" types, OTOH makes it impossible to declare global or local objects variables (without the overhead of allocating memory). If we have objects and classes, the programmer can choose what (s)he prefers.
Delphi does not allocate memory for object variables untill the object is actually created with its create method.
[b] the constructor does the heap allocation stuff, e.g., "Foo := MyFoo.Create" *allocates memory for Foo "(New, Foo)" *calls Foo^.Create (constructor)
So it's the same as "Foo := New(MyFoo, Create)" in BP? Why not! Shorter to type, perhaps easier to read (once one gets used to not looking for "New").
This is also how Delphi works, again;
VarMyObject := TMyObject.Create;
What about destructors? Does Delphi still use "Dispose", or has it another syntax too, or does it dispose of objects automatically. (C++, BTW, does the latter. It destroys e.g. local objects at the end of the function automatically. This is possible because in C++ every class has exactly one destructor. I guess they set the pointer to nil automatically at the beginning (and set it back to nil if the destructor is called manually), so they can easily find all local objects that "exist" and destroy them.)
Delphi has two methods for object destruction, Free and Destroy. However, Free is what should always be used. It deallocates memory etc. and calls destroy only if the object is not nil. This provides a safer, cleaner destruction of the object.
- All classes to have the same ultimate ancestor object.
The same discussion as with objects recently... ;-) Is this really necessary (if so, for what?), or is it sufficient if all classes in a given library use the same ancestor by convention?
In Delphi, the common object ancestor (TObject) provides the most basic methods and properties that ALL objects need (creation, destruction, etc.). These are the methods/properties that are unlikely to be overridden (its rare that you would need a different destructor for example) and having a common ancestor provides the programmer with a ready to go foundation for his/her objects. I think a common ancestor is the right way to go.
Larry Carter lcarter@powerslave.jf.intel.com
On Thu, 3 Jul 1997, Larry Carter wrote:
- All classes to have the same ultimate ancestor object.
The same discussion as with objects recently... ;-) Is this really necessary (if so, for what?), or is it sufficient if all classes in a given library use the same ancestor by convention?
In Delphi, the common object ancestor (TObject) provides the most basic methods and properties that ALL objects need (creation, destruction, etc.). These are the methods/properties that are unlikely to be overridden (its rare that you would need a different destructor for example) and having a common ancestor provides the programmer with a ready to go foundation for his/her objects. I think a common ancestor is the right way to go.
When I actually started to think about this, I realized how this could be a problem. In Delphi, this commmon object works great becuase it provides all the basic machinery neccessary for all objects, however, this is machinery that is specific to the Intel running Windows environment, the memory model etc. An object of this type in GPC would probably be very bloated, making all its decedants bloated, becuase of all the different environments it would have to handle. Perhaps a library of foundation objects for each OS?? Especially since this really has little to do with the compiler itself anyway! :)
Larry Carter lcarter@powerslave.jf.intel.com
On Thu, 3 Jul 1997, Larry Carter wrote:
type
TMyObject = Class(TObject)
var VarMyObject : TMyObject;
Can someone also tell me what are those "class of" types??? Like this:
type TMyObject = class(TObject) ... end;
TMyObjectSomething = class of TMyObject;
What's that for?
Pierre Phaneuf
"The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offense." - Edsger W. Dijkstra.