Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Straight Question: Object Pascal with Generics?

61 views
Skip to first unread message

Barry Kelly

unread,
Mar 24, 2001, 4:38:44 PM3/24/01
to
Will we ever see an Object Pascal with support for compile-time
polymorphism?

Will we ever see explicitly instanciated templates in Object Pascal?

Will Object Pascal ever be as type safe as C++?

***

OK, so that last question was designed to provoke, but I believe the
statement "C++ is more type-safe than Object Pascal", and I feel VERY
strongly about this subject.

Every use of TList implies static typecasting.
Every use of a static typecast is a lost compiler type-checking opportunity.

C++ has typed containers through the use of templates. C++, when used
properly, is more type-safe than Object Pascal, but is far less readable.

***

I'm worried that the people in charge of compiler development direction in
Borland think that interfaces are the solution to all problems generic.

I think that compile-time checking is safer than run-time checking.

Generic programming using interfaces cannot provide compile-time checking
(see note 1 below).

Therefore, I think that generic programming using interfaces is inferior to
generic programming using explicitly instanciated (templates | units).

---
Note 1: what I mean is that a library of containers cannot be written which
have "an insertion constraint that forces insertions to be descendants of a
base class" at compile time.

***

I hope and pray I'm wrong. I look for signs that there are others of my
slant inside Borland.

As of Kylix, Object Pascal supports operator overloading - a double-bladed
sword, which can enhance readability or increase potential for obfuscation.

Operator overloading only works on variants, and I suppose it works using
hooks that must have been there since late-bound method calls on a variant
were implemented.

This can only be type-checked at run-time. This isn't good enough.

***

My language is extreme because my feelings are extreme. My frustration grows
daily, and the barrier of C++'s obfuscated syntax slowly becomes more
appealing than watching a pretty language like Object Pascal slowly slide
down a sad sideroad, becoming more like a scripting language by the day.

There is a ray of hope in C#: not because I'll use it, but because it has
been designed to provide generic programming (something missing in Java),
and just maybe, Microsoft will bring the competitive pressure to bear that
will push Java to adopt it. Then Object Pascal would be lonelier; and then
it might move.

***

Don't rush to say "but Object Pascal can do ... too". The point isn't
capability, but maintainability, ease of use, reduction in error rate.

I'm looking for hope. Show it to me. Show me that Borland has the long-range
vision to invest in generic compiler technology. It won't be a bullet point
for web development, a checkbox for database interaction, a feature to
impress corporate bosses looking for buzzwords and hype. It's not immediate
profits, it's a long-range thing.

SOAP. Kylix/Linux. WebSomethingOrOther. DatabaseExSomething.
InternetSomethingElse. I'm sure they mean a lot more to you than they do to
me; to me they're just marketing words for programming interfaces.
Interfaces that could benefit from generic support; and implementations
smaller, easier to develop, more type-safe too.

Show me that Borland isn't building its future on hype.

Thanks for reading.

-- Barry
barry_...@hotmail.com

William Meyer

unread,
Mar 24, 2001, 6:41:23 PM3/24/01
to
"Barry Kelly" <barry_...@hotmail.com> wrote in message
news:3abd13e3_2@dnews...

>
> Will Object Pascal ever be as type safe as C++?
>
> ***
>
> OK, so that last question was designed to provoke, but I believe the
> statement "C++ is more type-safe than Object Pascal", and I feel VERY
> strongly about this subject.

Wow! Never thought I'd hear that claim. The pervasive use of DWORDs in C++
where a pointer type should be used is the bane of my existence.

Bill


Frederick C. Wilt

unread,
Mar 24, 2001, 7:20:51 PM3/24/01
to
Answers:

1. I sure hope not.

2. Templates are basically code generation. If you think OB needs them write
a preprocessor and sell it.
I have a very usable set of container classes that requires me to override
only two methods and these are one-liners. If I wanted to it would be
trivial to create a Wizard that would generate the code for me.

3. You have got to be kidding right?
--
Regards, Frederick C. Wilt

Deborah Pate (TeamB)

unread,
Mar 24, 2001, 8:01:46 PM3/24/01
to
<<Frederick C. Wilt:

3. You have got to be kidding right?
>>

Not at all. Rudy wrote a great post on this in .discussion
yesterday you might like to read.

--
Deborah Pate (TeamB) http://delphi-jedi.org

Use Borland servers; TeamB don't see posts via ISPs
http://www.borland.com/newsgroups/genl_faqs.html


Barry Kelly

unread,
Mar 24, 2001, 8:16:31 PM3/24/01
to

"Frederick C. Wilt" <fcw...@mindspring.com> wrote in message
news:3abd3914_1@dnews...

> Answers:

Opinions, rather, I hope :)

> 1. I sure hope not.

I think you're wrong. I can't hope to convince you until you are specific
about

> 2. Templates are basically code generation.

Don't let a bad implementation damn a concept; and don't confuse templates
with generic programming.

Templates <> generics. Templates are an (ugly) implementation of generic
programming. Generic programming can be accomplished in OP with interfaces.
But not with compile-time type checking.

> If you think OP [better?] needs them write


> a preprocessor and sell it.

I've written a preprocessor. However, a preprocessor

> I have a very usable set of container classes that requires me to override
> only two methods and these are one-liners. If I wanted to it would be
> trivial to create a Wizard that would generate the code for me.

Run-time type-checking <> compile-time type-checking. If you like run-time
type checking, you should be happy with JavaScript, Perl, etc.

> 3. You have got to be kidding right?

No.

P.S. I'd appreciate some context to what exactly you reply to. Underquoting
can be as bad as overquoting.

-- Barry
barry_...@hotmail.com

Barry Kelly

unread,
Mar 24, 2001, 8:06:42 PM3/24/01
to
"William Meyer" <wme...@earthlink.net> wrote in message
news:3abd3099$1_2@dnews...

> "Barry Kelly" <barry_...@hotmail.com> wrote in message
> news:3abd13e3_2@dnews...

> > OK, so that last question was designed to provoke, but I believe the


> > statement "C++ is more type-safe than Object Pascal", and I feel VERY
> > strongly about this subject.

> Wow! Never thought I'd hear that claim. The pervasive use of DWORDs in C++
> where a pointer type should be used is the bane of my existence.

Unreformed programmer, by the sounds of it.

Programming languages don't prevent bad programming.

They can facilitate clean design, maintainability, and compile-time
checking, though.

Any non-trivial application that does more than GUI widget-manipulation will
need to work with structures of varying complexity, or else use a component
written by someone else that does said manipulation.

Object Pascal containers, in the effort to be flexible, usually work with
Pointers, Variants, Interfaces or TVarRec (array of const). They are not
type-checked at compile time.

C++ standard library containers use implicit and explicit templates to
provide genericity. These are type-checked at compile time.

-- Barry
barry_...@hotmail.com

William Meyer

unread,
Mar 24, 2001, 8:41:20 PM3/24/01
to
"Barry Kelly" <barry_...@hotmail.com> wrote in message
news:3abd44a1_1@dnews...

> > Wow! Never thought I'd hear that claim. The pervasive use of DWORDs in
C++
> > where a pointer type should be used is the bane of my existence.
>
> Unreformed programmer, by the sounds of it.

Likely so. And MS influenced, no doubt.

> Programming languages don't prevent bad programming.
>
> They can facilitate clean design, maintainability, and compile-time
> checking, though.

They can't prevent bad programming, but they can encourage good practice
(making it easy to do) and discourage bad practice (making it difficult.)
Block-structure, for example, discourages bad practice, but does not prevent
it. A block may still contain hundreds of lines of code, and will therefore
prove unmaintainable, in any rational sense.

> Any non-trivial application that does more than GUI widget-manipulation
will
> need to work with structures of varying complexity, or else use a
component
> written by someone else that does said manipulation.

Of course. And the complexity will usually be reduced by increasing
structure, establishing a hierarchy of structure, for example, and by
diligent application of the practices suggested by Fowler, Beck, and the
Gang of Four.

> Object Pascal containers, in the effort to be flexible, usually work with
> Pointers, Variants, Interfaces or TVarRec (array of const). They are not
> type-checked at compile time.
>
> C++ standard library containers use implicit and explicit templates to
> provide genericity. These are type-checked at compile time.

Not being expert in C++ (or even close to it) I cannot argue the issues of
template use. What I can say, however, is that I have seen very little
written in C++ (or about C++, for that matter) which exemplified clarity of
thought or presentation. Not having read huge amounts of C++, it is possible
I have merely been subjected to bad examples.

On the other hand, I have found in practice, that I am not at a loss for
solutions to the problems I have faced in OP, nor that the lack of
type-checking in OP containers has proved to be the source of bugs in my
finished apps.

In fairness, however, I will grant that our views are shaped by the tools
which become our favorites.

Bill


Barry Kelly

unread,
Mar 24, 2001, 9:13:01 PM3/24/01
to
"William Meyer" <wme...@earthlink.net> wrote in message
news:3abd4cb6$1_1@dnews...

> "Barry Kelly" <barry_...@hotmail.com> wrote in message
> news:3abd44a1_1@dnews...

> > Programming languages don't prevent bad programming.


> >
> > They can facilitate clean design, maintainability, and compile-time
> > checking, though.
>
> They can't prevent bad programming, but they can encourage good practice
> (making it easy to do) and discourage bad practice (making it difficult.)
> Block-structure, for example, discourages bad practice, but does not
prevent
> it. A block may still contain hundreds of lines of code, and will
therefore
> prove unmaintainable, in any rational sense.

Non-trivial object pascal programs force either hard casts or dynamic casts.
Dynamic casts check only at run-time. Hard casts aren't good practice.

Therefore, object pascal forces bad practice. <g,d&r>


> > Any non-trivial application that does more than GUI widget-manipulation
> will
> > need to work with structures of varying complexity, or else use a
> component
> > written by someone else that does said manipulation.
>
> Of course. And the complexity will usually be reduced by increasing
> structure, establishing a hierarchy of structure, for example, and by
> diligent application of the practices suggested by Fowler, Beck, and the
> Gang of Four.

Consider: would you agree bugs will be reduced by reusing existing tested
code, especially for containers with interesting characteristics. Said
existing tested code, in some library somewhere, must either use run-time
type checking, or force multiple manual overrides. What if the library is
upgraded? Overriding a container class's relevant methods to force
compile-time type checking won't automatically detect new methods.

My point is that this can be automated, with reduced probability of bugs,
with enhanced maintainability, with sheer less text, by allowing some kind
of generic programming.

Come, you must agree! <g>

> Not being expert in C++ (or even close to it) I cannot argue the issues of
> template use. What I can say, however, is that I have seen very little
> written in C++ (or about C++, for that matter) which exemplified clarity
of
> thought or presentation. Not having read huge amounts of C++, it is
possible
> I have merely been subjected to bad examples.

Don't damn the concept because of a flawed implementation. You agree that
Object Pascal is a clearer language than C++? Then you must agree that
generic programming with an Object Pascal syntax would be clearer than C++
templates, yes? So what is the problem beyond ugliness, which can answered?

Can you see the benefits? Come, you *must* agree with me!

> On the other hand, I have found in practice, that I am not at a loss for
> solutions to the problems I have faced in OP, nor that the lack of
> type-checking in OP containers has proved to be the source of bugs in my
> finished apps.

From my original post:

<<Don't rush to say "but Object Pascal can do ... too". The point isn't
capability, but maintainability, ease of use, reduction in error rate.>>

Don't you see the benefits?

> In fairness, however, I will grant that our views are shaped by the tools
> which become our favorites.

It is an oft-used truism that language shapes the way we think. Like 1984's
newspeak, designed to prevent the expression of illicit thoughts, too small
a language lexicon can prevent you from seeing other approaches to the same
problem.

Broaden your mind, and see the barriers that you have set yourself. Look at
Ada, particularly the section with stuff that Pascal doesn't have (link by
Deborah Pate): http://members.nbci.com/gdemont/pascada.htm.

> Bill

I hope I can convince you that you haven't finished your education <g,d&r>.
Learn more languages; you'll learn about the deficiencies of Object Pascal.
Then, from the benefits of contemplating other approaches, choose the best -
and ask for them in Object Pascal.

Good luck,

-- Barry

William Meyer

unread,
Mar 24, 2001, 9:35:31 PM3/24/01
to
"Barry Kelly" <barry_...@hotmail.com> wrote in message
news:3abd542d_1@dnews...

>
> Non-trivial object pascal programs force either hard casts or dynamic
casts.
> Dynamic casts check only at run-time. Hard casts aren't good practice.

I've yet to see any C++ without some hard casts, either.

> Therefore, object pascal forces bad practice. <g,d&r>

As C++ forces the use of some very ugly syntax (low readability = bad
practice).
Back at ya <g>

> My point is that this can be automated, with reduced probability of bugs,
> with enhanced maintainability, with sheer less text, by allowing some kind
> of generic programming.
>
> Come, you must agree! <g>

Nah, that would make it too easy on you. <g>

> Don't damn the concept because of a flawed implementation. You agree that
> Object Pascal is a clearer language than C++? Then you must agree that
> generic programming with an Object Pascal syntax would be clearer than C++
> templates, yes? So what is the problem beyond ugliness, which can
answered?

I don't damn the concept. I stipulated earlier to insufficient knowledge of
the (seemingly endless) intricacies of C++ to argue from a position of
expertise. and yes, OP is clearer, IMO, than C++, in all cases I have seen.
But bad practice can make either language unreadable and unmaintainable.

