Teaching new tricks to an old dog (C++ -->Ada)

  • Thread starter Turamnvia Suouriviaskimatta
  • Start date
C

Chris Jefferson

Matthew said:
Ada 2005 will have both ordered ("sorted") maps and hashed maps. The
current C++ standard only has ordered maps.

Just replying to this point.. The TR1 library edition will also have
hashed maps, although I suspect Ada 2005 might beat it out :) (Although
G++ 4.0 will have them as contained in the (almost) final version of the
TR1 standard).
 
F

Frank J. Lhota

bjarne said:
The Algol I was talking about in that context was Algol68.

Sorry for the confustion. I had assumed that the term Algol would
universally be interpreped as Algol68. Clearly this assumption was wrong,
and I should have added the "68" suffix to clarify the matter.
The result
would have been a more flexible and efficient language than Simula67
and a cleaner language than C++ became. Unfortunately, there was no
chance of such a language succeeding at that time and place - the
understanding of the basic concepts among the intended users and the
infrastructure needed to get work done were missing. It would have been
yet another beautiful, but stillborn, language. C++ was designed in
response to pressing problems, not as a 10-year project aimed at
abstract beauty. I think that in the long run, it actually gained from
that.

Having no Simula67 experience, and no readily available way to get such
experience, I cannot comment on the merits of that language. My exposure to
Algol, however, leads me to believe that it would make an excellent
foundation for a modern OO language. I understand that "Algol68 with
classes" would have virtually no chance of succeeding, although I find the
lack of viability of such a beautiful langage lamentable.
If you want to understand how and why C++ was done, have a look at
Stroustrup: "The Design and Evolution of C++" (Addison-Wesley). If
nothing else, it might help you to avoid revisionist history and wild
conjecture. I think that documenting decisions about major tools is
important and should not be confused with "confessions".

I have read the book, and I can recommend it highly.
 
G

Guest

Ioannis Vranos said:
Myself thinks though that this whole range specialisation thing is
non-sense for regular application programming at least.
Perhaps for your kind of programming, the Ada type model
would be unnecessary. In fact, for many Ada programs, it
is not essential. However, the ability to refine the meaning
of a type, in Ada, is quite useful for many reasons when writing
large-scale software where a lot of people will be involved in
the process.

1. It makes the program more readable because unique
names for types can be given meaningful names.

2. It enforces name equivalence within the type system, rather
than relying on structural equivalence. This deprives the
programmer of many hours of entertaining debugging sessions.

3. One can do simple membership tests on the specified ranges,
thereby eliminating such annoying constructs as:
if X >= 20 and X <= 50 then ...
which sometimes leads to interesting errors.

4. The scope and visibility rules, one of the most powerful features
of Ada for creating safe software, ensure that type names will
not be automatically visible everywhere in the code.

These are just a few benefits. I realize that, any one of these, taken by
itself, might not be impressive. However, in practice, the combined
power of them tends to make it easier to produce fewer errors during
the development process. You might think of this model as an assist
to the programmer in constraining the environment prior to coding in
that environment. Such constraints have proven useful to those who
learn to use them. For those who choose other courses of action,
no amount of argument, proof, or demonstration of benefits will suffice.

Richard Riehle
 
G

Guest

OK. I read your C++ example with care and interest.
Then I compared it, once again, with the example I wrote.

I wonder if you truly think the two examples are equlivalent
in all respects. I must confess that, if the C++ example
were an accurate representation of how one would solve
this problem in that language, I would abandon C++ for
all time.

A key goal of Ada is to produce readable code, not simply
writeable solutions in cryptic code. Who, upon encountering
the C++ example in your post, would be able to quickly
apprehend the meaning, the intent, or the result of this
code?

I rest my case.

Richard Riehle
 
G

Guest

