Future of C++

J

James Kanze

That's simply not true. My (and other teams) experience is
that a pair is more productive then two individuals.

In pure code production? And on what types of projects---I find
that at certain points, the limiting factor of my production is
typing speed. Maybe your work is different, but a lot of what I
do really isn't rocket science; the coding is fairly obvious
once the exact requirements are defined.
One programmer will continue working on the same story when
the pairs rotate, so there is always someone who knows the
code working on it.

I wasn't so much worried about knowing the code, as about the
original programmers getting actual feedback as to how readable
there code was for someone coming from the outside. It's still
necessary, at some point, that someone totally unfamiliar with
the code read it, and try to understand it without the aid of
the original programmer(s), and then provide feedback to the
original programmers from that point of view.
When your code is continuously reviewed the same is true.

It doesn't have to be contiuous, but obviously, when you first
start, reviews have to be fairly frequent. The whole point is
that the programmers learn to write code for others, so that in
the future, you don't need reviews to be so frequent.
In XP teams, the team owns the pride :)

As long as it doesn't mean that the individuals are shrugging it
off, saying the team will take care of it. You need individual
pride of accomplishment somewhere.
To stretch the analogy further, teams function better with
player who know when to pass the ball rather than run with it.

Certainly. What you want to do is instill a sense of pride
about knowing when (and how) to pass the ball.
That's true, but one of the strengths of pair programming is
two minds working on the same problem are less likely to
block, or waste time going up a blind alley.

That's true, and I can see it for some types of programming,
perhaps, at specific instances. But if the atmosphere is good
(and the programmers are used to writing code for others to
read), as soon as you block, you go to the next office and
brainstorm. You don't need pair programming for that.
But think how much more you would learn if you had been
writing the code with the reviewer. Pairing gives you all
those benefits you get from reviews, all the time rather than
in short bursts.

Except that the additional benefits are small. You get most of
the benefit from the review, without the added cost of tying up
two people full time.
I really enjoy pairing with inexperienced programmers. That's
probably because I enjoy mentoring. It's amazing how quickly
they learn and improve. I can't conceive of a better way to
accelerate the learning process than pairing with a more
experienced peer. The same also applies to new team members,
they can contribute from day one without having to read
through mountain of documentation.

Mentoring is a good use of pair programming (but not a new one:
I was "pair programming" with a new hire back in 1988). But
hopefully, your people don't need mentoring their entire career.
Again, think how much faster they learn working in pairs with
the more experienced ones.

Certainly. I'm all in favor of mentoring for beginners (and to
a lesser degree, for new hires with experience). If half of
your shop are new hires, I guess that would mean pair
programming. (But if half of your shop are new hires, I think
you have a turnover problem.) Even beyond that, I'm sure that
it's a good solution for specific problems or cases, and I've
used it as such in the past. But it's not an absolute, and for
a lot of what I do, it just ties up two people where one would
suffice, for very little additional gain.
 
P

Pavel

James said:
James said:
[...]
That's why you need a development process, and to pay
attention to software engineering issues. Good code review
can do wonders in this regard. Greater expressivity does
allow more ways of screwing things up, but it also allows
more effective solutions. The trick is to manage things so
you get the benefits without the costs.
Yes, I have heard above this free cheese before -- but have
never eaten one :).
In other words, you've never actually worked in a place
which had a good software development process in place.
I guess, I am a poor guy -- not only in software development
but never in real life did I see benefits without the costs.

You were the person who talked about 0 cost.
No, that were you. I just cited literally from your "The trick is to
manage things so you get the benefits without the costs."

There's no way to
develop software for free. But a good process reduces cost, and
results in more maintainable code.
It is always a trade-off (as we agreed the process is not free). If we
now both agree the processes, training etc are not free, the question
"which language requires a more expensive process to achieve the goal of
a particular project or a series of projects (a program)" makes sense.
My answer is the C++ is a good candidate (for the most costly language
in this sense).
Obviously not. Where did I say that? Code review is a process
which involves people.


But that's exactly what I said: you need a software process (to
manage people), regardless of the language, and the process is
more important than the language. Only once you've got that can
you begin to discuss the various advantages and disadvantages of
the different languages.
No, you mentioned managing "things" (and my guess was that by that you
probably meant processes). It is the first time you mention managing
people. My point was that people and especially people who produce best
results under favorable circumstances (best talents) are often quite
picky about processes. It is not that they deny the processes but they
feel entitled to specify their own processes, may disagree on them, may
not be willing to compromise on them and get upset and leave
organization when the other person's process "prevails". So, the less of
a process is required by the selected tool to achieve results ultimately
the better and may be a criterion of the tool selection.