> Can you see the benefits? Come, you *must* agree with me!

LOL! Keep trying.

> <<Don't rush to say "but Object Pascal can do ... too". The point isn't
> capability, but maintainability, ease of use, reduction in error rate.>>

Agreed, and I did not rush to say that. I merely speak from my own
*experience*, not conjecture. My experience is shaped both by the tools I
use, and by the problem domain in which I work (a factor which is sometimes
overlooked by some in these ngs.)

> Don't you see the benefits?

Again, lack of experience with the feature makes it a tough sell. If you've
a clear example to offer, that might help. Remember, though, that clarity of
expression (or rather, the infrequency with which I have seen it, in C++) is
a major concern.

> It is an oft-used truism that language shapes the way we think. Like
1984's
> newspeak, designed to prevent the expression of illicit thoughts, too
small
> a language lexicon can prevent you from seeing other approaches to the
same
> problem.

Too small is a value judgment which may not be valid. I would contend that
the C++ lexicon suffers from the failure of the committee to say no. too
much baggage, in the name of not breaking existing code. Hmmm... the same
problem which afflicts windows, to a great degree <g>.

> Broaden your mind, and see the barriers that you have set yourself. Look
at
> Ada, particularly the section with stuff that Pascal doesn't have (link by
> Deborah Pate): http://members.nbci.com/gdemont/pascada.htm.

Looked at ADA years ago. Played with it. Saw things to like, and things to
dislike. In chief, what was likable was IMO due to the dominance of a single
architect in formation of the language. A major negative feature, again IMO,
was the involvement of the DOD.

> I hope I can convince you that you haven't finished your education
<g,d&r>.
> Learn more languages; you'll learn about the deficiencies of Object
Pascal.
> Then, from the benefits of contemplating other approaches, choose the
best -
> and ask for them in Object Pascal.

Hell, as long as I am breathing, I will at least try to keep learning. I
started in hardware design when RTL was mostly gone, and DTL was going away
(thank all the Gods!) The first CPU I studied closely was the Intel 4040. As
to the tools, so long as Windows is the platform on which I work, Delphi is
the tool of choice. VC is a (sometimes) necessary evil. VC ups the ante on
unreadibility and bad practice, IMO.

But as to demanding features in Delphi, I prefer to focus first on improving
my own practice, then on improving my utilization of what is already
available in the tool. When I am confident that I have plumbed the limits of
Delphi and OP, I may be inclined to fight for extensions to OP. However, if
getting the benefit of templates leads to incurring any of the features of
C++ which I truly despise, I will pass.

It's important to me that Delphi remain lean and fast, and that OP remain as
compact as possible consistent with achieving good practice in light of
current advances in our understanding of programming techniques.

Bill


Barry Kelly

unread,
Mar 25, 2001, 12:02:00 AM3/25/01
to

I wrote:

> using namespace std; // NOTE B

"Sanity clause? There is no sanity clause!"

Here's that missing NOTE B:

Namespaces fill in for C++'s lack of modularization beyond 60's
preprocessors. I'm putting in a general using declaration to free up the
syntax from some clutter.

Now, I wonder what happened to NOTE A.... <g>

-- Barry

Barry Kelly

unread,
Mar 24, 2001, 11:53:24 PM3/24/01
to
"William Meyer" <wme...@earthlink.net> wrote in message
news:3abd5969_1@dnews...

> "Barry Kelly" <barry_...@hotmail.com> wrote in message
> news:3abd542d_1@dnews...

>> Non-trivial object pascal programs force either hard casts or dynamic
casts.

> I've yet to see any C++ without some hard casts, either.

C++ has more expressive casts than Delphi. Very seldom is a C-style cast
needed, which is pretty much what the standard Pascal cast is.

> > Therefore, object pascal forces bad practice. <g,d&r>
>
> As C++ forces the use of some very ugly syntax (low readability = bad
> practice).
> Back at ya <g>

Of the most commonly used programming languages I've known, C++ has the
worst syntax I've ever seen, except for Perl.

I don't think C++ is a good language. However, I can see it has features
that Object Pascal doesn't - and I think Object Pascal would be improved if
it took some of them up, with lessons learned. Templates, which is a
type-aware macro preprocessor in C++, are a bad idea, especially with
implicit instantiation (i.e. no warning when a new version of a function /
class is created with a new type), IMO - but genericity can *AND SHOULD* be
implemented by other means.

>>....must agree!


> Nah, that would make it too easy on you. <g>

<aside, to the Dark Lord>This one is tough, Master...</aside> <g>

> I don't damn the concept.

Cool.


> > <<Don't rush to say "but Object Pascal can do ... too". The point isn't
> > capability, but maintainability, ease of use, reduction in error rate.>>
>
> Agreed, and I did not rush to say that. I merely speak from my own
> *experience*, not conjecture.

Excellent.

> My experience is shaped both by the tools I
> use, and by the problem domain in which I work (a factor which is
sometimes
> overlooked by some in these ngs.)

Object Pascal & Delphi as a tool are given by the newsgroup title; problem
domain is not. Lack of unity in problem domain leads to lack of focus in
discussions to accomodate features of said problem domains.

>> Don't you see the benefits?
>
> Again, lack of experience with the feature makes it a tough sell. If
you've
> a clear example to offer, that might help. Remember, though, that clarity
of
> expression (or rather, the infrequency with which I have seen it, in C++)
is
> a major concern.

You're right, of course; the concept clouded by stuttering speech, a tragedy
of miscommunication. I'll speak some C++, and hopefully you'll follow.

---8<---
#include <iostream>
#include <vector>
#include <algorithm>

template<class Iter>
void AddSomeItems(Iter iter) // (1)
{
for (int i = 0; i < 10; i++) // (2)
*iter++ = i; // (3)
}

int main()
{


using namespace std; // NOTE B

vector<int> myVec; // (4)

// add some items
AddSomeItems( // (6)
back_inserter(myVec) // (5)
);

// print out items
copy( // (7)
myVec.begin(), // (8)
myVec.end(), // (9)
ostream_iterator<int>(cout, " ") // (10)
);
}
--->8---

"This isn't readable!", I hear you declaim in disdain. Of course it isn't.
It's C++!

However, it has some interesting characteristics that I hope you'll allow me
to describe to you. Ignore what it does (it's just a demonstration of
type-safety and implementation reuse). Try to focus on the semantics, and
overlook the tortured syntax.

***
(1) template<class Iter>
void AddSomeItems(Iter iter) {...}

This declares a templatized function, which takes a parameter. As it stands,
it doesn't do much typechecking, since at compile time (template compile
time) the compiler knows absolutely nothing about Iter or iter.


***
(2) for (int i = 0; i < 10; i++)

A simple for loop, starting at 0 and going up to 9.


***
(3) *iter++ = i;

The terse syntax C is famous for. What this does, is a little like this:

iter^ := i;
Inc(iter);

The '*' (think of it like a unary minus; it always goes before the variable
name (note that I'm writing to everybody, even those who've never seen C or
C++ before)) dereferences the iterator (iter). An iterator is like a
pointer; different iterators have different capabilities. Iterators can be
read only, write only, read/write. Independant of this, iterators can go
forwards only, forwards or backwards, or random access (array style access).
Iterators allow algorithms to be developed independant of the container they
'point' to.

The '++' at the end tells the compiler to increment iter *after* the
statement has been executed.

***
So, the function AddSomeItems fills values into iter as if it were a bottle
filling plant; fill, next, fill, next, fill, next, etc. until exit criteria
achieved.

***
(4) vector<int> myVec;
This declares a container, a 'vector', which holds ints as its atomic type.
This means that you can add ints, and only ints, to this container. If it
isn't an int, the compiler will shout at you.

A vector is a bit like TList, in that it has manipulation methods, and a bit
like 'array of Integer', in that it is typesafe.

***
(5) back_inserter(myVec)

This is a parameter to AddSomeItems, but it's newer information, so it comes
first :)

The back_inserter() function call returns an iterator that *adds* items to
the *end* of the container it's called with. More specifically, it returns a
back_insert_iterator (which is write only, and forward only), which ignores
the '++' operator, and adds to its container every time you assign to its
dereference.

***
(6) AddSomeItems(/* (5) */);

This is our function call. The compiler looks at the parameters of
AddSomeItems, and notices there is a templatized type; it notices we are
trying to call with a parameter of type 'back_insert_iterator<vector<int> >'
(notice that '>>' is a C++ operator; => '> >'), and deduces that it should
'instantiate' (i.e. create out of thin air) a copy of the function
AddSomeItems, using 'back_insert_iterator<vector<int> >' wherever it sees
Iter. IT THEN SYNTAX CHECKS THE AddSomeItems FUNCTION WITH THIS SPECIALIZED
ITERATOR. This is the crucial point. The compiler won't let the AddSomeItems
function add pointers, doubles, anything that isn't meant to go into
vector<int>.

***
(7) copy()

copy() is a simple and handy function used all over the place with the
standard C++ library. Its parameters: two forward input iterators, and an
output iterator. What it does is very simple: It starts "current" (local) at
begin, and assigns the value 'pointed to' by current, to the output iterator
"out" (local). It then increments both current and out. It checks to see if
current equals end. If it does, then it stops and returns. Otherwise it
continues. If begin was equal to end at the start, it doesn't do anything.

The upshot of this is, it acts like an interesting new machine for our
bottling plant; it starts at one end of a chain of bottles, and it knows
what the 'last' bottle looks like. Its also got a parallel output 'chain'.
It sucks out of the input, fills up the output, and moves on. Suck, fill,
next, suck, fill, next, until it reaches the end.

***
(8), (9), (10)
myVec.begin(),
myVec.end(),
ostream_iterator<int>(cout, " ") // (10)

These are the parameters to copy. (8) is the start, (9) specifies the end
AND THIS WON'T BE Copy'D. It is important to note that the end() iterator
exists at 'one past the end' of the container. If the container is empty,
begin() == end(), and copy() won't do anything.

(10) is interesting. It creates a special forward output iterator, which
whenever written to, spits that out at the stream given in its constructor,
with a separator, given as the second parameter in its constructor. It needs
to be created with an explicit type though. Handily enough, it'll complain
if you try to spit anything that isn't an int (or convertible to int) at it.

***

Exauhsting!

> Too small is a value judgment which may not be valid.

I write sometimes to provoke; when you feel strongly, the only thing worse
than somebody disagreeing with you is somebody not caring (warped Wilde ;-).


> I would contend that
> the C++ lexicon suffers from the failure of the committee to say no. too
> much baggage, in the name of not breaking existing code.

I think C++ is a disaster. That doesn't mean it doesn't have some
interesting features that OP could do with, though.

> Hmmm... the same
> problem which afflicts windows, to a great degree <g>.

I believe the client-server system of Windows NT (& 2000), with Native as
server and Win32 (csrss.exe) as client, interacting, reduces this annoyance
as much as possible; I believe that the architecture of WinNT is quite
powerful.

>>...


> Looked at ADA years ago. Played with it. Saw things to like, and things to
> dislike. In chief, what was likable was IMO due to the dominance of a
single
> architect in formation of the language. A major negative feature, again
IMO,
> was the involvement of the DOD.

I don't care too much for Ada either. In fact, I don't care about the
languages themselves; it's the semantics, the interesting syntax, the doors
opened to better *implementations* and better *interfaces*, that interest
me.

Object Pascal is my chosen language, because Ada isn't popular enough,
because C++ is ugly.

In generic programming, I see something that OP doesn't have. I'd like it to
have it. I can see improved library interfaces, with more type safety, a key
feature of Pascal. I can see improved library implementations, benefiting
from single-source solutions to problems of efficiency and type-safety. We
can learn from the mistakes of others past, and create a future more
perfect.

> ...


> VC is a (sometimes) necessary evil. VC ups the ante on
> unreadibility and bad practice, IMO.

I don't like VC. It blatantly ignores some fundamental parts of C++ by
default (for example 'for' local variable scoping).

> But as to demanding features in Delphi, I prefer to focus first on
improving
> my own practice, then on improving my utilization of what is already
> available in the tool. When I am confident that I have plumbed the limits
of
> Delphi and OP, I may be inclined to fight for extensions to OP.

I look at other languages with a mixture of disgust and envy; I want the
good bits without any of the crap. <g>

More particularly, since I'm young, I'm focusing on learning as much as
possible. To do this, I rewrite implementations of many things; compile-time
type-safe generic containers in the mode of C++ I have tried to do, and it
can't be done with a single source. I see the benefits of generic
programming. I see the barriers that others have stumbled upon. I believe
they can be overcome.

> However, if
> getting the benefit of templates leads to incurring any of the features of
> C++ which I truly despise, I will pass.

IIRC it was Wirth who wrote a book called "Data Structures + Algorithms =
Programs". He's right. And often, when you have the data structures, the
algorithms become obvious. However, often the algorithms are complex and
error-prone - especially when they are highly optimized.

So, we need algorithms that are generally applicable in a type safe manner.
We have this when these algorithms are methods of an object.

However, the object also specifies the data structure.

Attributes of the data structure vary depending on the problem domain.

So, do we rewrite the algorithm for every data structure? Of course not - if
the algorithm is worth being in a library, it would be a maintenance
nightmare to have it scattered in multiple layered versions here and there.

Instead, we should refactor, and *parameterize* those aspects of the data
structure that vary depending on the problem domain. Object Pascal doesn't
support parameterized types, so some kind of 'wildcard' must be used,
whether it be an interface, a variant, TVarRec (array of const), and the
type checking provided at run-time.