Ioannis Vranos said:
C++ maps on both. However I guess Ada maps on both too since it is a
systems programming language. :)
Rene Descartes originally developed his coordinate geometry in
quadrant One. That worked fine for a long time. When negative
quadrants were proposed, by later mathematicians, many wondered
what they were good for.

The early Greek mathematicians found no use for a number representing
zero. The reason: their number system was based on geometry and
there was no need to represent a non-existent geometrical object.

Some ancient cultures started their own number systems from two
because they saw no point in counting until there was more than
one of something.

There are many cases, in programming, where one wants to map the
solution space to the problem space. In the real world, not every
problem space originates at zero. Quite often, it is useful to define
the solution space beginning with 1 instead of zero. This makes
algorithms for such problems more straightforward. Other times,
one might want to begin the indexing at a number greater than 1.

type Channel is range 2..136;
type Active_Channels is array(Channel) of Boolean;

In practice, particularly in real-time systems, the ability to set the
array index to a range that closely reflects the realities of the
problem space can be quite helpful. It also acts as part of the
self-documenting aspect of the solution space.

Richard Riehle
 
G

Guest

Ioannis Vranos said:
In other words it does not make much sense to have signed indexes.
Otherwise it is easy and possible.
1. Signed indices are extremely valuable when doing certain
kinds of mathematical modeling.

2. Your example did not use "straight" C++. Instead, you relied
on the Vector template. Doing the same thing, in Ada, we
could have multiplied the power of this problem even more.

3. I have so often encountered the question, "But why would you
want to do that? in my career, that I am still amazed when I
hear it yet again.

Regarding number 3, I wish Ada had a good model of multiple
inheritance. I don't mean the somewhat haphazard model of
C++, but rather something like the multiple inheritance of
Eiffel. When someone asks me, wrt multiple inheritance, "But
why would you want to that? it drives me a little crazy.

There are lots of good uses for multiple inheritance. However,
there are also lots of dangers in it. Ada correctly comes down
on the side of safety, but I do sometimes wish it were available.

Richard Riehle
 
M

Martin Dowie

Regarding number 3, I wish Ada had a good model of multiple
inheritance. I don't mean the somewhat haphazard model of
C++, but rather something like the multiple inheritance of
Eiffel. When someone asks me, wrt multiple inheritance, "But
why would you want to that? it drives me a little crazy.

There are lots of good uses for multiple inheritance. However,
there are also lots of dangers in it. Ada correctly comes down
on the side of safety, but I do sometimes wish it were available.

It will have multiple inheritance of interfaces (a la Java) in
Ada2005 - is that enough?

Cheers

-- Martin
 
D

Dr. Adrian Wrigley

1. It makes the program more readable because unique
names for types can be given meaningful names.

2. It enforces name equivalence within the type system, rather
than relying on structural equivalence. This deprives the
programmer of many hours of entertaining debugging sessions.

3. One can do simple membership tests on the specified ranges,
thereby eliminating such annoying constructs as:
if X >= 20 and X <= 50 then ...
which sometimes leads to interesting errors.

4. The scope and visibility rules, one of the most powerful features
of Ada for creating safe software, ensure that type names will
not be automatically visible everywhere in the code.

And you can do really handy stuff passing arrays not indexed from 0,
and accessing the attributes:

-- No particular purpose but to demo
type MyString is array (Integer range <>) of Integer;

procedure UpdateString (Blob : in out MyString; K : Integer) is
begin