I do not try to trivialize, of course, a tool may offer good things in
exchange for requiring a complicated process and C++ does offer some. It
is just that it often has occurred to me (and often closer to the end of
the project) that it did not offer enough.. basically it was not worth
the trouble. All about cost/benefit analysis and everybody's mileage --
that's why I was trying to initiate some exchange of experiences less
than of opinions.
[...]
A programming language that is extra "expressive" and
"concise" has difficulties attracting practitioners. Who other
than a scientist really would want to line up all definitions
and then apply a zillion of rules of overloading in a specific
order in their sane minds to determine the "Best Viable
Function" (see 13.3.3. of the Standard)

A lot of computer scientists:). A lot of them tend to think of
it as a challenge, or fun.

Of course, from a software engineering point of view, it's
wasted effort. You don't bother with the exact details of the
rules of overload resolution when you're developing code,
See, that is what apparently those guys who wrote the code that then
gives trouble to its reader did -- they did not bother to know how many
"candidates" for BVF a potential reader will have to keep in mind to
understand the code. I think I already repeated it multiple times during
this discussion that the difficulties with C++ I has been pestered with
were not writing but reading the code written by others -- and the
primary purpose of any source code is to be read -- otherwise why to
have it at all?
because you don't overload unless it doesn't matter which
function will be called. (To a certain degree---obviously, if I
am working in double, it would matter if sin(float) were called
instead of sin(double). But we more or less count on the final
results of overload resolution being somewhat sensible, at
least.)

More generally, C++ is overly complicated, and offers a lot of
possibilities for obfuscation, if that's what you want. But you
don't have to use them;
I don't ( of course not :) ). But the other guy might -- and will with
the probability increasing with the size of the project. It is just an
incredible luck to never have a person who does not care enough or
simply does not fully understand the [complex] process on a team of a
significant size during a significant time period (both are required for
sizable projects).
the KISS principle applies when writing
C++ as well, and you shouldn't use a feature of the language
except when it makes the code simpler and more easily
understood. (And code reviews are a very effective technique
for ensuring this.)
Yeah that's what I am doing much of my time.. but some people leave
after code reviews and some even before :-(.. so I would rather read a
language with less potential for obfuscation.

Getting readable code from the first time would be so much more
effective in many regards that I wonder whether C++ additional benefits
cover this obfuscation potential.
Thus, for example, overloading the binary + operator (and the
other arithmetic operators) for BigDecimal definitly makes the
code more readable.
Yeah, but insignificantly. I would live with

a.add(b).add(c);

instead of
a = b + c;

even though the former is *little* less readable.

But guess (honestly, without trying), what the following trivia will print:

#include <streamline>
#include <string>
using namespace std;
int main(void) {
string a = "35" + 2;
cout << a << endl;
return 0;
}

(compiles and run without a warning on my cygwin, g++ 3.4.4). Then tell
me how much time it took you to guess. What if you replace '2' above
with '1'?

So I have my doubts about the usefulness of overloading..
 
P

Pavel

#include said:
#include <string>
using namespace std;
int main(void) {
string a = "35" + 2;
cout << a << endl;
return 0;
}

Sorry, this was
----------
#include <iostream>
#include <string>
using namespace std;
int main(void) {
string a = "35" + 2;
cout << a << endl;


return 0;
}
----------

I did not type, honestly -- but somehow was stupid enough to allow my
spellcheck to replace "iostream" with "streamline".. even old man makes
mistakes

-Pavel
 
P

Pavel

James said:
On Aug 12, 8:06 am, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:

Google won't let me post a detailed answer to all your points;
it's too long. So I'll just summarize a few of the more
pertinent ones...

First, I won't bother going into which language is more popular,
or growing, or shrinking, or whatever. Neither of us have the
gift of prophecy, so in the end, the only real factual statement
we can make is "we'll see". I just don't see C++ dying out any
time soon, especially since Microsoft has embraced it (at least
in name---perhaps in the future, will all be programming in
C++/CLI:)).

Second, with regards to the function "increment":

-- Even in the case of Percentage, the way C++ spells it is
Percentage::eek:perator++()
Does it? Did you solve my puzzle

#include <iostream>
#include <string>
using namespace std;
int main(void) {
string a = "35" + 1;
cout << a << endl;
return 0;
}

?

Perl would give one of intuitively expected answers -- see

perl -e 'print "35" + 1'

and Java would give the second one (you can certainly come up with the
code itself). Bad enough (Python reports the error in clear language
(TypeError: cannot concatenate 'str' and 'int' objects) -- one of the
reasons it is my favorite from syntactic viewpoint), but none of these
goes as far as C++. Now tell me honestly C++ is most expressive here --
and I only used overloads The Standard Library offers. Of course your
"C++ way" goes much further:

To inter-operate between your Percentage class and other "glorified"
numbers (say, to multiply percentage to some quantity or whatever) you
will have to overload helluva lot of operators and/or allow same amount
of conversions. The consequences for a reader of the code including
<percentage.h> (and maybe <quantity.h> and all other thinkable types of
things of which percentage can be taken in a single source) is a
guaranteed headache. Plus I doubt an author can actually foresee all
such consequences. So, I would rather go with my version in C++, whether
it is "the way C++ spells.." or not, in your opinion. It is certainly
imperfect but IMHO much closer to "perfect" than introducing Percentage.
:) (but that's really neither here
nor there---there are definitely functions which modify
state, for which there is no pre-defined operator).

-- Functions which modify state are normally members. You
don't write increment( object ), but rather
object.increment(). At least in principle: there are times
when, for various reasons, it's not possible, but it does
mean that the number of times the question comes up is
greatly reduced.
No, you are confusing the number of times you would *use* the non-const
reference as a parameter and the number of times I had to review the
code using such references written by someone (who was not you).

Until there is no such sanction as disbarment in C++ as opposed to
legalese (even though the former might not be much simpler than the
latter), the easiness with which such mines are planted keeps and will
keep a lot of practitioners and managers away of C++. Not that I would
support such kind of regulation..
-- A function named "increment" increments, i.e. it modifies
state. Otherwise, it would have a different name, e.g.
"incrementedValue", or borrowing from Pascal "successor"
(which is better depends on the semantics of the object).
If for some reason it is not a member, it takes a non-const
reference as parameter. Period. You don't have to look
further.
Then why to look at all? Just assume (as you just did) and put your
signature?
-- A function which modifies state is not used in more
complicated expressions: if it returns a value, it is the
old value, to allow client code to restore it. In the case
of increment, this is silly, of course, because if you know
the new value, you know the old. But in the case of things
like std::ios_base::setf(), etc., it's very useful. In the
case of member functions of objects with identity, it's
sometimes useful to return *this, to allow chaining, but
that's about the only case I can conceive of where you'd
return the "new" value.
And so you would just assume the person who wrote the code you are
reviewing conceived same way as you and write your name on the dotted line?
For the rest, expressivity is there for you to use, when
appropriate. It can obviously be abused, but that's not the
point.
That exactly is my point that you are trying to avoid by all means. I
already agreed with all your points that C++ has a lot of powerful and
"cool" features (you can call them expressive but I would be more
comfortable if you used this term consistently with some definition
preliminary agreed on between us. ( think, for example, that overloading
is closer to anti-expressiveness than to an expressiveness as it creates
ambiguity about which you will probably agree that it is an opposite to
expressiveness). In fact, I have never argued with them.

But even accepting your language, here is an extreme example: Atomic
bomb is very powerful and expressive, maybe even more powerful and
expressive than C++ so let's let everybody use it; abuses are not the
points and their victims are not "correct" victims; they probably simply
needed more experience or did not understand something.
It is the responsibility of the development process to
ensure that it is not. And you need the development process,
regardless; abuse of expressivity isn't the only way you can
foul up a project, far from it.
Of course not; but in my experience it is an often way enough to be
concerned with it. "Development process" is not a legal subject of being
responsible; people are, but they happen to have different priorities
and different ideas about what the development process should be.
Expressivity is a positive
feature, always. (That doesn't mean that C++ doesn't have other
problems. But expressivity, or the lack of it, certainly isn't
one.) The most obvious proof (except that it probably doesn't
prove anything about software engineering, but more likely
something about social psychology) is that all languages evolve
in the direction of increasing expressivity: Java has corrected
some of its problems, for example, by adding to the language
(e.g. templates), and will doubtlessly continue to do so if it
is to survive (and even if it just survives---today's Fortran is
a far more expressive language than the one I learned in the
1970's).

If you want to discuss specific problems in C++, fine. There's
certainly no lack of subject matter. But too much expressivity
is NOT a defect, it's a definite advantage.
No, seriously, let's define "expressivity". If C++ has too much or too
many of anything, IMHO these are features (many of which are certainly
useful) and the ambiguities they create for a reader who cannot keep all
contents of all headers in his/her head (and I have never met anybody
who could in my life).
And for the most
part, the points you've raised are points where C++ has a
definite advantage. (You can't write your increment() function
at all in Java, for a built in type. So if even discussing the
function has any relevance, Java is at a disadvantage.)
Again, your definition of "advantage" seems to be different from mine
and close to "having more useful features" (please correct me if I am
wrong). Java has less (syntactic) features than C++, no doubts here;
however this is one of its properties that makes it attractive to
project managers (who need to hire people, maintain old code, all at
fixed costs, etc). BTW It can still express all the same programs except
for system-level ones (the latter is not due to the lack of features).
(One last comment, with respect to using forward declarations in
C. Been there, done that. While they're obviously the way to
go for entity objects, you can't implement true value semantics
using forward declarations. Which is a major drawback if you
want or need value semantics.)

Certainly not. If I need *pure* value semantics I can simply use
structures. And for "hybrids" (say, structures with integral and
variable-length strings data members) it is always safer and often more
efficient to honestly treat them as "entities" (I am not sure this is a
common term, I would use "objects" but let it be) which they are -- in
any language. C++ provides convenience here (in comparison to C), I am
not arguing -- but only a "constant size" convenience, so to say. If I
Objects (with constructors & destructors) were only differences in C++,
I would take it instead of C..
--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

-Pavel
 
I

Ian Collins

Pavel said:
Yeah, but insignificantly. I would live with

a.add(b).add(c);

instead of
a = b + c;

even though the former is *little* less readable.
Until you use BigDecimal as a template parameter of a class or function
template that attempts to add two of them. The ability of a user
defined type to mimic built in types is one of C++'s original goals and
a very useful attribute.
But guess (honestly, without trying), what the following trivia will print:

#include <streamline>
#include <string>
using namespace std;
int main(void) {
string a = "35" + 2;

The address of the string literal "35"+2, which will be '\0'.
cout << a << endl;
return 0;
}

(compiles and run without a warning on my cygwin, g++ 3.4.4).

As it should.
Then tell me how much time it took you to guess.

Less time than it took to write this!
What if you replace '2' above with '1'?

The address of the string literal "35"+1, which will be '5'.
 
J

James Kanze

James said:
James Kanze wrote:
[...]
That's why you need a development process, and to pay
attention to software engineering issues. Good code
review can do wonders in this regard. Greater
expressivity does allow more ways of screwing things up,
but it also allows more effective solutions. The trick
is to manage things so you get the benefits without the
costs.
Yes, I have heard above this free cheese before -- but
have never eaten one :).
In other words, you've never actually worked in a place
which had a good software development process in place.
I guess, I am a poor guy -- not only in software development
but never in real life did I see benefits without the costs.
You were the person who talked about 0 cost.

Poor wording on my part. That should have been minimal cost.
In fact, a good process does reduce costs, significantly more
than it costs.
No, that were you. I just cited literally from your "The trick
is to manage things so you get the benefits without the
costs."
It is always a trade-off (as we agreed the process is not
free). If we now both agree the processes, training etc are
not free, the question "which language requires a more
expensive process to achieve the goal of a particular project
or a series of projects (a program)" makes sense. My answer
is the C++ is a good candidate (for the most costly language
in this sense).

Actual measurements show that it costs less to develop software
in C++ than in Java or C. Of course, those measurements really
only apply to the types of projects they were made on. All of
the ones I've seen have been made on large projects, for
example. And none in a domain where there is special
development support for Java. But it still would indicate that
at least in some domains, C++ should be preferred over Java or
C, at least on the basis of cost.
No, you mentioned managing "things" (and my guess was that by
that you probably meant processes). It is the first time you
mention managing people.

It seemed rather obvious. That's what you do manage, normally.
All "management" is managing people.
My point was that people and especially people who produce
best results under favorable circumstances (best talents) are
often quite picky about processes.

Of course they are. I far prefer working in a well managed
environment, where communication is encouraged. That's really
part of what being competent is all about. Being a team player,
and working within the framework of a well managed environment.
It is not that they deny the processes but they feel entitled
to specify their own processes, may disagree on them, may not
be willing to compromise on them and get upset and leave
organization when the other person's process "prevails".

Such people are not adults, and aren't capable of writing
anything worthwhile. Fire them, immediately.

In practice, such people are rare. Most people like the feeling
of success, and a good, well run process leads to success. And
what's nice about a good, well run process, as well, is that
average programmers also perform well.
So, the less of a process is required by the selected tool to
achieve results ultimately the better and may be a criterion
of the tool selection.

But no less process is required because of a tool. A process is
management; management is people, and tools don't control how
people work.
[...]
A programming language that is extra "expressive" and
"concise" has difficulties attracting practitioners. Who
other than a scientist really would want to line up all
definitions and then apply a zillion of rules of
overloading in a specific order in their sane minds to
determine the "Best Viable Function" (see 13.3.3. of the
Standard)
A lot of computer scientists:). A lot of them tend to
think of it as a challenge, or fun.
Of course, from a software engineering point of view, it's
wasted effort. You don't bother with the exact details of
the rules of overload resolution when you're developing
code,
See, that is what apparently those guys who wrote the code
that then gives trouble to its reader did -- they did not
bother to know how many "candidates" for BVF a potential
reader will have to keep in mind to understand the code.