All I'm saying is that this is a kludge, a workaround, for which there are
known solutions, some better than others, some more flexible, some prettier,
etc. It's time to choose.

> It's important to me that Delphi remain lean and fast, and that OP remain
as
> compact as possible consistent with achieving good practice in light of
> current advances in our understanding of programming techniques.

You should know that C++ containers are designed for maximal performance. If
you think that Delphi is lean and fast, look at the implementation of
TQueue.PushItem in Contnrs.pas. It is the worst bug-free implementation of
queue semantics I've ever seen in my life.

-- Barry


Barry Kelly

unread,
Mar 24, 2001, 11:57:07 PM3/24/01
to

"William Meyer" <wme...@earthlink.net> wrote in message
news:3abd5969_1@dnews...

> "Barry Kelly" <barry_...@hotmail.com> wrote in message
> news:3abd542d_1@dnews...

>> Non-trivial object pascal programs force either hard casts or dynamic
casts.

> I've yet to see any C++ without some hard casts, either.

C++ has more expressive casts than Delphi. Very seldom is a C-style cast


needed, which is pretty much what the standard Pascal cast is.

> > Therefore, object pascal forces bad practice. <g,d&r>


>
> As C++ forces the use of some very ugly syntax (low readability = bad
> practice).
> Back at ya <g>

Of the most commonly used programming languages I've known, C++ has the


worst syntax I've ever seen, except for Perl.

I don't think C++ is a good language. However, I can see it has features
that Object Pascal doesn't - and I think Object Pascal would be improved if
it took some of them up, with lessons learned. Templates, which is a
type-aware macro preprocessor in C++, are a bad idea, especially with
implicit instantiation (i.e. no warning when a new version of a function /
class is created with a new type), IMO - but genericity can *AND SHOULD* be
implemented by other means.

>>....must agree!


> Nah, that would make it too easy on you. <g>

<aside, to the Dark Lord>This one is tough, Master...</aside> <g>

> I don't damn the concept.

Cool.


> > <<Don't rush to say "but Object Pascal can do ... too". The point isn't
> > capability, but maintainability, ease of use, reduction in error rate.>>
>
> Agreed, and I did not rush to say that. I merely speak from my own
> *experience*, not conjecture.

Excellent.

> My experience is shaped both by the tools I
> use, and by the problem domain in which I work (a factor which is
sometimes
> overlooked by some in these ngs.)

Object Pascal & Delphi as a tool are given by the newsgroup title; problem


domain is not. Lack of unity in problem domain leads to lack of focus in
discussions to accomodate features of said problem domains.

>> Don't you see the benefits?


>
> Again, lack of experience with the feature makes it a tough sell. If
you've
> a clear example to offer, that might help. Remember, though, that clarity
of
> expression (or rather, the infrequency with which I have seen it, in C++)
is
> a major concern.

You're right, of course; the concept clouded by stuttering speech, a tragedy

iter^ := i;
Inc(iter);

***
(5) back_inserter(myVec)

***
(7) copy()

***

Exauhsting!

> Too small is a value judgment which may not be valid.

I write sometimes to provoke; when you feel strongly, the only thing worse


than somebody disagreeing with you is somebody not caring (warped Wilde ;-).

> I would contend that
> the C++ lexicon suffers from the failure of the committee to say no. too
> much baggage, in the name of not breaking existing code.

I think C++ is a disaster. That doesn't mean it doesn't have some


interesting features that OP could do with, though.

> Hmmm... the same


> problem which afflicts windows, to a great degree <g>.

I believe the client-server system of Windows NT (& 2000), with Native as


server and Win32 (csrss.exe) as client, interacting, reduces this annoyance
as much as possible; I believe that the architecture of WinNT is quite
powerful.

>>...


> Looked at ADA years ago. Played with it. Saw things to like, and things to
> dislike. In chief, what was likable was IMO due to the dominance of a
single
> architect in formation of the language. A major negative feature, again
IMO,
> was the involvement of the DOD.

I don't care too much for Ada either. In fact, I don't care about the


languages themselves; it's the semantics, the interesting syntax, the doors
opened to better *implementations* and better *interfaces*, that interest
me.

Object Pascal is my chosen language, because Ada isn't popular enough,
because C++ is ugly.

In generic programming, I see something that OP doesn't have. I'd like it to
have it. I can see improved library interfaces, with more type safety, a key
feature of Pascal. I can see improved library implementations, benefiting
from single-source solutions to problems of efficiency and type-safety. We
can learn from the mistakes of others past, and create a future more
perfect.

> ...


> VC is a (sometimes) necessary evil. VC ups the ante on
> unreadibility and bad practice, IMO.

I don't like VC. It blatantly ignores some fundamental parts of C++ by


default (for example 'for' local variable scoping).

> But as to demanding features in Delphi, I prefer to focus first on


improving
> my own practice, then on improving my utilization of what is already
> available in the tool. When I am confident that I have plumbed the limits
of
> Delphi and OP, I may be inclined to fight for extensions to OP.

I look at other languages with a mixture of disgust and envy; I want the


good bits without any of the crap. <g>

More particularly, since I'm young, I'm focusing on learning as much as
possible. To do this, I rewrite implementations of many things; compile-time
type-safe generic containers in the mode of C++ I have tried to do, and it
can't be done with a single source. I see the benefits of generic
programming. I see the barriers that others have stumbled upon. I believe
they can be overcome.

> However, if


> getting the benefit of templates leads to incurring any of the features of
> C++ which I truly despise, I will pass.

IIRC it was Wirth who wrote a book called "Data Structures + Algorithms =


Programs". He's right. And often, when you have the data structures, the
algorithms become obvious. However, often the algorithms are complex and
error-prone - especially when they are highly optimized.

So, we need algorithms that are generally applicable in a type safe manner.
We have this when these algorithms are methods of an object.

However, the object also specifies the data structure.

Attributes of the data structure vary depending on the problem domain.

So, do we rewrite the algorithm for every data structure? Of course not - if
the algorithm is worth being in a library, it would be a maintenance
nightmare to have it scattered in multiple layered versions here and there.

Instead, we should refactor, and *parameterize* those aspects of the data
structure that vary depending on the problem domain. Object Pascal doesn't
support parameterized types, so some kind of 'wildcard' must be used,
whether it be an interface, a variant, TVarRec (array of const), and the
type checking provided at run-time.

All I'm saying is that this is a kludge, a workaround, for which there are
known solutions, some better than others, some more flexible, some prettier,
etc. It's time to choose.

> It's important to me that Delphi remain lean and fast, and that OP remain


as
> compact as possible consistent with achieving good practice in light of
> current advances in our understanding of programming techniques.

You should know that C++ containers are designed for maximal performance. If

William Meyer

unread,
Mar 25, 2001, 12:45:52 AM3/25/01
to
"Barry Kelly" <barry_...@hotmail.com> wrote in message
news:3abd79e9_2@dnews...

>
> C++ has more expressive casts than Delphi. Very seldom is a C-style cast
> needed, which is pretty much what the standard Pascal cast is.

"More expressive" may also be viewed as a euphemism for more confusing. C++
is overloaded (pun intended) with an excess of features. This leads many to
mix and match at will, confusing the support included for legacy code with
current practice.

> Of the most commonly used programming languages I've known, C++ has the
> worst syntax I've ever seen, except for Perl.

Well, K&R C has a pretty funky syntax, with a good deal of irregularity,
too, so I suppose we can forgive some of Stroustrup's foibles, but the
committee, moving at a glacial pace, had no good reason to commit such
folly.

> I don't think C++ is a good language. However, I can see it has features
> that Object Pascal doesn't - and I think Object Pascal would be improved
if
> it took some of them up, with lessons learned. Templates, which is a
> type-aware macro preprocessor in C++, are a bad idea, especially with
> implicit instantiation (i.e. no warning when a new version of a function /
> class is created with a new type), IMO - but genericity can *AND SHOULD*
be
> implemented by other means.

I think that a pre-processor is in general a bad idea. I like
macro-processors, and admire some of the clever things which can be done
with them, *on their own*, but I see the inclusion of a macro-processor in C
and C++ as a major weakness. It leads to Byzantine constructs, and is a
major cause of debugger problems.

> <aside, to the Dark Lord>This one is tough, Master...</aside> <g>

And proud to be, too. <g>

> Object Pascal & Delphi as a tool are given by the newsgroup title; problem
> domain is not. Lack of unity in problem domain leads to lack of focus in
> discussions to accomodate features of said problem domains.

Fair enough, but many here are inclined to assume that we all build office
apps of some sort, and that we all use database in all our apps, too. Both
are faulty premises. My own application domain is more involved with
real-time issues and hardware interface -- areas which have little in common
with office apps.

> You're right, of course; the concept clouded by stuttering speech, a
tragedy
> of miscommunication. I'll speak some C++, and hopefully you'll follow.

And by my continuing inability to find time for all the many things I wish
to study <g>. I keep putting C++ on the list, and it keeps getting too
little time.

Also, please understand that most of my exposure to C++ has, unfortunately
been in its VC incarnation, which some may argue is a perversion of C++ (and
I might agree.)

> ---8<---
> #include <iostream>
> #include <vector>
> #include <algorithm>
>
> template<class Iter>
> void AddSomeItems(Iter iter) // (1)
> {
> for (int i = 0; i < 10; i++) // (2)
> *iter++ = i; // (3)
> }
>
> int main()
> {
> using namespace std; // NOTE B
>
> vector<int> myVec; // (4)
>
> // add some items
> AddSomeItems( // (6)
> back_inserter(myVec) // (5)
> );
>
> // print out items
> copy( // (7)
> myVec.begin(), // (8)
> myVec.end(), // (9)
> ostream_iterator<int>(cout, " ") // (10)
> );
> }
> --->8---
>
> "This isn't readable!", I hear you declaim in disdain. Of course it isn't.
> It's C++!

Well, let's just say that as in any language, it assumes some understanding
on the part of the reader.

> However, it has some interesting characteristics that I hope you'll allow
me
> to describe to you. Ignore what it does (it's just a demonstration of
> type-safety and implementation reuse). Try to focus on the semantics, and
> overlook the tortured syntax.

I will never disdain illustrations offered by someone who may be able to
facilitiate my continuing education. I will do my best to comprehend, and
will try to ask when something glazes my eyes.

> ***
> (1) template<class Iter>
> void AddSomeItems(Iter iter) {...}
>
> This declares a templatized function, which takes a parameter. As it
stands,
> it doesn't do much typechecking, since at compile time (template compile
> time) the compiler knows absolutely nothing about Iter or iter.

Ok, so far.

> ***
> (2) for (int i = 0; i < 10; i++)
>
> A simple for loop, starting at 0 and going up to 9.

OK, I'm not *that* ignorant of C++ <g>.

> ***
> (3) *iter++ = i;
>
> The terse syntax C is famous for. What this does, is a little like this:
>
> iter^ := i;
> Inc(iter);

A logical(?) extension from the old += in C, I guess, but on first blush, it
seems it might too easily be misread as the older form.

> The '*' (think of it like a unary minus; it always goes before the
variable
> name (note that I'm writing to everybody, even those who've never seen C
or
> C++ before)) dereferences the iterator (iter). An iterator is like a
> pointer; different iterators have different capabilities. Iterators can be
> read only, write only, read/write. Independant of this, iterators can go
> forwards only, forwards or backwards, or random access (array style
access).
> Iterators allow algorithms to be developed independant of the container
they
> 'point' to.

I clearly recall reading K&R many years ago, and being exceedingly
comfortable with the language, *until* chapter 7, in which they blundered
through the presentation of pointers and pointer notation. I don't think I
ever met anyone who would defent that chapter as an example of clarity.

> The '++' at the end tells the compiler to increment iter *after* the
> statement has been executed.

Understood.

> ***
> So, the function AddSomeItems fills values into iter as if it were a
bottle
> filling plant; fill, next, fill, next, fill, next, etc. until exit
criteria
> achieved.
>
> ***
> (4) vector<int> myVec;
> This declares a container, a 'vector', which holds ints as its atomic
type.
> This means that you can add ints, and only ints, to this container. If it
> isn't an int, the compiler will shout at you.
>
> A vector is a bit like TList, in that it has manipulation methods, and a
bit
> like 'array of Integer', in that it is typesafe.

OK....

> ***
> (5) back_inserter(myVec)
>
> This is a parameter to AddSomeItems, but it's newer information, so it
comes
> first :)

Huh?

> The back_inserter() function call returns an iterator that *adds* items to
> the *end* of the container it's called with. More specifically, it returns
a
> back_insert_iterator (which is write only, and forward only), which
ignores
> the '++' operator, and adds to its container every time you assign to its
> dereference.
>
> ***
> (6) AddSomeItems(/* (5) */);
>
> This is our function call. The compiler looks at the parameters of
> AddSomeItems, and notices there is a templatized type; it notices we are
> trying to call with a parameter of type 'back_insert_iterator<vector<int>
>'
> (notice that '>>' is a C++ operator; => '> >'), and deduces that it should
> 'instantiate' (i.e. create out of thin air) a copy of the function
> AddSomeItems, using 'back_insert_iterator<vector<int> >' wherever it sees
> Iter. IT THEN SYNTAX CHECKS THE AddSomeItems FUNCTION WITH THIS
SPECIALIZED
> ITERATOR. This is the crucial point. The compiler won't let the
AddSomeItems
> function add pointers, doubles, anything that isn't meant to go into
> vector<int>.