if Blob'Length = 0 then
return;
elsif Blob'Length = 1 then
Blob (Blob'First) := Blob (Blob'First) + K;
return;
else
UpdateString (Blob (Blob'First .. Blob'First+Blob'Length/2-1), 19);
UpdateString (Blob (Blob'First+Blob'Length/2 .. Blob'Last), 27);
return;
end if;

end UpdateString;
....
UpdateString (Fred (10 .. 19), 0);

In this case, you make the intent clear which part is being
updated in each level of recursion. You get the bounds checking
in each level, to make sure it is not stepping outside the specific
part of the array passed.

I don't think the C++ equivalent would be so clear, since you would
have to add extra parameters saying what part of the array you are using,
and you would have to add extra bounds checking manually, even
if the container class checked against the overall bounds.

The C++ users who are so concerned about the overhead of storing
bounds in the type have to weigh the cost against storing the
bounds elsewhere and passing them as another couple of parameters.
It's rare that Ada code would have to store bounds which wouldn't
otherwise have to be stored somewhere anyway. (did we cover this already?)
 
J

Jerry Coffin

Peter Amey wrote:

[ ... ]
Actually, a close reading of the thread should have made it clear
that the additional safety is indeed "free". Since the majority
of Ada's checks are compile time they do not impact on run-time
efficiency.

Some of the cited cases provide checks that are free in terms of
run-time, but run-time is hardly the major cost in most software.
Though I haven't done so recently, back when I used Ada, nowhere close
to all of the checks were free even in terms of run-time either.

Furthermore, even when the run-time check itself imposes no extra code
execution, that doesn't mean it's necessarily free in terms of run-time
cost either. Simple economic reality is that writing a good compiler is
NOT a quick, cheap, or simple thing to do. Generally speaking, it's
done to a budget of some sort and time and effort that's put into
compile-time checks more or less directly translates into time and
effort that was NOT put into better code generation and optimization.
This can be ameliorated in a case like GNAT, where the Ada compiler
shares a back-end with something else, but the effect is almost never
really eliminated -- time and effort are almost always limited
resources, so expending them in one way nearly always reduces their
expenditure elsewhere.
Where Ada's goals can only be met by run-time checks these are
no more expensive than equivalent manually-inserted checks in
any other language (and are often less because Ada provides the
compiler with more information by which to judge when they can
safely be optimised away).

Maybe...or maybe not. IME, absolute statements about generalities (e.g.
all implementations of a language) are rarely accurate. Ada compilers
vary quite widely, and I've certainly seen some emit code that included
checks that were logically unnecessary. I'd guess that the current
compilers are better, but perfection in this respect would surprise me.

In the end, my experiece has been that Ada compilers produce _slightly_
worse code in general than C and C++ compilers, but it would take
considerable work to determine how much of this is due to the source
language, and how much simply because their smaller market share
supports less time and effort in optimization. In fairness, I should
add that the differences are rarely very noteworthy. In most typical
situations, if one produces adequately fast output, so will the other.
Of course, if you're dealing with hard real-time requirements and a C++
compiler meets the requrement with only .5% to spare, there's a pretty
fair chance that Ada would fail -- but this sort of situation is
unusual (probably even rare).

[ ... ]
It should also have been clear from the thread that Ada imposes no
limits on expressiveness.

Nonsense -- examples of Ada expressing a few specific concepts have
been given, but this hardly proves a lack of limits. The fact is,
_every_ programming language places severe limits on expressiveness;
anybody who believes otherwise simply hasn't given the subject much
real thought. Programming languages in general express only a small
range of specific actions that are relevant to (most) computers. By
design, none of them is really expressive in areas such as human
emotions.

Even sticking to programming types of things, Ada has some limits to
its expressiveness.

Just for one obvious example, Ada doesn't provide an easy way to
express/do most of the things one can do with the C or C++
preprocessor. It provides some alternative in _some_ cases, but quite
frankly, these are really the exceptions rather than the rule.

Some areas are somewhat more questionable -- calling a class a "tagged
record" is clearly a mistake, but it's open to question whether it
should be classified under poor expression of the concept, or just
general idiocy.

The Ada folks who insist that things should be part of the base
language rather than an add-on library may have strings, but have
nothing equivalent to a dtor in C++. The possible presence of garbage
collection does little to mitigate this, as dtors are useful for _far_
more than just releasing memory when no longer in use. Ada even tacitly
admits to this shortcoming by providing Ada.Finalization in the
library. My understanding, however, is that this requires anything that
wants a destructor be derived from their base class (oops -- their base
tagged record). This may be usable, but it's hardly what I'd call a
clean expression of the concept. In fairness, I should add that I've
never used Ada.Finalization, so my understanding of it may well be
flawed, and corrections about this area would be welcome.

Speaking of strings, I'll digress for a moment: personally, I find it a
bit humorous when Ada advocates talk about things like having five
string types as an advantage. IMO, the need, or even belief, that five
string types are necessary or even useful is a _strong_ indication that
all five are wrong.

Ada's exception handling is also primitive at best (exceptionally so,
if you'll pardon a pun). In particular, in Ada what you throw is
essentially an enumaration -- a name that the compiler can match up
with the same name in a handler, but nothing more. Only exact matches
are supported and no information is included beyond the identity of the
exception.

In C++ you can throw an arbitrary type of object with an arbitrary
value. All the information relevant to the situation at hand can be
expressed cleanly and directly. The usual inheritance rules apply, so
an exception handler can handle not only one specific exception, but an
entire class of exceptions. Again, this idea can be expressed directly
rather than as the logical OR of the individual values. And, once
again, the addition of tagged records to Ada 95 testifies to the fact
that even its own designers recognized the improvement this adds in
general, but (whether due to shortsightedness, concerns for backward
compatibility or whatever) didn't allow this improvement to be applied
in this situation.
Can you say what led you to the opposite conclusion?

Study and experience. Can you say what leads you to believe your own
claim?
 
I

Ioannis Vranos

fabio said:
Ciao,

I think we don't have to care about the presence of a high-level
construct like whatever container. When C++ hadn't yet standardised
containers, everyone could actually build these higher-level structures
by himself. The only problem is standardisation. If you have languages
that are sufficienly low-level like C++ and Ada you can manufacture
every type of algorithm and containers you need.

You build higher-level components by using lower-level built-in
language features. Every compile-time or run-type check that you can
have for built-in types you "inherit" for user created structures. This
is said to answer your past question about Ada having or not same
checks for built-in types and user defined types.

OK.


I suppose std::vector is a simple array which must be copied to a
larger one in order to insert a new element while it is full. You know
it can be done in Ada too.


It is not that expensive. An implementer reserves some more space so as
to avoid frequent reallocations, and vector provides reserve() method to
allocate unitialised space for objects since the beginning by yourself,
if you are going to insert many objects later, so as to avoid
reallocation. For example:


// Contains 10 ints initialised to 0.
vector<int> vec(10);

// Reserves unitialised memory space for 1000 ints in total
vec.reserve(1000);


What's more in Ada is that you can, in a standardised way, directly
create low-level representation of user defined types with a lot of
attributes that C++ doesn't provide. Ada programmers prefer to build
their own types rather than using built-in Integer, Float, Long_Float
(int, float, double) and so on in order to gain a much finer control.

In Ada you can decide representation attributes like range, digit,
delta, mod, address, alignment, size, byte-order (little or big endian)
in record component, and many other things like these. As an example
you can write:

type Counter is new Integer;
for Counter'Size use 48;
for Counter'Alignment use 16;

What's more, you get a compiler error if your machine can't use some
sort of representation you need in order to free you from knowing how
much space a type can provide.

You said that real C++ code hardly need to specify ranges, because you
should be careful not to assign a value that can't be held by a
variable of some specific type. Imagine you have know a variable is to
hold numbers not larger than 99_999 and you choose to store them in an
"int" knowing that you have enough space. When later you port your
program to a machine where "int" is 16 bits you don't have any warning
from a C++ compiler and program run for years until for some reason
that variable is assigned with say 86_000. I think you know what
happens..


The standard guarantees the minimum ranges, for int can hold at least
16-bit values and long at least 32-bit values.

If you had that type declared as "type Var_T is range 0 .. 99_999;", at
the very moment you port your program to this new machine the compiler
would choose the correct size to hold values of that type so program is
no more restricted to this 16 bits C++ "int" and consequently won't
raise this bug.

Do you still think you don't need ranges?


Ranges are a nice thing to have, however if you are provided with
minimum range guarantees, this also does the job.


I would prefer compiler error messages for out of range assignments
though. And I wonder what backwards compatibility (apart from -1
assignment to unsigned integral types) this would break.
 
M

Matthew Heaney

Jerry said:
Speaking of strings, I'll digress for a moment: personally, I find it a
bit humorous when Ada advocates talk about things like having five
string types as an advantage. IMO, the need, or even belief, that five
string types are necessary or even useful is a _strong_ indication that
all five are wrong.

It's the same as in C++:

char[]
wchar_t[]
std::string
std::wstring

The string types in Ada95 are very similar:

String
Wide_String
Unbounded_String
Wide_Unbounded_String
 
I

Ioannis Vranos

Dmitry said:
In general, we use ADT. It is also a recommended practice in C++, BTW. What
would you do with

namelist["Pascal Obry"]="+0 321/45563 ";

or

namelist["321-45563"]="Pascal Obry";


I am not sure what you mean here, input validation should take place
before such assignment.

Note that both Ada and C++ support ADT. Ada's arrays is just an example of
ADT. It is possible in C++ to implement an array as a set of classes though
it will be much more verbose and suffer from numerous drawbacks.


I am not sure what you mean here either.

Of course it does. It is no different. The bounds can be specified either
as discriminants or as generic parameters (the latter has C++ equivalent).
As for the types with discriminants, they can be statically/dynamically
constrained and this is propagated down to the implementation where the
constraints are used. If corresponding methods are inlined then nothing
prevents the compiler from checking statically known bounds at
compile-time.

I seems to me that you still missing the point. Ada's ability to check
bounds is based on the idea of constrained subtypes. It is a fundamental
concept which C++ lacks. (The only weak form of constraining C++ supports
is templates specialization.)


OK then, Ada is probably better in this area.
 
M

Matthew Heaney

Ioannis said:
If it is also defined in std namespace, I am going to smile.

It's declared as a child of Ada.Containers. It's otherwise very
similar to std::vector. (Actually, that's true of all of the
containers in the standard library, since STL was the inspiration.)
 
J

Jerry Coffin

Matthew said:
Jerry said:
Speaking of strings, I'll digress for a moment: personally, I find
it a bit humorous when Ada advocates talk about things like having
five string types as an advantage. IMO, the need, or even belief,
that five string types are necessary or even useful is a _strong_
indication that all five are wrong.

It's the same as in C++:

char[]
wchar_t[]
std::string
std::wstring

The string types in Ada95 are very similar:

String
Wide_String
Unbounded_String
Wide_Unbounded_String

char[] and wchar_t[] are arrays, not strings. C++ really only has one
string type: std::basic_string. std::string and std::wstring are not
types of their own at all, but simply typedefs as:

typedef std::basic_string<char> string;
typedef std::basic_string<wchar_t> wstring;

In addition, one of the major arguments the Ada fans have used here is
that Ada's strings are built-in, NOT added as a class like in C++. If
C++ had been designed from the beginning with a string class, the
array-based "stuff" probably wouldn't exist at all.

BTW, in case anybody really cares, yes I apply the same standard to
C++: while its string handling facilities are fewer and IMO better than
Ada's, they're still far short of perfect.
 
M

Martin Dowie

Jerry said:
Just for one obvious example, Ada doesn't provide an easy way to
express/do most of the things one can do with the C or C++
preprocessor. It provides some alternative in _some_ cases, but quite
frankly, these are really the exceptions rather than the rule.

That 'problem' isn't unique to Ada - I can't think of another
language that *does* define a pre-processor.

And if you like a preprocessor - just use one! You can always write
a makefile/.bat/.com/<whatever> to invoke the preprocessor before the
compiler is called. GNAT comes with an Ada-centric preprocessor but
there is nothing to stop you using the 'C' one.

Ada's exception handling is also primitive at best (exceptionally so,
if you'll pardon a pun). In particular, in Ada what you throw is
essentially an enumaration -- a name that the compiler can match up
with the same name in a handler, but nothing more.

See Ada.Exceptions - perhaps not as elegant but it does the job and
back when the first exception mechanism for Ada was designed, I doubt
there was much call for anything other than a 'this fault has occured'
style exception. At the time, I'd guess that 90%+ of all code in
exsistance was COBOL, C or FORTRAN - none of which had any exception
handling!

Only exact matches
are supported and no information is included beyond the identity of
the exception.

True for Ada83 but not so in Ada95 - again see Ada.Exceptions and
getting expanded again in Ada2005.


And, once
again, the addition of tagged records to Ada 95 testifies to the fact
that even its own designers recognized the improvement this adds in
general, but (whether due to shortsightedness, concerns for backward
compatibility or whatever) didn't allow this improvement to be applied
in this situation.

Almost certainly backwards compatibility - but I'm sure Bob and/or Randy
could shed more light on that...

Cheers

-- Martin
 
I

Ioannis Vranos

Georg said:
A vector has an index range built into the language C++.
It was stated that type based indexing together with
attributes helps both the writer and the compiler.
No programmer effort needed.

Elsewhere you say that it is possible and does make sense
to work around this lack using compile time assertions,
carfully placing them close to the object to which they are somehow
related. (Effectively creating an ad-hoc meta-language written in
templates. Only shows that the thing is indeed missing in C++.)

It makes sense to know the bounds of a container,
possibly in advance. Are you declaring that std::vector and
not knowing the bounds is the only reasonable thing to do in
programming?

Type attributes are a mode of expression, available with
types in Ada. You can build algorithms around language provided
attributes, for example bounds, without having to resort to
mere conventions and the hope that the compiler will do something
useful with the conventional items.


OK, I think you are right. C++ lacks these, and I wonder why additional
keywords enabling this are not added in language proposals for future
standard revision (C++0x).


For fixed size arrays and containers it is true, the compiler does not
catch at compile time any out of boundaries access. However we can do
this explicitly, by using compile-time checked assertions.


In other words, C++ array like types don't have these properties.
I'm not saying this is catastrophic. It's just not available
unless you roll your own. This has consequences for how you write
your software. It has consequences for what your compiler can do.
Some of them are interesing, because of template computing.

May you give an example for a container along with such a subtype?


It was given, starting this "sub"thread.
Here you can see one point that you might want to demonstrate:
The compiler won't tell you that there is something wrong
with

doors[10].SetOpen().SetNoVan();

Worse, the program won't tell you either. This shows the missing
link between vector indexing and the base type system in your
approach. You could use

doors.at(10).SetOpen().SetNoVan();

and handle the exception _at run time_.
In Ada, the compiler will tell you: "index value 10 is no good!"
because the array "doors" can only be indexed by values effectively
between 0 .. 9. These and only these are the values of the type
enumerating the ten doors, and only these are allowed as index
values x in expressios doors(x).
No exception handling, no .at() needed when you listen to your
compiler and fix the indexing error before you deliver a program.
You get this for free as a result of the language's type handling
at compile time.


Will the Ada compiler tell you this, for user-defined types too?


An enum is a user defined type.
Any unconstrained type (including more than array types)
entails constrained objects, and the compiler may have a word
in this.
Maybe, if one gets used to template programming, the basis of the
language is deliberately ignored?
Ada just doesn't need templates for many things that are tried
using templates in C++, because the things are already in the
language.

Or is this restricted to built-in arrays? If the latest is true, then
its value isn't that much.


Every bug that is found at compile time is worth a lot
to me.

Try telling someone that useful array attributes, and type attributes
and object attributes in general, aren't of much value.
What else are .begin() and .end() other than roll-my-own replacements
for something that C style arrays lack, *language-wise*?
Those working for an insurance company, in a stocks related business,
in math related computing, statistics, etc. use *Array Programming
Languages*. Why would they be doing this if good array support
isn't worth something? What is the value of good array support in
all those valuable Fortran computing libraries?

Are you saying that a robust base type system isn't worth it because
of the STL?
Consider the effort is takes to get a useful STL made of
basically, at-least-so-many-bits integers, pointers, and malloc().

Please answer this question:
Why is vector not implemented using vector? (I'm serious.)


OK I get your point, and you are right. These things would be nice to
have in C++, and I think it is possible to have them just by introducing
new keywords in the language, without breaking backwards compatibility.
I do not know why there is no proposal for these.


The fastest possible element access in C++ is dereferencing a pointer.
The fastest possible element access in STL/C++ is varying with container
and method.

Compare

type Floor_Number is -2 .. 52;
-- sky scraper

type Door_Count is array(Floor_Number) of Natural;

versus

typedef char Floor_Number;
typedef std::map<Floor_Number, unsigned int> Door_Count;


char does not feel well, one could use short but probably will use int.


We are discussing fastest access, and type based indexing.


I can't understand why your code has faster access (I assume you mean
run-time efficiency).

So my question again, what does it take, in C++, to replace
Floor_Number as typedefed above with something that matches
the given building's floors exactly?


I assume a vector that permits defining negative indices, and this is
easy to be defined. However I may assume that since no such vector
container is provided (even third-party), I may assume that either it is
not considered as needed, or it is believed that maps and hash_maps can
do the job.


To give another example, .NET does not provide such an array container
either, in its own containers collection. So why such a mainstream
framework does not provide an array type with negative indexing either?


This is not some kind of general proof, but for me it is an indication.
Again, I agree that boundary checking etc are useful and should be added
in C++ perhaps with additional keywords.

The point is, how does a language help you writing
correct and efficient programs. C++ the language doesn't
have fixed size built in arrays. In some problem domains,
fixed size arrays are very useful, if not essential.

This is why many programming languages have them.



Just to be technically accurate. C++ has fixed size built in arrays. It
doesn't provide range checking for them though.


int array[4];

is a fixed size, stack based, built in array.


Fixed size in the heap:

int *parray= new int[4];


Also, standard library containers with fixed size are valarray and bitset.
 
I

Ioannis Vranos

Martin said:
It will have multiple inheritance of interfaces (a la Java) in
Ada2005 - is that enough?


For application programming only, it is usually enough. I am not sure if
in library writing it is enough though.
 
I

Ioannis Vranos

OK. I read your C++ example with care and interest.
Then I compared it, once again, with the example I wrote.

I wonder if you truly think the two examples are equlivalent
in all respects. I must confess that, if the C++ example
were an accurate representation of how one would solve
this problem in that language, I would abandon C++ for
all time.

A key goal of Ada is to produce readable code, not simply
writeable solutions in cryptic code. Who, upon encountering
the C++ example in your post, would be able to quickly
apprehend the meaning, the intent, or the result of this
code?


Believe it or not, I do not understand most of Ada code, apart from some
Pascal-like constructs here and there. :)
 
I

Ioannis Vranos

Martin said:
That 'problem' isn't unique to Ada - I can't think of another
language that *does* define a pre-processor.

And if you like a preprocessor - just use one! You can always write
a makefile/.bat/.com/<whatever> to invoke the preprocessor before the
compiler is called. GNAT comes with an Ada-centric preprocessor but
there is nothing to stop you using the 'C' one.


Here is an interesting link BTW:

http://boost-consulting.com/tmpbook/preprocessor.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,666
Latest member
selsetu

Latest Threads

Top