You misunderstand. You don't care how many candidates there
are, nor which one ultimately gets picked. If it makes a
difference, the functions have different semantics, and thus
different names.
I think I already repeated it multiple times during this
discussion that the difficulties with C++ I has been pestered
with were not writing but reading the code written by others
-- and the primary purpose of any source code is to be read --
otherwise why to have it at all?

And it has been shown repeatedly that it is not difficult to
write very readable C++. Because C++ is so expressive.
I don't ( of course not :) ). But the other guy might

Which is why you have a process. So that the other guy doesn't.
But the fact that the other guy might do something stupid
doesn't depend on the language. You're worrying about the small
stuff, and ignoring the big. If the other guy names his
functions f1(), f2()... etc., for example.
-- and will with the probability increasing with the size of
the project. It is just an incredible luck to never have a
person who does not care enough or simply does not fully
understand the [complex] process on a team of a significant
size during a significant time period (both are required for
sizable projects).

I can see you've never worked with any sort of process. It's
extremely rare to find someone who intentionally wants to make
life hard for others. And the process ensures the necessary
communication so that he knows what others expect. It's like I
pointed out to Ian, in a different subthread, concerning one
aspect of a good process: the programmers very quickly end up
writing code to be read.
Yeah, but insignificantly. I would live with

instead of a = b + c;
even though the former is *little* less readable.