Got it. I think. you're saying the AddSomeItems is not type specific in its
definition, but becomes so in its application, and the compiler treats it in
the context of its invocation, thus allowing the type checking at compile
time. If I am understanding this properly, The alternative would be to
generate overloaded functions for all conceivable types, or at least for
each type used in the application.

Still with you.

> (10) is interesting. It creates a special forward output iterator, which
> whenever written to, spits that out at the stream given in its
constructor,
> with a separator, given as the second parameter in its constructor. It
needs
> to be created with an explicit type though. Handily enough, it'll complain
> if you try to spit anything that isn't an int (or convertible to int) at
it.

OK.

> ***
>
> Exauhsting!

Clearly communicating knew knowledge to an audience without making
unwarranted assumptions always is. <g> Well done!


> I write sometimes to provoke; when you feel strongly, the only thing worse
> than somebody disagreeing with you is somebody not caring (warped Wilde
;-).

I'm not so easily provoked. I'm comfortable with my tools, and with my field
of application. After coding for over 25 years, I don't think I have to
prove anything, and since the application domain is highly specialized, I'm
at little risk of being displaced by young turks fresh from university. More
likely, I will guide a group of them as project leader.

> I think C++ is a disaster. That doesn't mean it doesn't have some
> interesting features that OP could do with, though.

On this we agree. To both parts.

> I believe the client-server system of Windows NT (& 2000), with Native as
> server and Win32 (csrss.exe) as client, interacting, reduces this
annoyance
> as much as possible; I believe that the architecture of WinNT is quite
> powerful.

I'm very much at ease with Win2K, as it appears to have overcome most of the
problems which affect my own application issues.

> Object Pascal is my chosen language, because Ada isn't popular enough,
> because C++ is ugly.

OP is mine, because I've been using Pascal since before Turbo, and because
Delphi makes me more productive in Windows than any other tool I can find. I
still find that C offers some advantages in parsing text (even though the
lack of string support in K&R is a bit silly), but the most recent changes
in OP have reduced this somewhat.

> In generic programming, I see something that OP doesn't have. I'd like it
to
> have it. I can see improved library interfaces, with more type safety, a
key
> feature of Pascal. I can see improved library implementations, benefiting
> from single-source solutions to problems of efficiency and type-safety. We
> can learn from the mistakes of others past, and create a future more
> perfect.

I have a better understanding of genericity, thanks to your efforts. My most
recent study has been moving more in the direction of technique and good
practice, rather than expanded understanding of specific tools. I still
would like to make time for some study of C++, specifically to lift myself
out of the trap of too narrow a view. But then there's that list of tasks
again.....

> I don't like VC. It blatantly ignores some fundamental parts of C++ by
> default (for example 'for' local variable scoping).

It also is totally unreliable in error reporting, among other things.

> I look at other languages with a mixture of disgust and envy; I want the
> good bits without any of the crap. <g>

I'd say I do much the same. For some, such as Lisp, it's no contest -- pure
disgust. <g>

> More particularly, since I'm young, I'm focusing on learning as much as
> possible. To do this, I rewrite implementations of many things;
compile-time
> type-safe generic containers in the mode of C++ I have tried to do, and it
> can't be done with a single source. I see the benefits of generic
> programming. I see the barriers that others have stumbled upon. I believe
> they can be overcome.

Ah, the energy of youth <g>. I do think the days are shorter, and the task
list longer, as we age.

> IIRC it was Wirth who wrote a book called "Data Structures + Algorithms =
> Programs". He's right. And often, when you have the data structures, the
> algorithms become obvious. However, often the algorithms are complex and
> error-prone - especially when they are highly optimized.

Yes it was. And he was. Data dictates program structure, to a large degree.
That's why OOP has achieved what structured programming could only approach.

> So, do we rewrite the algorithm for every data structure? Of course not -
if
> the algorithm is worth being in a library, it would be a maintenance
> nightmare to have it scattered in multiple layered versions here and
there.

Sometimes, yes, because sometimes, the burden implied by making something
generic is, in and of itself, insupportable. There are, after all, still
times when the right answer is inline assembler.

> Instead, we should refactor, and *parameterize* those aspects of the data
> structure that vary depending on the problem domain. Object Pascal doesn't
> support parameterized types, so some kind of 'wildcard' must be used,
> whether it be an interface, a variant, TVarRec (array of const), and the
> type checking provided at run-time.

I'm a recent convert to refactoring, though I've done much of that anyway,
as it becomes obvious to anyone who must maintain a program of significant
size. Fowler codifies good practice, however, and reinforces the lessons we
derive from experience -- and affirmation is always welcome. Variants I
habitually avoid, as they are only useful if wrapped with a good deal of
diagnostics, in my view. I see the benefit of genericity, and I will agree
that it would be a good addition to OP, if done with the same elegance which
has always characterized the language.

Did you notice? I agreed.<g> Time to celebrate!

> You should know that C++ containers are designed for maximal performance.
If
> you think that Delphi is lean and fast, look at the implementation of
> TQueue.PushItem in Contnrs.pas. It is the worst bug-free implementation of
> queue semantics I've ever seen in my life.

In C++, doesn't maximum performance = minimal clarity? <g>

Bill


William Meyer

unread,
Mar 25, 2001, 12:47:02 AM3/25/01
to
"Barry Kelly" <barry_...@hotmail.com> wrote in message
news:3abd7bc8_1@dnews...

>
> I wrote:
>
> > using namespace std; // NOTE B
>
> "Sanity clause? There is no sanity clause!"
>
> Here's that missing NOTE B:
>
> Namespaces fill in for C++'s lack of modularization beyond 60's
> preprocessors. I'm putting in a general using declaration to free up the
> syntax from some clutter.

Oh yeah... I forgot all about B <g>.

> Now, I wonder what happened to NOTE A.... <g>

LOL! Documentation error!

Bill


William Meyer

unread,
Mar 25, 2001, 12:55:04 AM3/25/01
to
"Barry Kelly" <barry_...@hotmail.com> wrote in message
news:3abd7aa4_1@dnews...

>
> Of the most commonly used programming languages I've known, C++ has the
> worst syntax I've ever seen, except for Perl.

And speaking of bad syntax, I have seen some appallingly bad use of the
ternary operator in C. I will have to dig for it, but I think I can offer up
an example in which there were three successive lines, each using the
ternary op, and each over 150 characters in length!

Of greater interest is that these were in a VC app, and during the time I
spent unsuccessfully trying to port that to BCB, I found that although VC
made no complaint, BCB correctly discovered an error in one of the three
lines, which resulted from mismatched parentheses. Yet another reason I hate
VC!

Bill


Barry Kelly

unread,
Mar 25, 2001, 2:18:39 AM3/25/01
to
"William Meyer" <wme...@earthlink.net> wrote in message
news:3abd8608_2@dnews...

> "Barry Kelly" <barry_...@hotmail.com> wrote in message
> news:3abd79e9_2@dnews...

> > Of the most commonly used programming languages I've known, C++ has the


> > worst syntax I've ever seen, except for Perl.
>
> Well, K&R C has a pretty funky syntax, with a good deal of irregularity,
> too, so I suppose we can forgive some of Stroustrup's foibles, but the
> committee, moving at a glacial pace, had no good reason to commit such
> folly.

My particular bone of contention with C & C++ is function pointer
declarations. Pascal types are generally read from left to right, nice and
simple. A pointer to an array of functions returning pointers to arrays of
functions returning pointers, in OP, as short as possible (^array isn't
allowed by compiler):

---8<---
type
TPointerFuncArray = array[0..3] of function: Pointer;
PPointerFuncArray = ^TPointerFuncArray;
TPointerFuncArrayFuncArray = array[0..3] of function: PPointerFuncArray;
TMyComplexType = ^TPointerFuncArrayFuncArray;
--->8---

I never learned the proper order and syntax for function pointers or arrays
in C, so I can't write an equivalent. Generally, though, complex C
declarations have to be read backwards and inside out, especially when you
get to C++ and the distinction between const pointer and pointer to const
and const pointer to const...

> > <aside, to the Dark Lord>This one is tough, Master...</aside> <g>
>
> And proud to be, too. <g>

<aside to the Dark Lord>And yet, see how he has fallen before me...</aside>
<g,d&r>

> Fair enough, but many here are inclined to assume that we all build office
> apps of some sort, and that we all use database in all our apps, too. Both
> are faulty premises. My own application domain is more involved with
> real-time issues and hardware interface -- areas which have little in
common
> with office apps.

My own domain of preference is compiler construction. Not much to do with
office apps either, but fundamental to every programmer's job!

> And by my continuing inability to find time for all the many things I wish
> to study <g>. I keep putting C++ on the list, and it keeps getting too
> little time.

If you read anything, read Stroustrup's 3rd The C++ Programming Language;
it's the only book I've ever read on C++, but I like to go to the source for
initial 'conceptual framework', newsgroups to fill in reality,
experimentation for understanding, and practice to learn. My next mission is
to petition God for more hours per day. <g>

> > ---8<---
> > #include <iostream>
> > #include <vector>
> > #include <algorithm>
> >
> > template<class Iter>
> > void AddSomeItems(Iter iter) // (1)
> > {
> > for (int i = 0; i < 10; i++) // (2)
> > *iter++ = i; // (3)
> > }
> >
> > int main()
> > {
> > using namespace std; // NOTE B
> >
> > vector<int> myVec; // (4)
> >
> > // add some items
> > AddSomeItems( // (6)
> > back_inserter(myVec) // (5)
> > );
> >
> > // print out items
> > copy( // (7)
> > myVec.begin(), // (8)
> > myVec.end(), // (9)
> > ostream_iterator<int>(cout, " ") // (10)
> > );
> > }
> > --->8---

> > (1) template<class Iter>
> > void AddSomeItems(Iter iter) {...}

It's like a class. It defines how a function behaves, but it doesn't do
anything. (I know you know, Bill, but I don't know if everyone else knows,
and I've thought of a better analogy).

> > (3) *iter++ = i;
> >
> > The terse syntax C is famous for. What this does, is a little like this:
> >
> > iter^ := i;
> > Inc(iter);
>
> A logical(?) extension from the old += in C, I guess, but on first blush,
it
> seems it might too easily be misread as the older form.

The interesting thing is that the syntax works just as well for a pointer.
If I have an old-fashioned array (with at least 10 elements of course), I
can pass it (or the address of the first element; same thing in C) to the
function, and it will perform as expected.

> I clearly recall reading K&R many years ago, and being exceedingly
> comfortable with the language, *until* chapter 7, in which they blundered
> through the presentation of pointers and pointer notation. I don't think I
> ever met anyone who would defent that chapter as an example of clarity.

I learned Pascal before C; with Pascal, a unary ^ BEFORE for type definition
("points to type"), and a unary ^ AFTER for dereferencing ("...I'm stuck for
words but you know what I mean...") seems so natural (especially for
records). I was confused for a while until I twigged it: exactly like a
unary negate. Stick it in brackets if you're in doubt (as you are when
you're pointing to a struct; but hey! there's another operator for that...).

> > ***
> > (5) back_inserter(myVec)
> >
> > This is a parameter to AddSomeItems, but it's newer information, so it
> comes
> > first :)
>
> Huh?

Refer to the numbers above. I call AddSomeItems with this exact parameter.
Sorry for the confusion, but it only makes sense to talk about implicit
template function initialization when the type of the parameters are known.

> [snipped stuff about template instantiation]

> Got it. I think. you're saying the AddSomeItems is not type specific in
its
> definition, but becomes so in its application, and the compiler treats it
in
> the context of its invocation, thus allowing the type checking at compile
> time. If I am understanding this properly, The alternative would be to
> generate overloaded functions for all conceivable types, or at least for
> each type used in the application.

You got it.


> >
> > Exhausting!


>
> Clearly communicating knew knowledge to an audience without making
> unwarranted assumptions always is. <g> Well done!

Thanks!

***

I'd like to point out something else... you can change the program to use
'list' instead of 'vector'. Vector is implemented as an array (I believe
this is guaranteed; the comittee designed it to replace ALL usage of
arrays). Therefore, it has poor performance for insertions in the middle or
at the start. 'list' is implemented as a double-linked list, so it's got
good insertion performance, as long as you've got an iterator pointing at
where you want to insert.

So, to change to use list:

replace "#include <vector>" with "#include <list>"

replace "vector<int> myVec" with "list<int> myVec" (I'm trying to minimize
changes here :)

And the program will work as before. The function AddSomeItems() doesn't
care about what container it's working with, and yet it is still type-safe.
However, the error messages for template bugs can be very cryptic - but I
think this is an implementation issue.

> I
> still find that C offers some advantages in parsing text (even though the
> lack of string support in K&R is a bit silly), but the most recent changes
> in OP have reduced this somewhat.

I always use PChar. Personally, I like the use of sets for checking stuff;
like, to skip whitespace:

---8<---
var
cp: PChar;
begin
cp := PChar(SomeBuffer);
while cp^ in [#1..#32] do
Inc(cp);
// either point at EOF (#0) or some token...
end;
--->8---

Yes, I know isspace() is 'better', but the set can be replaced with a
constant. Testing for set inclusion generates tight code too.

It does annoy me quite a bit when I see people parsing strings using Pos &
Delete (Delete to consume the start... ugh!). FreeVCS annoys me particularly
because it uses some brain-dead tag replacement algorithm that runs about
64KB per second...


> > I look at other languages with a mixture of disgust and envy; I want the
> > good bits without any of the crap. <g>
>
> I'd say I do much the same. For some, such as Lisp, it's no contest --
pure
> disgust. <g>

<g>

> Ah, the energy of youth <g>. I do think the days are shorter, and the task
> list longer, as we age.

<g>

> > So, do we rewrite the algorithm for every data structure? Of course
not -
> if
> > the algorithm is worth being in a library, it would be a maintenance
> > nightmare to have it scattered in multiple layered versions here and
> there.

> Sometimes, yes, because sometimes, the burden implied by making something
> generic is, in and of itself, insupportable. There are, after all, still
> times when the right answer is inline assembler.

The only time when assembley is the right answer is where the compiler is
unsupportably inefficient, or the problem domain doesn't intersect with the
language's domain. Whether the assembley is inline or not is another
matter - I'm rather of the opinion that one shouldn't mix the specific and
the general, the portable and the non-portable.

> > Instead, we should refactor, and *parameterize* those aspects of the
data
> > structure that vary depending on the problem domain. Object Pascal
doesn't
> > support parameterized types, so some kind of 'wildcard' must be used,
> > whether it be an interface, a variant, TVarRec (array of const), and the
> > type checking provided at run-time.
>
> I'm a recent convert to refactoring, though I've done much of that anyway,
> as it becomes obvious to anyone who must maintain a program of significant
> size.


Refactoring is an endless process, terminating at infinity with the perfect
program that generates every other program...

> I see the benefit of genericity, and I will agree
> that it would be a good addition to OP, if done with the same elegance
which
> has always characterized the language.
>
> Did you notice? I agreed.<g> Time to celebrate!

Woohoo! Excellent! I hope some lurkers-converted lurk too...

>> You should know that C++ containers are designed for maximal performance.
>> If you think that Delphi is lean and fast, look at the implementation of
>> TQueue.PushItem in Contnrs.pas. It is the worst bug-free implementation
of
>> queue semantics I've ever seen in my life.

Look at the method implementation (GPL, FreeCLX); it uses:

---8<---
TQueue.PushItem(AItem: Pointer);
begin
List.Insert(0, AItem);
end;
--->8---

Can you imagine how long it takes to insert items at the start of a TList
when there are some items in it already? This minimal implementation can
only serve as an idiot-proof test case, never to be used in production code.
I'm writing a patch to Contnrs.pas that refactors (that word again - I
notice you like it <G>) the TOrderedList class to either use a double-linked
list or a TList as its implementation; then derive TStack from
TListList(descends from TOrderedList), and TQueue from TLinkedList(also
descends from TOrderedList). That'll fix it.

> In C++, doesn't maximum performance = minimal clarity? <g>

<G>

Good luck,

-- Barry


William Meyer

unread,
Mar 25, 2001, 3:02:19 AM3/25/01
to
"Barry Kelly" <barry_...@hotmail.com> wrote in message
news:3abd9bf7_1@dnews...

>
> My particular bone of contention with C & C++ is function pointer
> declarations. Pascal types are generally read from left to right, nice and
> simple. A pointer to an array of functions returning pointers to arrays of
> functions returning pointers, in OP, as short as possible (^array isn't
> allowed by compiler):

> I never learned the proper order and syntax for function pointers or


arrays
> in C, so I can't write an equivalent. Generally, though, complex C
> declarations have to be read backwards and inside out, especially when you
> get to C++ and the distinction between const pointer and pointer to const
> and const pointer to const...
>

I used to remember the page number in K&R for the table of precedence, and
the place where it delineated the order of interpretation in unpacking the
sense of declarations. Some were L->R, others were R->L, and still others
bounced back and forth, from the inside out. Can you say it was a happening?

> > > <aside, to the Dark Lord>This one is tough, Master...</aside> <g>
> >
> > And proud to be, too. <g>
>
> <aside to the Dark Lord>And yet, see how he has fallen before
me...</aside>
> <g,d&r>

LOL! Not fallen, but willing to agree on *some* points you advanced.

> My own domain of preference is compiler construction. Not much to do with
> office apps either, but fundamental to every programmer's job!

Domains of preference and domains of employment are not necessarily
congruent <g>. I spent some time, years ago, on compiler design study,
struggling with Aho and Ullman, and with Gries, but am content with the more
pragmatic and approachable presentation of Cranshaw, though he admits his
compilers will never threaten any commercial offerings.

> If you read anything, read Stroustrup's 3rd The C++ Programming Language;
> it's the only book I've ever read on C++, but I like to go to the source
for
> initial 'conceptual framework', newsgroups to fill in reality,
> experimentation for understanding, and practice to learn. My next mission
is
> to petition God for more hours per day. <g>

Uh... has he gained anything in communication skills? With all due respect,
I picked up the first edition years ago, and found a nearly perfect cure for
insomnia. <g> I think I am more likely to try reading Eckel's "Thinking in
C++', frankly; he is good at conveying concepts, and I have little patience
with writers who haven't master communication skills. When you get the
response on that petition, let me know... I need a few more.

> The interesting thing is that the syntax works just as well for a pointer.
> If I have an old-fashioned array (with at least 10 elements of course), I
> can pass it (or the address of the first element; same thing in C) to the
> function, and it will perform as expected.

And that's one of the shortest routes to hell in C or C++ -- the ease with
which pointers may be fouled.

> I learned Pascal before C; with Pascal, a unary ^ BEFORE for type
definition
> ("points to type"), and a unary ^ AFTER for dereferencing ("...I'm stuck
for
> words but you know what I mean...") seems so natural (especially for
> records). I was confused for a while until I twigged it: exactly like a
> unary negate. Stick it in brackets if you're in doubt (as you are when
> you're pointing to a struct; but hey! there's another operator for
that...).

I also learned Pascal before C, but unfortunately, it was UCSD Pascal, then
Pascal/M, both of which I abandoned, for reasons which will be clear to
anyone who used either of them. <g> The unary negate parallel is useful; I
wish it had occurred to K&R to express it in those terms. My recollection is
that they managed to keep things pretty murky in the area of * and &.

> > > (5) back_inserter(myVec)
> > >
> > > This is a parameter to AddSomeItems, but it's newer information, so it
> > comes
> > > first :)
> >
> > Huh?
>
> Refer to the numbers above. I call AddSomeItems with this exact parameter.
> Sorry for the confusion, but it only makes sense to talk about implicit
> template function initialization when the type of the parameters are
known.

I referred back before writing my profound response. Clear as mud. Later it
occurred to me that back_inserter must be something taken from the #include
<vector> file.

> > [snipped stuff about template instantiation]
>
> > Got it. I think. you're saying the AddSomeItems is not type specific in
> its
> > definition, but becomes so in its application, and the compiler treats
it
> in
> > the context of its invocation, thus allowing the type checking at
compile
> > time. If I am understanding this properly, The alternative would be to
> > generate overloaded functions for all conceivable types, or at least for
> > each type used in the application.
>
> You got it.

Whew!

> > >
> > > Exhausting!
> >
> > Clearly communicating knew knowledge to an audience without making
> > unwarranted assumptions always is. <g> Well done!
>
> Thanks!
>
> ***
>
> I'd like to point out something else... you can change the program to use
> 'list' instead of 'vector'. Vector is implemented as an array (I believe
> this is guaranteed; the comittee designed it to replace ALL usage of
> arrays). Therefore, it has poor performance for insertions in the middle
or
> at the start. 'list' is implemented as a double-linked list, so it's got
> good insertion performance, as long as you've got an iterator pointing at
> where you want to insert.

Comments about committees in general, and *that* one in particular, expunged
after due consideration...

>
> So, to change to use list:
>
> replace "#include <vector>" with "#include <list>"
>
> replace "vector<int> myVec" with "list<int> myVec" (I'm trying to minimize
> changes here :)
>
> And the program will work as before. The function AddSomeItems() doesn't
> care about what container it's working with, and yet it is still
type-safe.
> However, the error messages for template bugs can be very cryptic - but I
> think this is an implementation issue.

Getting a little murky again, but only because the concept is still pretty
abstract to me, and also because the vast collection of collectons of stuff
in C++ is just so.....vast. And still largely unknown to me.

> I always use PChar. Personally, I like the use of sets for checking stuff;
> like, to skip whitespace:

I hate PChars. The Pascal string type has always made more sense to me. I
also make use of sets -- they often convey a much clearer sense of what is
being done.

> ---8<---
> var
> cp: PChar;
> begin
> cp := PChar(SomeBuffer);
> while cp^ in [#1..#32] do
> Inc(cp);
> // either point at EOF (#0) or some token...
> end;
> --->8---
>
> Yes, I know isspace() is 'better', but the set can be replaced with a
> constant. Testing for set inclusion generates tight code too.

Not clear that isspace() is better. It *would* be better to declare the set
somewhere as a const, however, and give it a good name, like WhiteSpace, so
that you then say:

while cp^ in WhiteSpace do

Which makes the notion very clear. (Refactoring principles again.)

> It does annoy me quite a bit when I see people parsing strings using Pos &
> Delete (Delete to consume the start... ugh!). FreeVCS annoys me
particularly
> because it uses some brain-dead tag replacement algorithm that runs about
> 64KB per second...

I use whatever makes best sense at the time. Depends on the requirements.
Delete is ok for a quick and dirty fixup, but if I have to parse a string,
I'm more likely to use head and tail indices, and then do a copy.

> > Sometimes, yes, because sometimes, the burden implied by making
something
> > generic is, in and of itself, insupportable. There are, after all, still
> > times when the right answer is inline assembler.
>
> The only time when assembley is the right answer is where the compiler is
> unsupportably inefficient, or the problem domain doesn't intersect with
the
> language's domain. Whether the assembley is inline or not is another
> matter - I'm rather of the opinion that one shouldn't mix the specific and
> the general, the portable and the non-portable.

I'm more pragmatic. There are times to use assembler inline. Look at the VCL
source for some examples. Munching text is one of those times, as the x86
instruction set has some special instructions which are very efficient, but
teaching a compiler to apply them at the right times (only) would lead to
some pretty ugly internal kludges.

> > I'm a recent convert to refactoring, though I've done much of that
anyway,
> > as it becomes obvious to anyone who must maintain a program of
significant
> > size.
>
> Refactoring is an endless process, terminating at infinity with the
perfect
> program that generates every other program...

Well, let's just settle for enless <g>.

> > I see the benefit of genericity, and I will agree
> > that it would be a good addition to OP, if done with the same elegance
> which
> > has always characterized the language.
> >
> > Did you notice? I agreed.<g> Time to celebrate!
>
> Woohoo! Excellent! I hope some lurkers-converted lurk too...

Don't overlook my caveat. I'm not willing for it to bring with it any of the
uglier features of C++. your victory, if such it was, is conditional. <g>

> Look at the method implementation (GPL, FreeCLX); it uses:
>
> ---8<---
> TQueue.PushItem(AItem: Pointer);
> begin
> List.Insert(0, AItem);
> end;
> --->8---
>
> Can you imagine how long it takes to insert items at the start of a TList
> when there are some items in it already? This minimal implementation can
> only serve as an idiot-proof test case, never to be used in production
code.
> I'm writing a patch to Contnrs.pas that refactors (that word again - I
> notice you like it <G>) the TOrderedList class to either use a
double-linked
> list or a TList as its implementation; then derive TStack from
> TListList(descends from TOrderedList), and TQueue from TLinkedList(also
> descends from TOrderedList). That'll fix it.

Looking at that implementation, I would have assumed that List.Insert must,
in fact, be based on a doubly linked list -- otherwise, the penalty is
obvious, and tolerable only in lists of trivial length.

Bill


Rudy Velthuis (TeamB)

unread,
Mar 25, 2001, 5:19:44 AM3/25/01
to
Barry Kelly wrote in <3abd46ee_1@dnews>...

>
> "Frederick C. Wilt" <fcw...@mindspring.com> wrote in message
> news:3abd3914_1@dnews...
>
> > Answers:
>
> Opinions, rather, I hope :)
>
> > 1. I sure hope not.
>
> I think you're wrong. I can't hope to convince you until you are specific
> about
>
> > 2. Templates are basically code generation.
>
> Don't let a bad implementation damn a concept; and don't confuse templates
> with generic programming.
>
> Templates <> generics. Templates are an (ugly) implementation of generic
> programming. Generic programming can be accomplished in OP with interfaces.
> But not with compile-time type checking.
>
> > If you think OP [better?] needs them write
> > a preprocessor and sell it.
>
> I've written a preprocessor. However, a preprocessor
>
> > I have a very usable set of container classes that requires me to override
> > only two methods and these are one-liners. If I wanted to it would be
> > trivial to create a Wizard that would generate the code for me.
>
> Run-time type-checking <> compile-time type-checking. If you like run-time
> type checking, you should be happy with JavaScript, Perl, etc.

Generated classes will have compile time type checking allright. There
will simply be a new source file (or at least a newly derived class) for
each type of item, either based on a class that uses pointers, or uses
some kind of dynamic array of items of any size. The checking will be
done during compilation.

Generators only have the disadvantage that you can't write your own data
structures without rewriting the generator, and that hand-made
modifications to the generated code (e.g. some special handling for a
type) will be lost each time you have to regenerate the code.

Preprocessors relieve you a bit of that, but they have the disadvantage
that your error messages are totally messed up, since line numbers etc.
will refer to the preprocessed code, not to the original code.