That's an overly simple example.
But guess (honestly, without trying), what the following
trivia will print:
#include <streamline> #include <string> using namespace std;
int main(void) { string a = "35" + 2; cout << a << endl;
return 0;
}

Agreed. Logically, it shouldn't compile, and without the
constraints of C compatibility, it probably wouldn't. But the
equivalent code also compiles in C and in Java, with equally
unexpected results. (For that matter, I can't really figure out
what the expected results should be, other than failure to
compile. Adding a string and an int makes no sense at all.)
(compiles and run without a warning on my cygwin, g++ 3.4.4).
Then tell me how much time it took you to guess.

Well, I worked in C long before I'd heard of C++, so I'm pretty
familiar with pointer arithmetic, and spotted it right away.
(Without guessing.) But I can imagine that most people, on
seeing it, would imagine that it wouldn't compile, or that, if
it did, you'd get 37. (Basically, in a strictly typed language,
it shouldn't compiler, in a weakly typed language, say like perl
or AWK, you'll get 37. Anything else is a design error in the
language. As is allowing it to compile if the language is
otherwise typed, like C++ or Java.)
What if you replace '2' above with '1'?
So I have my doubts about the usefulness of overloading..

What does this have to do with overloading? It's a problem of
pointer arithmetic, and the fact that in C++, for historical
reasons, "..." doesn't have the type string. But first and
foremost a problem of pointer arithmetic.
 
J

James Kanze

Sorry, this was
----------
#include <iostream>
#include <string>
using namespace std;
int main(void) {
string a = "35" + 2;
cout << a << endl;
return 0;}
----------

But I understood what you were getting at. A point where I
agree that C++ has a weakness: pointer arithmetic has no place
at the application level.

It's an interesting point, however, because Java is just as bad
here, and it doesn't have pointer arithmetic.
 
J

James Kanze

Until you use BigDecimal as a template parameter of a class or
function template that attempts to add two of them.

Even without the template. What happens if you started out
using double, then changed to BigDecimal because of later
constraints?

Not to mention that the example is overly simple. Try writing
something like (-b + sqrt( b*b - 4*a*c )) / (2*a) without
operator overloading. (And strange as it may seem, some
programs actually use expressions like this---or more
complicated ones.)
The ability of a user defined type to mimic built in types is
one of C++'s original goals and a very useful attribute.
The address of the string literal "35"+2, which will be '\0'.

You've got considerable C experience as well:).
As it should.

According to the C++ standard. Whether that's a good thing or
not is debatable.

Try the same thing in Java:

class Test
{
public static void main( String[] args )
{
System.out.println( "35" + 2 ) ;
}
} ;

It also compiles and runs. With different, but equally
surprising results:).