An example: for JEDI, we use a special format when creating a header
translation, a .par file (according to Borland's specs), primarily to be
able to handle both ANSI and Unicode types of the same functions and
types. We use a Borland-supplied preprocessor to generate the real .pas
file (Borland requires this -- the preprocessor is available for free,
for everyone who wants it). Testing such a .pas file always requires
updating the .par file, not the .pas file, although the error message
points to the .pas file, of course. This is very tedious, and error
prone.

That explains why I have an aversion against preprocessors (except if
they are part of the language, and the language handles such
differences). If you use them you are always writing in a meta-language
(even if it is very close to the original), not in the language itself.
--
Rudy Velthuis (TeamB) http://delphi-jedi.org

Rudy Velthuis (TeamB)

unread,
Mar 25, 2001, 5:01:20 AM3/25/01
to
William Meyer wrote in <3abd3099$1_2@dnews>...

> Wow! Never thought I'd hear that claim. The pervasive use of DWORDs in C++
> where a pointer type should be used is the bane of my existence.

That is C. You'll only see that in API headers.

Truth is (see the discussion in borland.public.discussion about code
templates too), that C++, through templates (one way of providing
genericity) has a way of creating reusable containers and functions with
inherent type checking. The container/function normally doesn't even have
to know anything about the type.

OP's containers, however sophisticated they might be (some 3rd party
libraries are), can't come around this deficit.

You either derive a new container for each type if item you want to
contain (type safe, but of course a lot of work, see TObjectList,
TInterfaceList, TStringList, etc.), or you must do static or dynamic
casting (very un-type-safe, see TList), or you do your own RTTI, by
storing your own kind of type information (size, how to free, comparison
-- for sorting --, etc.) with the different types you store, which also
results in run time type checking (see some of the 3rd party libs, which
use interfaces or objects).

If we had

type
TList(T: type) = class
...
function GetItem(Index: Integer): T;
function Add(Item: T): Integer;
function Remove(Item: T): Boolean;
function IndexOf(Item: T): Integer;
function Delete(Item: T): T;

or

TMap(TKey, TValue: type) = class
...

and we could have

var
IntList: TList(Integer);
StrList: TList(String);
begin
IntList := TList.Create(Integer);
StrList := TList.Create(string);
IntList.Add(1234);
StrList.Add('Hello');
...
StrList[0] := StrList[0] + ' there';

or even

MyMap['Hello'] := 17;

then we'd probably soon see a vast amount of useful maps, lists, vectors,
trees, and other containers.

Rudy Velthuis (TeamB)

unread,
Mar 25, 2001, 5:37:38 AM3/25/01
to
Rudy Velthuis (TeamB) wrote in
<MPG.1527e4a78...@newsgroups.borland.com>...

> Barry Kelly wrote in <3abd46ee_1@dnews>...

Oops, sorry for the heave quoting.

Rudy Velthuis (TeamB)

unread,
Mar 25, 2001, 5:06:24 AM3/25/01
to
Frederick C. Wilt wrote in <3abd3914_1@dnews>...

> 2. Templates are basically code generation. If you think OB needs them write
> a preprocessor and sell it.

No. No no no. No one is asking for templates (at least, I'm not).

BTW, OB = Object Basic? <g,d&r> (see above)

> I have a very usable set of container classes that requires me to override
> only two methods and these are one-liners. If I wanted to it would be
> trivial to create a Wizard that would generate the code for me.

What methods would that be? (I am really serious, since all container
classes I could come up with would require at least 5 or 6 methods per
class to be overridden, and maps would even require a jump through
several hoops at once).



> 3. You have got to be kidding right?

No. He has read the thread that has been going on between Michael Warner
and Guido Gybels in borland.public.discussion (with a few intermezzos by
Deborah and me).

Rudy Velthuis (TeamB)

unread,
Mar 25, 2001, 4:40:53 AM3/25/01
to
Barry Kelly wrote in <3abd13e3_2@dnews>...

> I'm worried that the people in charge of compiler development direction in
> Borland think that interfaces are the solution to all problems generic.

They also seem to think (see Kylix), that variants could be the solution.
of course no compile-time type checking there either. But a lot easier to
use than interfaces.

Barry Kelly

unread,
Mar 25, 2001, 10:16:33 AM3/25/01
to
"William Meyer" <wme...@earthlink.net> wrote in message
news:3abda600_1@dnews...

> "Barry Kelly" <barry_...@hotmail.com> wrote in message
> news:3abd9bf7_1@dnews...

> >...


> > Look at the method implementation (GPL, FreeCLX); it uses:
> >
> > ---8<---
> > TQueue.PushItem(AItem: Pointer);
> > begin
> > List.Insert(0, AItem);
> > end;
> > --->8---

> > ...
> ...


> Looking at that implementation, I would have assumed that List.Insert
must,
> in fact, be based on a doubly linked list -- otherwise, the penalty is
> obvious, and tolerable only in lists of trivial length.

Unfortunately, List.Insert is TList.Insert.

-- Barry
barry_...@hotmail.com

William Meyer

unread,
Mar 25, 2001, 12:13:28 PM3/25/01
to
"Barry Kelly" <barry_...@hotmail.com> wrote in message
news:3abe0bfc_1@dnews...

> > ...
> > Looking at that implementation, I would have assumed that List.Insert
> must,
> > in fact, be based on a doubly linked list -- otherwise, the penalty is
> > obvious, and tolerable only in lists of trivial length.
>
> Unfortunately, List.Insert is TList.Insert.

Yes, I realize, and the penalty, as I said, is clear.

Bill


Loren Pechtel

unread,
Mar 25, 2001, 1:15:57 PM3/25/01
to
>Object Pascal containers, in the effort to be flexible, usually work with
>Pointers, Variants, Interfaces or TVarRec (array of const). They are not
>type-checked at compile time.

Some months ago I was arguing for a solution to this: A keyword
"redeclare". If you declare a function/procedure/property with it,
you do not provide any code, all it does is use the existing code with
the new type specified (like a typecast). Thus you can make versions
of the core objects with the types you want without wasting a routine
that does nothing but pass through the parameter.

Loren Pechtel

unread,
Mar 25, 2001, 1:15:57 PM3/25/01
to
>Every use of TList implies static typecasting.
>Every use of a static typecast is a lost compiler type-checking opportunity.

Personally, if I'm going to make a lot of use of a TList for one
purpose I make a decendant of the right type.

Barry Kelly

unread,
Mar 25, 2001, 10:26:39 AM3/25/01
to
"Rudy Velthuis (TeamB)" <rvel...@gmx.de> wrote in message
news:MPG.1527e18d4...@newsgroups.borland.com...

> No. He has read the thread that has been going on between Michael Warner
> and Guido Gybels in borland.public.discussion (with a few intermezzos by
> Deborah and me).

I don't read .discussion (not enough time), and I only looked through that
thread on .discussion after Deborah mentioned it above.

-- Barry


William Meyer

unread,
Mar 25, 2001, 12:16:25 PM3/25/01
to
"Rudy Velthuis (TeamB)" <rvel...@gmx.de> wrote in message
news:MPG.1527e05ef...@newsgroups.borland.com...

>
> That is C. You'll only see that in API headers.

Let's say that in a perfect world, your statement might be true, but I
*have* seen it in C++. Not claiming that the code in question is exemplary,
only that it exists, and still must be dealt with.

> OP's containers, however sophisticated they might be (some 3rd party
> libraries are), can't come around this deficit.

Yes, as Barry's example has helped me to appreciate.

>
> If we had
>
<code snip>


>
> then we'd probably soon see a vast amount of useful maps, lists, vectors,
> trees, and other containers.

I'm sure you are correct, now that I understand better what is involved.

Bill


Motty Adler

unread,
Mar 25, 2001, 5:24:00 PM3/25/01
to
>>> I've written a preprocessor. However, a preprocessor

How have you written this? using the OTA?

Would you please send me some sample code of how to do this I need it desperetly

Thomas Schulz

unread,
Mar 25, 2001, 1:30:38 PM3/25/01
to
> Will we ever see explicitly instanciated templates in Object Pascal?

I totallly agree this is needed.
After I saw it in a C++ book a few days ago I almost.. almost cryed :)
I don't have the book by hand, so I am unable to write the correct source
here as an example (let me just say - that it isn't that_ ugly to use, just
not very nice).

E.g. imagine a quicksort function with a "callback" for compare.
Now the template defines that any type can be put here in the quicksort.
When the user then uses the algorithm he can define what type he wants..
And volia, with compile-time type checking will ensure you only do that
(e.g. the paramaters you get back in your callback will be of that type).
And your quicksort suddenly works for all_ types.. with type safety without
you have to hassle with casting or runtime performance loss. That is_ kewl.


Regards
Thomas Schulz


Rudy Velthuis (TeamB)

unread,
Mar 25, 2001, 2:16:41 PM3/25/01
to
Rudy Velthuis (TeamB) wrote in
<MPG.152856154...@newsgroups.borland.com>...

> Loren Pechtel wrote in <3abe2ebe...@newsgroups.borland.com>...


>
> > Personally, if I'm going to make a lot of use of a TList for one
> > purpose I make a decendant of the right type.
>

> Sure, but if you need a more complicated container, and multiple types as
> well, you end up writing lots of wrappers. A fully debugged, well
> designed, *generic* container library could do that for everyone once and
> for all.

Michael Warner posted an interesting interview of the creator of the C++
STL in borland.public.discussion. Reading that would give you more
insight in what I mean. Containers, elements and algorithms should be
orthogonal to each other.

Rudy Velthuis (TeamB)

unread,
Mar 25, 2001, 1:24:03 PM3/25/01
to
Loren Pechtel wrote in <3abe2ebe...@newsgroups.borland.com>...

> Personally, if I'm going to make a lot of use of a TList for one


> purpose I make a decendant of the right type.

Sure, but if you need a more complicated container, and multiple types as

well, you end up writing lots of wrappers. A fully debugged, well
designed, *generic* container library could do that for everyone once and
for all.

Or you simply write a container lib, that has wrappers for each
combination of container and element type. Of course for containers like
maps, which have different types for key and value, you'll have to write
a container for every combination as well. <g>

Rudy Velthuis (TeamB)

unread,
Mar 25, 2001, 1:09:33 PM3/25/01
to
Loren Pechtel wrote in <3abe2f0b...@newsgroups.borland.com>...

> Some months ago I was arguing for a solution to this: A keyword
> "redeclare". If you declare a function/procedure/property with it,
> you do not provide any code, all it does is use the existing code with
> the new type specified (like a typecast).

That is similar to what templates in C++ do. You provide a code template,
which is instantiated and compiled as soon as you use it for a certain
type, and will be instantiated with another type, and compiled for that
other type as well. So although you only have one source, the compiler
will generate distinct classes, one for each type it is instantiated for.

Barry Kelly

unread,
Mar 25, 2001, 9:46:44 PM3/25/01
to
"Motty Adler" <MAd...@TheKosher.net> wrote in message
news:3ABE7000...@TheKosher.net...

> >>> I've written a preprocessor. However, a preprocessor
>
> How have you written this?

My preprocessor is very simplistic; it only replaces valid Object Pascal
identifiers with another identifier. It is like a 'smart' replace; it
ignores text inside strings and comments, and only matches whole words. Its
entire purpose was to quickly generate type-safe containers from templates.

> using the OTA?

As Erik Berry told you on delphi.opentoolsapi, you may find this awkward
because of debug information. Looking at what he said:

* start is Erik's FAQ: http://www.gexperts.org/opentools/

> 1. How do I loop thru all source code in a project.
* IOTAProject.GetModule

Looking at through ToolsAPI.pas, I wonder how to get IOTAProject. I see that
there exists IOTAModuleServices; it has properties for looping through all
modules (ModuleCount & Modules[]). I can see that project groups
(IOTAProjectGroup) descend from IOTAModule, so it should be possible to
search Modules[] to get an IOTAProjectGroup. I can see a property of
IOTAProjectGroup called ActiveProject, returning IOTAProject. IOTAProject
has methods called GetModuleCount and GetModule. So, putting all this
together:

---8<---
var
moduleServices: IOTAModuleServices;
projectGroup: IOTAProjectGroup;
activeProject: IOTAProject;
currentModuleInfo: IOTAModuleInfo;
i: Integer;
begin
moduleServices := BorlandIDEServices as IOTAModuleServices;

for i := 0 to moduleServices.ModuleCount - 1 do
if moduleServices.Modules[i] is IOTAProjectGroup then
begin
projectGroup := moduleServices.Modules[i];
Break;
end;

if not Assigned(projectGroup) then
Exit;

activeProject := projectGroup.ActiveProject;
for i := 0 to activeProject.ModuleCount - 1 do
begin
currentModuleInfo := activeProject.Modules[i];
// look at the stuff IOTAModuleInfo has...
end;
end;
--->8---

I've never coded to the OTA before, but it doesn't seem too difficult, as
long as you can find a way of getting from A to B. Ask in .opentoolsapi for
more information if this isn't working, since I don't have time to test it.

What Erik said:

<< I think you are fighting an uphill battle and you'll find that
reliable/convenient macro replacement is near impossible. For example,
you can't restore the code to the original state after the compile
finishes, or the line numbers during debugging will be off if you've
added lines. You might be better served by posting about the exact goal
of macro replacement to the .objectpascal group to see if there is
another method to simulate your macro features using interfaces, etc. >>


> Would you please send me some sample code of how to do this I need it
desperetly

I'll post my simple replacement source code to borland.public.attachments.
SmartReplace (TM <g>) for Pascal, aka 'srpas.exe', is a command-line
utility. The idea is you create a template unit like this:

---8<---
unit GenericUnit; // "GenericUnit.template"