Pavel's right about this one: it shouldn't compile in any
language which is statically typechecked. (In more dynamic
languages, of course... ` print "35" + 2 ' prints 37 in AWK.
Which is what I would expect, given the total absence of typing.
Which is fine for small projects---I regularly use AWK for up to
around 500 lines of code---but doesn't scale well.)
 
I

Ian Collins

James said:
You've got considerable C experience as well:).
Not really, only about 28 years :)
According to the C++ standard. Whether that's a good thing or
not is debatable.
But in this case, the string literal decays to a const char*, so no type
checking rules are broken.
Pavel's right about this one: it shouldn't compile in any
language which is statically typechecked. (In more dynamic
languages, of course... ` print "35" + 2 ' prints 37 in AWK.

As well as every scripting language I know.
Which is what I would expect, given the total absence of typing.
Which is fine for small projects---I regularly use AWK for up to
around 500 lines of code---but doesn't scale well.)
Try PHP, I'm in the middle of a several thousand line PHP/JavaScript
application at the moment. The lack of type checking is both liberating
and dangerous. Thank goodness for unit tests, they take the place of
the compiler!
 
P

Pavel

James said:
But I understood what you were getting at. A point where I
agree that C++ has a weakness: pointer arithmetic has no place
at the application level.

It's an interesting point, however, because Java is just as bad
here, and it doesn't have pointer arithmetic.
My point is actually about operator overloading and implicit
conversions.. I would be fine with the pointer arithmetic as long as it
could be unambiguously seen from the code that the pointer arithmetics
takes place here and what particular arithmetics.

My example with Java vs C++ vs Python vs Perl just shows that the
expressiveness is far from universal, it is more subjective. Some people
believe concatenation should be done with operator + (C++, for strings
only, Java), some believe it should be done with ..
(Perl), some (SQL) prefer || (SQL cleverly offers CONCAT() as an
alternative). C++ seems to be the worst here as + can mean all but
anything, without even user-defined overloads.

But nobody yet died from typing concatStrings(s1, s2). Not too cool? I
prefer safety and clarity to coolness in engineering (the result
sometimes needs to be cool, but the tools helping to produce it do not
have to).

-Pavel
 
P

Pavel

Ian said:
Until you use BigDecimal as a template parameter of a class or function
template that attempts to add two of them. The ability of a user
defined type to mimic built in types is one of C++'s original goals and
a very useful attribute.
I know. But the consequences are
For using in generic algorithms, functions and function objects can be
used everywhere fit more than operators (I would rather define a
function or a functor for built-in types -- which C++ Standard Library
sometimes smartly does.
The address of the string literal "35"+2, which will be '\0'.
It's not the address, but the value, but ok.
As it should.
That's precisely my point. Python tells you you probably are doing not
what you think you are doing.. Perl and Java try to do something that
you probably think you are doing (but because there is no real way to
know, they get it differently). The attitude of C++ in this regard.. the
best is to cite from Ed Post's "Real Programmer's Don't Use Pascal".

"No, the Real Programmer wants a "you asked for it, you got it" text
editor-- complicated, cryptic, powerful, unforgiving, dangerous. TECO,
to be precise."

TECO is left behind and, I am afraid, C++ is speeding same direction
(the comparison is apples-to-apples as TECO was a programming language
after all).
Less time than it took to write this!
Good for you. I should have known..

....

-Pavel
 
P

Pavel

James said:
Even without the template. What happens if you started out
using double, then changed to BigDecimal because of later
constraints?
A typedef would be an alternative. But see, Java has BigDecimal and C++
does not. Little wordier, yes. But clear -- and comes with additional
perks: if your app is so picky about arithmetics, you will probably
appreciate an extra add() with the 3rd parameter MathContext that allows
better control of precision etc. Nothing too cool. Just the code that
does exactly what's implied by it. Safe. Readable. Little wordy.
Not to mention that the example is overly simple. Try writing
something like (-b + sqrt( b*b - 4*a*c )) / (2*a) without
operator overloading. (And strange as it may seem, some
programs actually use expressions like this---or more
complicated ones.)
The ability of a user defined type to mimic built in types is
one of C++'s original goals and a very useful attribute.
The address of the string literal "35"+2, which will be '\0'.

You've got considerable C experience as well:).
As it should.

According to the C++ standard. Whether that's a good thing or
not is debatable.

Try the same thing in Java:

class Test
{
public static void main( String[] args )
{
System.out.println( "35" + 2 ) ;
}
} ;

It also compiles and runs. With different, but equally
surprising results:).

Pavel's right about this one: it shouldn't compile in any
language which is statically typechecked. (In more dynamic
languages, of course... ` print "35" + 2 ' prints 37 in AWK.
Which is what I would expect, given the total absence of typing.
Which is fine for small projects---I regularly use AWK for up to
around 500 lines of code---but doesn't scale well.)
Thanks!

-Pavel
 
I

Ian Collins

My point is actually about operator overloading and implicit
conversions.. I would be fine with the pointer arithmetic as long as it
could be unambiguously seen from the code that the pointer arithmetics
takes place here and what particular arithmetics.
Well form a C programmer's perspective, the statement is unambiguous.
If I were to see the same statement in JavaScript or PHP, it would also
be unambiguous. Context is everything in cases like this.
 
I

Ian Collins

A typedef would be an alternative.
How?

But see, Java has BigDecimal and C++ does not.

That's because a programmer can't write BigDecimal with natural
operators in Java, so the language has to provide it. Other languages
have to add extra built in features because they lack the expressiveness
to enable programmer' to roll their own. Look at the hoops C had to go
through to add a complex number type.
Little wordier, yes. But clear -- and comes with additional
perks: if your app is so picky about arithmetics, you will probably
appreciate an extra add() with the 3rd parameter MathContext that allows
better control of precision etc. Nothing too cool. Just the code that
does exactly what's implied by it. Safe. Readable. Little wordy.

I think the above comment form James is very pertinent here.
 
S

Stefan Ram

Ian Collins said:
That's because a programmer can't write BigDecimal with natural
operators in Java, so the language has to provide it.

The language Java does not provide special operators for the
type »java.math.BigDecimal«.

The type »java.math.BigDecimal« is provided by the Java
standard library, not by the language.

A class with the same properties as this standard class can be
declared by any author in a application program or third-party
library. (In Java, »to declare« means something like »to
define« in C++.)

Both the standard class and a third-party class can not
declare special infix operators. Their clients can only use
the method invocation syntax to invoke behavior of objects
representing numbers.
 
J

James Kanze

My point is actually about operator overloading and implicit
conversions..

Well, they certainly affect the Java version:). My point was
just that in the C++ version, you don't even get that far before
the unexpected happens, because of pointer arithmetic. Neither
have "expected" behavior. And I don't really see operator
overloading as a problem here, although I agree with you that
too many implicit conversions is a problem; it's the base of the
problem with Java, for example. (Java got rid of some of C++'s
implicit conversions, which is good; but it added some of its
own, which is bad.)
I would be fine with the pointer arithmetic as long as it
could be unambiguously seen from the code that the pointer
arithmetics takes place here and what particular arithmetics.
My example with Java vs C++ vs Python vs Perl just shows that
the expressiveness is far from universal, it is more
subjective. Some people believe concatenation should be done
with operator + (C++, for strings only, Java), some believe it
should be done with ..
(Perl), some (SQL) prefer || (SQL cleverly offers CONCAT() as an
alternative). C++ seems to be the worst here as + can mean all but
anything, without even user-defined overloads.

That's what I said: pointer arithmetic:). (I don't
particularly like + for concatenation, either. At the very
least, any operator which is overloaded to use + should be
commutative. But + seems to be the de facto standard for
concatenation anyway, from Basic, for example.)
But nobody yet died from typing concatStrings(s1, s2).

Again, it doesn't scale. It doesn't work in more complex
expressions.

The problem with the overloaded operator here isn't, however,
that they've overloaded + for strings. The real problem is that
other types for which the operator is defined also support +.
So you get unexpected results. (It's a small problem, of
course, compared with all of the rest.) Get rid of pointer
arithmetic, and C++ does the right thing. Get rid of the
conversions of numeric types to string in Java, and the Java
version does the right thing.
 
J

James Kanze

Not really, only about 28 years :)

You beat me by two.
But in this case, the string literal decays to a const char*,
so no type checking rules are broken.

None according to the language standard. In this case, I'd
argue that it is the language which is broken; an array is NOT a
pointer, and it shouldn't implicitly convert to one. Of course,
changing this would break C compatibility and so much existing
code we can't even conceive of it, but it is clearly a design
flaw in the original C (probably present because that's the way
it worked in B, where it actually made sense).
As well as every scripting language I know.

Supposing the scripting language supports numeric addition.
(Historically, the Bourne shell didn't, and I've still the habit
of using expr, instead of ((...)).)
Try PHP, I'm in the middle of a several thousand line
PHP/JavaScript application at the moment. The lack of type
checking is both liberating and dangerous.

Exactly. I'm not familiar with PHP or JavaScript, because my
networked machines talk to other machines, not people (through
browsers), but I do do a lot of scripting, in addition to C++.
It's the glue which holds things together.
Thank goodness for unit tests, they take the place of the
compiler!

True, but a unit test failing isn't quite as good as a compiler
error message in such cases.
 
J

James Kanze

The language Java does not provide special operators for the
type »java.math.BigDecimal«.
The type »java.math.BigDecimal« is provided by the Java
standard library, not by the language.

Formally, at least in C++, a class provided by the standard
library is part of the language. But that's really irrelevant
here---the point is that java.math.BigDecimal has more or less
the same semantics as the BigDecimal class I use in C++, but is
a lot harder to use correctly, because of the absense of
operator overloading in Java. (At one point, Gosling had a page
about Java numerics where he proposed a form of operator
overloading, but it's since disappeared.)
 
K

kwikius

Formally, at least in C++, a class provided by the standard
library is part of the language.  But that's really irrelevant
here---the point is that java.math.BigDecimal has more or less
the same semantics as the BigDecimal class I use in C++, but is
a lot harder to use correctly, because of the absense of
operator overloading in Java.  (At one point, Gosling had a page
about Java numerics where he proposed a form of operator
overloading, but it's since disappeared.)

Its a cinch to do in Java

Object_ref operator@(Object_ref, Object_ref)

Voila! youre done. who needs all that C++ complexity !

(Sort of like they did for templates)

:)

regards
Andy Little
 
J

James Kanze

[...]
Does it? Did you solve my puzzle
#include <iostream>
#include <string>
using namespace std;
int main(void) {
string a = "35" + 1;
cout << a << endl;
return 0;
}

What does that have to do with the increment() function? You
seem to be mixing subthreads.
Perl would give one of intuitively expected answers -- see
perl -e 'print "35" + 1'
and Java would give the second one (you can certainly come up
with the code itself).

The "intuitively expected" answer will obviously depend on the
overall philosophy of the language: for untyped languages, such
as Perl, AWK, etc., the intuitively expected response is "36";
for typed languages, such as C++ and Java, the only intuitively
expected response is a compiler error. Which neither Java nor
C++ get right (for different reasons).
Bad enough (Python reports the error in clear language
(TypeError: cannot concatenate 'str' and 'int' objects) -- one
of the reasons it is my favorite from syntactic viewpoint),
but none of these goes as far as C++. Now tell me honestly C++
is most expressive here -- and I only used overloads The
Standard Library offers.

I'm afraid that I don't see any real difference between Java and
C++ here. Not that it's really relevant; neither language is
perfect, and no reasonable person would pretend the contrary.
Both have their flaws. The basic question concerns the
totality, which depends on the application domain, but
doubtlessly favors C++ over Java most of the time.
Of course your "C++ way" goes much further:
To inter-operate between your Percentage class and other
"glorified" numbers (say, to multiply percentage to some
quantity or whatever) you will have to overload helluva lot of
operators and/or allow same amount of conversions.

And? Designing a good interface does require a bit of typing.
And I'm not sure that you'd need that many overloads for
percentage. Not every operation makes sense on a percentage.
No, you are confusing the number of times you would *use* the
non-const reference as a parameter and the number of times I
had to review the code using such references written by
someone (who was not you).

No. You're confusing your personal experience in poorly run
shops (where any language would fail) with absolute truths.
Until there is no such sanction as disbarment in C++ as opposed to
legalese (even though the former might not be much simpler than the
latter), the easiness with which such mines are planted keeps and will
keep a lot of practitioners and managers away of C++. Not that I would
support such kind of regulation..
Then why to look at all? Just assume (as you just did) and put
your signature?

Exactly. Why look further.
And so you would just assume the person who wrote the code you
are reviewing conceived same way as you and write your name on
the dotted line?

I would assume that any code which passed code review was
conform to the conventions in use in the company.
That exactly is my point that you are trying to avoid by all
means. I already agreed with all your points that C++ has a
lot of powerful and "cool" features (you can call them
expressive but I would be more comfortable if you used this
term consistently with some definition preliminary agreed on
between us.

Which is, after all, exactly what software engineering is all
about. If you don't do that, you might as well pack it up and
go home; no language is going to work for you.
No, seriously, let's define "expressivity".

The ability to say exactly what you want, clearly and concisely.
Again, your definition of "advantage" seems to be different
from mine and close to "having more useful features" (please
correct me if I am wrong).

My definition of "advantage" is, in the end, something that
reduces the cost of software development. Expressing exactly
what you want, clearly and concisely, definitely reduces the
cost of software development, and so is an advantage.
Java has less (syntactic) features than C++, no doubts here;
however this is one of its properties that makes it attractive
to project managers (who need to hire people, maintain old
code, all at fixed costs, etc).

There are two things which make Java attractive to project
managers: the first is simply that it is more or less
"in"---it's not a good reason, but it's probably the most wide
spread one. The second is the support structure which is
available for certain types of applications.
BTW It can still express all the same programs except for
system-level ones (the latter is not due to the lack of
features).

Sure. It's Turing complete. You just can't express them as
clearly and concisely.
Certainly not. If I need *pure* value semantics I can simply use
structures.

A structure doesn't necessarily have the semantics you want in
your pure value.
And for "hybrids" (say, structures with integral and
variable-length strings data members) it is always safer and
often more efficient to honestly treat them as "entities" (I
am not sure this is a common term, I would use "objects" but
let it be) which they are -- in any language.

And that's simply wrong. A value is a value, and has entirely
different characteristics than an entity. Look at
java.lang.String, for example, for an example of a well designed
value in Java. (Note that it is final, has no mutable members
and... has overloaded operators.)
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top