uses SysUtils;

procedure SuperFunction(x: TGeneric); overload;

implementation

procedure SuperFunction(x: TGeneric);
begin
Writeln(x);
end;

end.
--->8---

And then you specialize it like this:

srpas GenericUnit.template IntUnit GenericUnit=IntUnit TGeneric=Integer
srpas GenericUnit.template SingleUnit GenericUnit=SingleUnit TGeneric=Single
...

etc.

The scanner class is constructed with a TStream parameter. The parser class
is constructed with a TScanner parameter. The Exec method of the TParser
class takes a TStream destination parameter. This all means that to'ing and
fro'ing from TMemoryStream or TFileStream should be as painless as possible.
The utility has a total of 677 lines, with lots of comments.

Good luck.

-- Barry

Motty Adler

unread,
Mar 26, 2001, 9:47:52 AM3/26/01
to


> As Erik Berry told you on delphi.opentoolsapi, you may find this awkward
> because of debug information. Looking at what he said:
>

That is not a problem for me because I am going to be replacing comments
Each comment will have to be on a seperate line and therfore Debug line numbvers
will match.

>
> > Would you please send me some sample code of how to do this I need it
> desperetly
>
> I'll post my simple replacement source code to borland.public.attachments.
> SmartReplace (TM <g>) for Pascal, aka 'srpas.exe', is a command-line
> utility. The idea is you create a template unit like this:
>

Thanks. I'll take a look;

Rudy Velthuis (TeamB)

unread,
Mar 26, 2001, 1:03:53 PM3/26/01
to
Loren Pechtel wrote in <3abf7b74...@newsgroups.borland.com>...

> I agree that it's not the optimal solution. However, for
> something seeing a lot of use in your program, I think it's better
> than typecasting all the time.

True. But wouldn't it be even better if there were existing, debugged
code you (and others) could readily use with any imaginable type?

Frederick C. Wilt

unread,
Mar 26, 2001, 11:14:46 AM3/26/01
to
Hello Rudy,

> No. No no no. No one is asking for templates (at least, I'm not).

I am glad (very) to hear that.

> BTW, OB = Object Basic? <g,d&r> (see above)

That will teach me to trust my spell checker!

> What methods would that be? (I am really serious, since all container
> classes I could come up with would require at least 5 or 6 methods per
> class to be overridden, and maps would even require a jump through
> several hoops at once).

I have a class called TBaseItem and a class called TBaseList. I inherit and
extend from these to get TWhateverItem and TWhateverList. In TBaseList there
is a method to add an item and a property access method to retrieve an item.
These can be overridden (I always do) to provide compile time type checking.
If you want you can also override TBaseList.Create and add one line of code
thus making some other features available. The classes are not the ideal but
they have been used in a large number of projects where they have proven
very useful.

I would very much like to see OP have better support for this class of
problem but based on what I have read of C++ templates they are not the
solution I would care to see. I would hope that whatever solution (if any)
would not mangle the lean, mean OP that I have come to admire. As I watch my
fellow workers (who are using VC++ and "Solaris" C++) struggle with the
language, the tools and the (by my standards) very long compile times, I am
grateful that my boss let me chose my own programming tools and that Delphi
is among them.

When I took my current job Delphi was not available and I started my end of
the project (the client side) with BC++ 4.x. The job before that was all
embedded programming using a C compiler for the Intel 8080 family (we used
the Z80 from Zilog). So while I have many years of experience with C, I
never really liked the language, and the additions provided by C++ have not
changed my mind.

Regards, Frederick C. Wilt

Rudy Velthuis (TeamB)

unread,
Mar 26, 2001, 12:11:42 PM3/26/01
to
Frederick C. Wilt wrote in <3abf6b68$1_1@dnews>...

> I have a class called TBaseItem and a class called TBaseList. I inherit and
> extend from these to get TWhateverItem and TWhateverList. In TBaseList there
> is a method to add an item and a property access method to retrieve an item.
> These can be overridden (I always do) to provide compile time type checking.
> If you want you can also override TBaseList.Create and add one line of code
> thus making some other features available. The classes are not the ideal but
> they have been used in a large number of projects where they have proven
> very useful.

Ah, I see. Problem is that normal collection classes have also functions
like Remove and Contains, and indexed classes also IndexOf, Insert, etc.
And then I didn't even mention Push, Pop, etc.

All these methods I mentioned should be overridden to accept different
types. In one design I made, I tried to overcome this by creating wrapper
interfaces, and use these as parameters. Or by creating Accessors, which
only knew how to convert a type to a pointer, and vice versa. All that
required quite a lot of redefining of functions (the accessors would also
store a type ID, which pointed to a class that knew how to compare,
store, retrieve, free, etc. such a type -- one class for each item type).

Although this makes the containers quite a bit more generic, the types
still required a lot of work. And each new type required new, extra work
(and runtime type checking).

> I would very much like to see OP have better support for this class of
> problem but based on what I have read of C++ templates they are not the
> solution I would care to see. I would hope that whatever solution (if any)
> would not mangle the lean, mean OP that I have come to admire.

Here we go. How would they mangle the lean, mean OP? Templates are just
that (templates for real code). During compilation, they are filled with
actual types, and then compiled. So type checking and handling is done at
compile time. Of course that may slow down compilation, but *only if you
use them*. Since (AFAIK all) member functions in the STL are static, they
can also be easily be linked incrementally, I.e. methods not used will be
left out.

> As I watch my
> fellow workers (who are using VC++ and "Solaris" C++) struggle with the
> language, the tools and the (by my standards) very long compile times, I am
> grateful that my boss let me chose my own programming tools and that Delphi
> is among them.

I agree that C++ has long compile times (although using precompiled
headers correctly, like in BC++B, really makes a difference). And the
complexity of C++ is also a problem. But the STL is normally quite easy
to use.

> When I took my current job Delphi was not available and I started my end of
> the project (the client side) with BC++ 4.x. The job before that was all
> embedded programming using a C compiler for the Intel 8080 family (we used
> the Z80 from Zilog). So while I have many years of experience with C, I
> never really liked the language, and the additions provided by C++ have not
> changed my mind.

I guess you should see the current standard. Old C++ was quite a
hodgepodge, current C++, especially since it has an STL, is a rather
modern language.

Loren Pechtel

unread,
Mar 26, 2001, 12:56:42 PM3/26/01
to
>> Personally, if I'm going to make a lot of use of a TList for one
>> purpose I make a decendant of the right type.
>
>Sure, but if you need a more complicated container, and multiple types as
>well, you end up writing lots of wrappers. A fully debugged, well
>designed, *generic* container library could do that for everyone once and
>for all.

I agree that it's not the optimal solution. However, for


something seeing a lot of use in your program, I think it's better

than typecasting all the time. I don't bother for things that see
little use, though.

Frederick C. Wilt

unread,
Mar 26, 2001, 2:09:13 PM3/26/01
to
Hello again,

> Ah, I see. Problem is that normal collection classes have also functions
> like Remove and Contains, and indexed classes also IndexOf, Insert, etc.
> And then I didn't even mention Push, Pop, etc.

For our set of applications every item had to have a unique integer code and
string name. So while I do have Find, IndexOf, Remove etc they all take the
item ID or NAME rather then the item itself. There was no requirement for
Push, Pop though I did provide for Insert. I did provide for run-time type
checking, as compile time option, so if desired you can skip overriding many
methods, and everything still works, you just find out where you screwed up
at run time instead. Assign is provided for but of course this requires
overriding for each XXXItem but once done then Assign for XXXList works. The
classes are certainly not the ultimate answer but they work.

> Here we go. How would they mangle the lean, mean OP? Templates are just
> that (templates for real code). During compilation, they are filled with

Well that would all depend on the implementation I suppose but just for the
sake of argument lets say that the implementation was the product of a very
deranged coder and now instead of a nice fast one pass compiler we had a,
oh, lets say a 32 pass compiler. <g>

--
Regards, Frederick C. Wilt

Rosimildo da Silva

unread,
Mar 26, 2001, 4:17:39 PM3/26/01
to
Danny Thorpe wrote in message <3abfa7eb$1_1@dnews>...
>
>>If we had [generics in the style of C++]

>>then we'd probably soon see a vast amount of useful maps, lists, vectors,
>>trees, and other containers.
>
>You'd also soon see an enormous rise in code bloat, just like templates in
C++. C++ templates do not share code, they multiply code.

Memory and HD space are cheap. Programmers time cost a lot more.

>
>If you want to see the kind of intelligent, efficient generics that the
Delphi R&D team has had sketched out on the whiteboard for quite awhile now,
send email to the Borland exec's to allocate deep research time for Delphi.
In the last two years we've done a lot of product development but haven't
been allotted schedule time for real research. Architecting (and
implementing and testing and documenting) major new language technologies
can't be done on a 3 month product schedule.

This is the big dilemma for Borland. Without many important features such as
Generics, OP would never
take off, and will *always* be a niche language as it is today. Without a
sizeable market share, Borland
probably would never make enough money to do the R&D of such a nice
features.

Rosimildo.

Craig Stuntz (TeamB)

unread,
Mar 26, 2001, 4:06:17 PM3/26/01
to

Danny Thorpe wrote:
>
> If you want to see the kind of intelligent, efficient generics
> that the Delphi R&D team has had sketched out on the whiteboard
> for quite awhile now, send email to the Borland exec's to allocate
> deep research time for Delphi.

Sure, no problem. Thanks for the suggestion.

Of course, everyone on these newsgroups (except me :) will complain if
the next release of Delphi takes more than a year or if the size of a
"Hello, world" program is bigger than D6's, but I'd rather have the
"intelligent, efficient generics."

Looking forward to seeing what you guys come up with,

-Craig

--
Craig Stuntz (TeamB) Senior Developer, Vertex Systems Corp.
Delphi/InterBase weblog: http://delphi.weblogs.com
Use Borland servers; posts via others are not seen by TeamB.
For more info, see http://www.borland.com/newsgroups/genl_faqs.html

Peter N Roth

unread,
Mar 26, 2001, 3:50:42 PM3/26/01
to
"Danny Thorpe" <nor...@borland.com> wrote in message
news:3abfa7eb$1_1@dnews...
>

> You'd also soon see an enormous rise in code bloat, just like templates in
C++. C++ templates do not share code, they multiply code.

yeah, but with templates, the _compiler_ is writing the code, not I.
'Machine code = good, Pete code = who_knows?'

> If you want to see the kind of intelligent, efficient generics that the
Delphi R&D team has had sketched out on the whiteboard for quite awhile now,
send email to the Borland exec's to allocate deep research time for Delphi.

Will do. May we quote you? ;o)

Also I think i'll recommend you for an additional
16 hours / week so you can go up into the hills and relax.
No no, I mean work harder! ... yeah, that's it, work harder.
man this keyboard has a mind of its own
--
Grace + peace,
Peter N Roth
Engineering Objects International
http://engineeringobjects.com


Danny Thorpe

unread,
Mar 26, 2001, 3:34:51 PM3/26/01
to

>If we had [generics in the style of C++]
>then we'd probably soon see a vast amount of useful maps, lists, vectors,
>trees, and other containers.

You'd also soon see an enormous rise in code bloat, just like templates in C++. C++ templates do not share code, they multiply code.

If you want to see the kind of intelligent, efficient generics that the Delphi R&D team has had sketched out on the whiteboard for quite awhile now, send email to the Borland exec's to allocate deep research time for Delphi. In the last two years we've done a lot of product development but haven't been allotted schedule time for real research. Architecting (and implementing and testing and documenting) major new language technologies can't be done on a 3 month product schedule.

-Danny

Barry Kelly

unread,
Mar 26, 2001, 4:46:46 PM3/26/01
to
"Danny Thorpe" <nor...@borland.com> wrote in message
news:3abfa7eb$1_1@dnews...

Danny, first let me thank you for posting. It indicates not only that
someone is listening (something that John K & Anders O assures us is true,
redirecting new information to relevant people), but also that something is
being heard.

> >If we had [generics in the style of C++]
> >then we'd probably soon see a vast amount of useful maps, lists, vectors,
> >trees, and other containers.
>
> You'd also soon see an enormous rise in code bloat, just like templates
> in C++. C++ templates do not share code, they multiply code.

You're right: C++ templates are a programmable type-aware preprocessor, and
not necessarily what is desired when generic containers are wanted.
Type-checking is important for improving compiler checking of program
semantics.

Thinking aloud...

A generic containers parameterized by type vary in several essential ways.

1) Types have special allocation / deallocation / copying semantics. These
types include strings and interfaces. Generic containers pretty much need to
be specialized for these.

2) Different types can have different sizes. This affects allocation, array
indexing, pointer increments, that sort of thing. Containers with different
type sizes need to be specialized.

3) Different types can have different semantics for algorithms. A string
compare is different to an integer compare; a string hash is different to an
integer hash. If algorithms become methods of containers, how can bloat be
avoided where one has types of the same size (object reference) and same
allocation / deallocation / copying semantics (say TObject vs
TMySpecialObject)? The algorithms must (a) be factored away from the
container, and (b) the (hash, compare) semantics should be capable of being
specialized for the type, independant of both the algorithm and the
container.

Allowing containers to share implementations whereever possible is an
engineering problem that can be solved within certain constraints; bloat can
be restricted to where it is necessary; but compile times will suffer <g>.

> If you want to see the kind of intelligent, efficient generics
> that the Delphi R&D team has had sketched out on the whiteboard
> for quite awhile now,

I'm sure many would love to.

> send email to the Borland exec's

Can somebody supply relevant target addresses?

> to allocate
> deep research time for Delphi. In the last two years we've done
> a lot of product development but haven't been allotted schedule
> time for real research.

> Architecting (and implementing and testing
> and documenting) major new language technologies can't be done on
> a 3 month product schedule.

I understand; and I'm afraid that the 'short-termism' in this approach is
hurting current product development because 'better' solutions aren't
possible to implement without generic support.

.NET is slated to have support for generic programming; Java can
(theoretically, of course) be dynamically compiled to efficient code for a
generic container (doesn't help with type-safety though).

I understand your frustrating dilemma; however, I do believe the benefits in
type safety (and the reduced programmer-overhead of overriding of static
methods to simulate type-safety) would include reduced source code size,
increased mantainability, increased compile-time type checking, and
potentially an STL-style library for non-trivial applications; and that
these benefits would weigh heavier over delaying it for much longer.


-- Barry


Stefan Hoffmeister

unread,
Mar 26, 2001, 5:09:14 PM3/26/01
to
: "Barry Kelly" <barry_...@hotmail.com> wrote:

>
>> send email to the Borland exec's
>
>Can somebody supply relevant target addresses?

http://www.borland.com/about/management/

has a few names.



>.NET is slated to have support for generic programming;

Really? Last time I checked they didn't want to have it in. BTW, .net is
not a programming language - C++ is.

I am not certain whether the severely castrated Eiffel# has generics,
VB.not doesn't. VC++ does, but I don't know whether they have generics
in the *managed* environment .

--
Replies that overquote or underquote are ignored.
If you attach any data to your message,
I will never see your message.

Dave Nottage

unread,
Mar 26, 2001, 6:42:07 PM3/26/01
to

Stefan Hoffmeister <Borland.N...@econos.com> wrote:
>>.NET is slated to have support for generic programming;
>
>Really? Last time I checked they didn't want to have it in. BTW, .net is
>not a programming language - C++ is.

In this case, I think you mean C#.

--
Dave Nottage
"2001: A Fruit Odyssey"

Giovanni Pelosi

unread,
Mar 26, 2001, 8:40:14 PM3/26/01
to
from Bruce Eckel's
Thinking in C++ 2 nd edition
Volume 2: Standard Libraries &
Advanced Topics


"Before C++, the most successful object-oriented language was Smalltalk. Smalltalk was
created from the ground up as an OO language. It is often referred to as pure, whereas C++,
because it was built on top of C, is called hybrid. One of the design decisions made with
Smalltalk was that all classes would be derived in a single hierarchy, rooted in a single base
class (called Object - this is the model for the object-based hierarchy). You cannot create a
new class in Smalltalk without inheriting it from an existing class, which is why it takes a
certain amount of time to become productive in Smalltalk - you must learn the class library
before you can start making new classes. So the Smalltalk class hierarchy is always a single
monolithic tree.
Classes in Smalltalk usually have a number of things in common, and always have some
things in common (the characteristics and behaviors of Object), so you almost never run into
a situation where you need to inherit from more than one base class. However, with C++ you
can create as many hierarchy trees as you want. Therefore, for logical completeness the
language must be able to combine more than one class at a time - thus the need for multiple
inheritance.
However, this was not a crystal-clear case of a feature that no one could live without, and
there was (and still is) a lot of disagreement about whether MI is really essential in C++. MI
was added in AT&T cfront release 2.0 and was the first significant change to the language.
Since then, a number of other features have been added (notably templates) that change the
way we think about programming and place MI in a much less important role. You can think
of MI as a "minor" language feature that shouldn't be involved in your daily design decisions.
One of the most pressing issues that drove MI involved containers. Suppose you want to
create a container that everyone can easily use. One approach is to use void* as the type
inside the container, as with PStash and Stack. The Smalltalk approach, however, is to make
a container that holds Objects. (Remember that Object is the base type of the entire Smalltalk
hierarchy.) Because everything in Smalltalk is ultimately derived from Object, any container
that holds Objects can hold anything, so this approach works nicely.
...
A container class describes an object that holds other objects. Container classes are so
important that they were considered fundamental to early object-oriented languages. In
Smalltalk, for example, programmers think of the language as the program translator together
with the class library, and a critical part of that library is the container classes. So it became
natural that C++ compiler vendors also include a container class library. You'll note that the
vector was so useful that it was introduced in its simplest form very early in this book.
Like many other early C++ libraries, early container class libraries followed Smalltalk's
object-based hierarchy, which worked well for Smalltalk, but turned out to be awkward and
difficult to use in C++.

Another approach was required... (extra dots added)"

Dave Nottage

unread,
Mar 26, 2001, 5:19:07 PM3/26/01
to
"Barry Kelly" wrote:
> > send email to the Borland exec's
>
> Can somebody supply relevant target addresses?

dfu...@borland.com

is one.

William Meyer

unread,
Mar 27, 2001, 2:26:19 AM3/27/01
to
"David Farrell-Garcia" <dav...@orcasoftware.com> wrote in message
news:3ac03ec5$1_2@dnews...
> A true craftsman does not shun a
> better tool for a specific job.

A true craftsman doesn't use broken tools, however, and that's the nicest
characterizationI can make of VC.

Bill


David Farrell-Garcia

unread,
Mar 27, 2001, 2:31:00 AM3/27/01
to
Of course such a broad statment is flawed. One could easily make a case that
C++ promotes bad practice, in that it is intrinsically easier to write bad
C++ code. That said, Object Pascal is specifically a language designed to
quickly create applications. If this is your goal then it is a tool that is
hard to beat. A good OP programmer will beat you to market everytime with a
new quality application. However, if you are a systems programmer or
developing a very small specialized high-performance part of a larger
project then C++ may be a better choice. A true craftsman does not shun a

better tool for a specific job.

"Barry Kelly" <barry_...@hotmail.com> wrote in message
news:3abd542d_1@dnews...
> Therefore, object pascal forces bad practice. <g,d&r>
>

Rudy Velthuis (TeamB)

unread,
Mar 27, 2001, 6:52:36 AM3/27/01
to
Craig Stuntz (TeamB) wrote in
<3ABFAF49.1CF9DDF7@no_spam.vertexsoftware.com>...

> Of course, everyone on these newsgroups (except me :)

... and me ...

Rudy Velthuis (TeamB)

unread,
Mar 27, 2001, 6:54:47 AM3/27/01
to
Stefan Hoffmeister wrote in
<i9fvbt0r1chi0pe36...@4ax.com>...

> I am not certain whether the severely castrated Eiffel# has generics,
> VB.not doesn't. VC++ does, but I don't know whether they have generics
> in the *managed* environment .

IIRC, C# is supposed to have some kind of generics.

Rudy Velthuis (TeamB)

unread,
Mar 27, 2001, 6:51:23 AM3/27/01
to
Danny Thorpe wrote in <3abfa7eb$1_1@dnews>...

> You'd also soon see an enormous rise in code bloat, just like templates
> in C++. C++ templates do not share code, they multiply code.

I know. But they reuse (well, copy) written code. The exe is bloated, but
the programmer has a reusable code base.

> If you want to see the kind of intelligent, efficient generics that the
> Delphi R&D team has had sketched out on the whiteboard for quite awhile
> now,

That is good to hear!

> send email to the Borland exec's to allocate deep research time for
> Delphi. In the last two years we've done a lot of product development
> but haven't been allotted schedule time for real research. Architecting
> (and implementing and testing and documenting) major new language
> technologies can't be done on a 3 month product schedule.

Shoot! That is bad to hear.

Do you think that if everyone who wants it sends e-mail to Dale, it might
help?

David Farrell-Garcia

unread,
Mar 27, 2001, 10:13:38 AM3/27/01
to
So now we are talking about IDE's? I thought you were discussing languages.
I will guarantee that given a set of complex business reqirements for an
application, I can bring a quality, finished Delphi application to market
faster then you can with VC. So if you were insane enough to challenge
Delphi on it's real strength you would lose. On the other hand, if the
challenge was to write kernal code or low level systems programming, you
would probabaly do faster job with VC, but then for that kind of programming
the VC IDE is not really necessary. Don't get me wrong, I have nothing
against VC.. in fact I have used it since version 1, but I find that I use
it very little these days as Delphi simply does a better job for what we
do..... and MS must agree.. since they hired top Delphi designers for the
.Net project.. and guess what... C# is more Delphi-like the more I play with
it... except Delphi writes to native, while C# writes to the runtime.


"William Meyer" <wme...@earthlink.net> wrote in message
news:3ac04083$1_1@dnews...

Loren Pechtel

unread,
Mar 27, 2001, 3:24:37 PM3/27/01
to
>>If we had [generics in the style of C++]
>>then we'd probably soon see a vast amount of useful maps, lists, vectors,
>>trees, and other containers.
>
>You'd also soon see an enormous rise in code bloat, just like templates in C++. C++ templates do not share code, they multiply code.

The proposal I made for "redeclare" would not handle all cases,
but it causes *NO* increase in code size.

Harold Howe (TeamB)

unread,
Mar 27, 2001, 4:46:51 PM3/27/01
to

"Barry Kelly" <barry_...@hotmail.com> wrote in message
news:3abfb8c7_1@dnews...

>
> You're right: C++ templates are a programmable type-aware preprocessor,

C++ templates are not handled by the preprocessor like a #define is.
Templates and template instances are handled by the compiler.

H^2
http://www.bcbdev.com


Rudy Velthuis (TeamB)

unread,
Mar 28, 2001, 6:13:54 AM3/28/01
to
"Harold Howe \(TeamB\)" <hh...@bcbdev.com> wrote in <3ac10a27_2@dnews>...

> > You're right: C++ templates are a programmable type-aware preprocessor,
>
> C++ templates are not handled by the preprocessor like a #define is.
> Templates and template instances are handled by the compiler.

I guess he meant: _like_ a programmable type-aware preprocessor. It is
immaterial if the preprocessor is actually involved or not. The mechanism
is the same: code reuse by copy and type substitution.

Mike Margerum

unread,
Mar 28, 2001, 6:39:46 AM3/28/01
to
>So now we are talking about IDE's? I thought you were discussing languages.
>I will guarantee that given a set of complex business reqirements for an
>application, I can bring a quality, finished Delphi application to market
>faster then you can with VC.
I doubt you could say the same thing when competing against C++
builder. If the machine has a lot of memory :) C++ isnt the problem,
Visual c+ is.


Message has been deleted

Rudy Velthuis (TeamB)

unread,
Mar 28, 2001, 7:21:17 AM3/28/01
to
Chee Wee wrote in <3ac1d514_1@dnews>...

> Hey! I like the coding that you've done!
> How can I write to Borland management to ask them to allocate deep research
> time for Delphi for these kinds of features? Saw their names, but are their
> email addresses derived from the first letter of their first name and the
> whole of their last name? eg, dfu...@borland.com, is that correct?

That is the general pattern, yes.

David Farrell-Garcia

unread,
Mar 28, 2001, 12:13:43 PM3/28/01
to
You mean Delphi vs C++ Builder? of course I was talking about VC.. since
he started talking IDE's. You are correct. C++Builder and Delphi would be
an even match.

"Mike Margerum" <mikemblo...@margerum.com> wrote in message
news:3ac1cd36...@newsgroups.borland.com...

Mike Margerum

unread,
Mar 30, 2001, 11:11:41 AM3/30/01
to
>You mean Delphi vs C++ Builder? of course I was talking about VC.. since
>he started talking IDE's. You are correct. C++Builder and Delphi would be
>an even match.
>
Not with anthying less than 256k :) C++ builder was brutal with
128megs. Delphi and buider are both fine tools. VC+ was relegated to
supporting "legacy" apps a long time ago for me :)

Edward Kreis

unread,
Apr 3, 2001, 7:15:34 AM4/3/01
to
"Thomas Schulz" <dk...@hotmail.com> wrote in message
news:3abe3930$1_1@dnews...
> E.g. imagine a quicksort function with a "callback" for compare.
> Now the template defines that any type can be put here in the quicksort.
> ...
> And your quicksort suddenly works for all_ types.. with type safety
without
> you have to hassle with casting or runtime performance loss. That is_
kewl.
>

Have you ever heard about "The Delphi Container and Algorithm Library"
(DeCAL) that is based on STL. It has a lot of "generic" containers as well
as "generic" algorithms, including quicksort.

Link is http://sourceforge.net/projects/decal/

Regards,
Edward Kreis


Rudy Velthuis (TeamB)

unread,
Apr 3, 2001, 8:20:03 AM4/3/01
to
In article <3ac9b0d6$1_1@dnews>, ptx...@mail.ru says...

> "Thomas Schulz" <dk...@hotmail.com> wrote in message
> news:3abe3930$1_1@dnews...
> > E.g. imagine a quicksort function with a "callback" for compare.
> > Now the template defines that any type can be put here in the quicksort.
> > ...
> > And your quicksort suddenly works for all_ types.. with type safety
> without
> > you have to hassle with casting or runtime performance loss. That is_
> kewl.
> >
>
> Have you ever heard about "The Delphi Container and Algorithm Library"
> (DeCAL) that is based on STL. It has a lot of "generic" containers as well
> as "generic" algorithms, including quicksort.

The genericity is simply the use of TVarRec, IIRC. Not really generic
programming, just a way to be able to use different types of parameters.
But it still needs a lot of runtime checks. You could probably use
variants as well, as some simple form of genericity.
--
Rudy Velthuis (TeamB)

0 new messages