468,249 Members | 1,487 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,249 developers. It's quick & easy.

Future of C++

My hunch is my posts to clc++ are disappearing down a hole, so I post here
instead.

Future of C++ thread on clc++

"Abhishek" <no*******************@yahoo.comwrote in message
news:g7**********@aioe.org...
Hi All,
This is a non-technical off topic post, so please excuse me for that.

I wanted to understand from the Gurus of C++ out here about their opinion
on
the future of C++. I have spent eight plus years in the software industry
working in applications programming on C++/ Windows. My current company is
now moving big time towards Java/ J2EE based technologies. Most of the
other
companies which are writing application software are also moving (or have
alreadt moved) to J2EE or to .Net. So is there no future for C++ in
application software? What do the people on this group feel about it?

I understand that Systems side and Embedded are still the areas where C++
is
being used well. But is that all? What do the people who have invested
time
and energy in C++ should do? Learn Java or C# because a significant
majority
of other developers (apparently) could not free the pointers and found
garbage collector to be a great idea.

Thoughts/ Suggestions/ Criticism?

AFAICS C++ is very much about a "craft" approach to software development.
For one It takes a long time to get good at it. Like any craftsman, say a
carpenter it costs. Once upon a time if you wanted a new door, you asked the
carpenter and he made you one to your spec. These days doors are all
standard sizes and you buy them off the shelf at a hardware superstore. A
similar situation applies with C++ and other languages in respect to
libraries. The modern trend is towards abstracting away the hardware. This
results in a loss of performance but much greater productivity, and
critically libraries which become unofficial standards within the language.
The classic example in C++ is GUI. Often newbies ask about the C++ GUI and
they are vaguely pointed off towards various libraries. In modern languages
there are usually one or two "standard" GUI libraries that everyone uses.

Because C++ is so expressive, if you start a new library ( or even
application ) then you are presented with a huge number of decisions. Do I
use templates or RTTI, Do I use Dll or static libs, Do I worry about cross
platform or target one. This all takes a long time and results in
fragmentation. In other less complicated languages, you don't have to worry
about these things. They have been solved or abstracted away. Hence
languages like Java, and Python have huge libraries because presumably they
are easier to write once in practise. The low level problems that confront
you in C and C++ are abstracted away.

That said C++ and C will be around a long time. For windows they will be
around as long as its around I guess, but I don't see there being as much
demand for C++ programmers.

regards
Andy Little

Aug 6 '08 #1
75 2773
kwikius wrote:
My hunch is my posts to clc++ are disappearing down a hole, so I post here
instead.

Future of C++ thread on clc++

"Abhishek" <no*******************@yahoo.comwrote in message
news:g7**********@aioe.org...
>Hi All,
This is a non-technical off topic post, so please excuse me for that.

I wanted to understand from the Gurus of C++ out here about their opinion
on
the future of C++. I have spent eight plus years in the software industry
working in applications programming on C++/ Windows. My current company is
now moving big time towards Java/ J2EE based technologies. Most of the
other
companies which are writing application software are also moving (or have
alreadt moved) to J2EE or to .Net. So is there no future for C++ in
application software? What do the people on this group feel about it?

I understand that Systems side and Embedded are still the areas where C++
is
being used well. But is that all? What do the people who have invested
time
and energy in C++ should do? Learn Java or C# because a significant
majority
of other developers (apparently) could not free the pointers and found
garbage collector to be a great idea.

Thoughts/ Suggestions/ Criticism?


AFAICS C++ is very much about a "craft" approach to software development.
For one It takes a long time to get good at it. Like any craftsman, say a
carpenter it costs. Once upon a time if you wanted a new door, you asked the
carpenter and he made you one to your spec. These days doors are all
standard sizes and you buy them off the shelf at a hardware superstore. A
similar situation applies with C++ and other languages in respect to
libraries. The modern trend is towards abstracting away the hardware. This
results in a loss of performance but much greater productivity, and
critically libraries which become unofficial standards within the language.
The classic example in C++ is GUI. Often newbies ask about the C++ GUI and
they are vaguely pointed off towards various libraries. In modern languages
there are usually one or two "standard" GUI libraries that everyone uses.

Because C++ is so expressive, if you start a new library ( or even
application ) then you are presented with a huge number of decisions. Do I
use templates or RTTI, Do I use Dll or static libs, Do I worry about cross
platform or target one. This all takes a long time and results in
fragmentation. In other less complicated languages, you don't have to worry
about these things. They have been solved or abstracted away. Hence
languages like Java, and Python have huge libraries because presumably they
are easier to write once in practise. The low level problems that confront
you in C and C++ are abstracted away.

That said C++ and C will be around a long time. For windows they will be
around as long as its around I guess, but I don't see there being as much
demand for C++ programmers.

regards
Andy Little
A couple of bare facts/observations with minimal comments:

1. A younger co-worker of mine left for Microsoft last week. What's
interesting, they took him to take part in writing their next generation
Visual Studio or whatever they will call it -- and it is going to be the
first version of it written wholly in C# (instead of C/C++, in which all
recent previous versions have been written). Maybe second next Windows
version will not be in C/C++ either? :-)

2. I received the last issues of last professional C++ magazine I knew
(C/C++ User Journal) more than a year ago (I think). I then checked on
C++ Reports that I used to read much earlier just to learn it had been
dead for quite a while already. Was not very happy about it; this
newsgroup seems to be one of very few C++ dedicated resources.

I would not mind to read a civilized discussion about where C++ is
heading and why -- and I have some ideas of my own about it -- but not
sure if such discussion is an off-topic here or whether there is enough
interest. Also the topic may be quite flame-prone. Any opinions?

-Pavel
Aug 6 '08 #2
On Aug 6, 3:27*am, "kwikius" <a...@servocomm.freeserve.co.ukwrote:
My hunch is my posts to clc++ are disappearing down a hole, so I post here
instead.

Future of C++ thread on clc++

"Abhishek" <nospam_abhishekpan...@yahoo.comwrote in message

news:g7**********@aioe.org...


Hi All,
This is a non-technical off topic post, so please excuse me for that.
I wanted to understand from the Gurus of C++ out here about their opinion
on
the future of C++. I have spent eight plus years in the software industry
working in applications programming on C++/ Windows. My current companyis
now moving big time towards Java/ J2EE based technologies. Most of the
other
companies which are writing application software are also moving (or have
alreadt moved) to J2EE or to .Net. So is there no future for C++ in
application software? What do the people on this group feel about it?
I understand that Systems side and Embedded are still the areas where C++
is
being used well. But is that all? What do the people who have invested
time
and energy in C++ should do? Learn Java or C# because a significant
majority
of other developers (apparently) could not free the pointers and found
garbage collector to be a great idea.
Thoughts/ Suggestions/ Criticism?

AFAICS C++ is very much about a "craft" approach to software development.
For one It takes a long time to get good at it. Like any craftsman, say a
carpenter it costs. Once upon a time if you wanted a new door, you asked the
carpenter and he made you one to your spec. These days doors are all
standard sizes and you buy them off the shelf at a hardware superstore. A
similar situation applies with C++ and other languages in respect to
libraries. The modern trend is towards abstracting away the hardware. This
results in a loss of performance but much greater productivity, and
critically libraries which become unofficial standards within the language.
The classic example in C++ is GUI. Often newbies ask about the C++ GUI and
they are vaguely pointed off towards various libraries. In modern languages
there are usually one or two "standard" GUI libraries that everyone uses.

Because C++ is so expressive, if you start a new library ( or even
application ) then you are presented with a huge number of decisions. Do I
use templates or RTTI, Do I use Dll or static libs, Do I worry about cross
platform or target one. This all takes a long time and results in
fragmentation. In other less complicated languages, you don't have to worry
about these things. They have been solved or abstracted away. Hence
languages like Java, and Python have huge libraries because presumably they
are easier to write once in practise. The low level problems that confront
you in C and C++ are abstracted away.

That said C++ and C will be around a long time. For windows they will be
around as long as its around I guess, but *I don't see there being as much
demand for C++ programmers.

regards
Andy Little- Hide quoted text -

- Show quoted text -
Dear Kwikius/Andy
Hello

I am not going to defend C++ blindly. I try to offer my opinions to
light up some confusions,
Of course may be I am me mistaken.
1. One thing that we should think about is: C++ is a general purpose
programming language not a complete system.
J2EE and Visual Studio .NET are systems. So in C++ "Programming
Language", you can't have ODBC, DAO, GUI components, ...
but using C++ (core language + standard library) and in a complete C++
programming environment,
you can implement libraries for database programming, GUI and so on/
forth. C++ is not/will not a language to bind to
relational database, GUI technology, OS ... It is and will be open and
general-purpose PL.
I think the comparison of C++ PL vs. Java system is somehow unfair.
Of course, my company uses Java rather than C++, because we use a
Trade system that was implemented
using Java technology and my company bought the software. It is not
relevant to C/C++. Programming language selection is not just a
technical issue.
2. As you know, the next revision of C++ is coming soon. It is called C
++0x. It will bring us various features in two area: programming
language
and standard library: in language area we have concepts, initializer
lists, lambda, enum classes, nullptr, programmer-controled GC, ...
and in library area we will see threads, tuples, huge statistics and
math functions, regular expressions, hash_map containers, ...
but again there are no vendor-related components and libraries.
3. Stroustrup say: The only thing that has consistently grown faster
than hardware is human expectations. I think this is absolutely
correct.
Your comment is about efficiency (performance) vs. productivity. In
all software engineering books and university classes,
it is mentioned that with such a drastic changes in hardware speeds
and abilities, the importance of efficiency was decreased.
I think the right sentence is by Kernighan and Plauger in their book:
Elements of Programming Style:
Don't sacrifice readability for small efficiency. Please note to small
adjective. Up until now, there is no feature of C++
which added to language and put unusual overhead on rest of features.
It is very difficult task. Compare the performance of
object-oriented features of C++ vs. Smalltalk. It is applicable for C+
+ vs. Java, C++ vs. Python, C++ vs. Ruby,

4. You used the door and carpenter example. It is about reusability
and as you wrote abstracting away unnecessary details.
C++ tries to do it efficiently: using string rather than char*, vector
rather than arrays, bitset rather than bit manipulations and huge
generic algorithms are some witnesses.
5. IMHO, such expressiveness is not bad thing; indeed it is good and
necessary. C++ continue
To increase in emphasis on statically verifiable type safety. If you
want type safety, you should be expressive. I believe being less
expressive lead us to script programming. As a matter of fact, C++
offer 2-3 ways for a subject to program. It is natural result of
multi-paradigm nature of the PL.

Regards,
Saeed Amrollahi
Aug 6 '08 #3
eb********@gmail.com wrote:
To increase in emphasis on statically verifiable type safety. If you
want type safety, you should be expressive. I believe being less
expressive lead us to script programming.
I don't quite understand that statement. What do you mean? Static typing
and expressiveness in a language are two distinct concepts. C++ is in
some ways more expressive than C but not as expressive as Lisp (which is
a dynamically typed language). What's got one to do with the other?
Aug 6 '08 #4
On Aug 6, 5:09*pm, Matthias Buelow <m...@incubus.dewrote:
ebony.s...@gmail.com wrote:
To increase in emphasis on statically verifiable type safety. If you
want type safety, you should be expressive. I believe being less
expressive lead us to script programming.

I don't quite understand that statement. What do you mean? Static typing
and expressiveness in a language are two distinct concepts. C++ is in
some ways more expressive than C but not as expressive as Lisp (which is
a dynamically typed language). What's got one to do with the other?
Wel heres my take on it.

If you have strong typing you can be more expressive in comfort
because errors in expressions will be caught by the compiler, whereas
dynamic typing postpones errors till runtime and it may take much
testing to try to locate all possible errors.

IOW the dynamic language is "expressive" of many things though some
are potentially incorrect, but the static typed language is
expressive, whilst being (arguably) proved correct prior to
execution.

regards
Andy Little
Aug 6 '08 #5
kwikius wrote:
On Aug 6, 5:09 pm, Matthias Buelow <m...@incubus.dewrote:
>ebony.s...@gmail.com wrote:
>>To increase in emphasis on statically verifiable type safety. If you
want type safety, you should be expressive. I believe being less
expressive lead us to script programming.
I don't quite understand that statement. What do you mean? Static typing
and expressiveness in a language are two distinct concepts. C++ is in
some ways more expressive than C but not as expressive as Lisp (which is
a dynamically typed language). What's got one to do with the other?

Wel heres my take on it.

If you have strong typing you can be more expressive in comfort
because errors in expressions will be caught by the compiler, whereas
dynamic typing postpones errors till runtime and it may take much
testing to try to locate all possible errors.

IOW the dynamic language is "expressive" of many things though some
are potentially incorrect, but the static typed language is
expressive, whilst being (arguably) proved correct prior to
execution.

regards
Andy Little
I am not sure one language is much more expressive than the other --
IMHO it is much more dependent on the style of use than the language
itself. I have seen quite understandable code in different Assemblers
and much more of inscrutable code in all possible languages even
including Python (although it is not too easy to write something
completely misleading in Python -- maybe only on purpose). But the "cost
of complete understanding" of a C++ program was always among the highest
for me -- often, I had to pre-process a source file to understand with
certainty what's coming from where. Consider this fragment:

int i = 0;
f(i);
myprint(i);

If it is written in Java (or C, for that matter), I can tell with some
certainty that myprint() receives 0 as an argument. But to tell
something about it in C++ I have to know whether f() takes a reference
or a value and, to make things even more fun, I never know which of
possible overloaded f's is called, -- not until I pre-process the code
and line up all possible fs. IDE with a browser may help somewhat but as
it jumps to the definition or declaration of f() it dislocates my focus
-- quite an overkill especially if the only purpose of my review is to
track down where that 'i' could get changed.

To review C++ code with a reasonable speed (as compared to Java, C or
even PL/SQL code of the same functional complexity -- even FORTRAN), one
would have to put a lot of trust to the people who wrote it. I
personally got burned too many times and I do not trust anymore so I
have to bite the bullet and jump the sources back and forth like crazy.
Which brings us back to the productivity question.. it should not come
at a surprise that in a project of any considerable size a developer
spends more time reading, researching and understanding the code than
changing it. From this perspective, unexpectedly, C is so much more
productive than C++ (plus, an equivalent C program usually compiles 10
times faster than C++ -- because "smart guys" like inserting templates
and meta-programming wherever they don't need them or at least they will
include a couple of "cool" headers -- so a change/compile/debug
iteration in C is much shorter than in C++).

Not sure how to break this vicious cycle -- it seems the more powerful a
language is the more it gets abused and the more it hurts the
productivity. Java is getting there too, BTW, and C# is almost there
already (see version 3.0 of the language). I, for one, have never been
more productive than when I wrote in FORTRAN 66 in my University -- and
I can still easily read those subroutines after 25 years. I wish I could
say it of my C++ code after 25 years..

-Pavel
Aug 8 '08 #6
Pavel wrote:
<...>
I am not sure one language is much more expressive than the other --
IMHO it is much more dependent on the style of use than the language
itself. I have seen quite understandable code in different Assemblers
and much more of inscrutable code in all possible languages even
including Python (although it is not too easy to write something
completely misleading in Python -- maybe only on purpose). But the "cost
of complete understanding" of a C++ program was always among the highest
for me -- often, I had to pre-process a source file to understand with
certainty what's coming from where. Consider this fragment:

int i = 0;
f(i);
myprint(i);

If it is written in Java (or C, for that matter), I can tell with some
certainty that myprint() receives 0 as an argument. But to tell
something about it in C++ I have to know whether f() takes a reference
or a value and, to make things even more fun, I never know which of
possible overloaded f's is called, -- not until I pre-process the code
and line up all possible fs.
Deducing automatically which function to call based on its arguments is
certainly an important feature in making C++ what I would call
"expressive". Its obviously not available in C. (I cant remember if
there is an overloading scheme available in Java, but even if it is it
would be of limited use because Java is OOP and function overloading is
actually about expressions which are not part of the OOP vocabulary.
Note that Fortress Suns next generation language incorporates
overloading based on various constructs as well as many other familiar
general constructs that have been available in C++ for a long time)

I would prefer if the algorithm regarding which function is actually
called was more rigorously and concisely expressed itself. In general in
C++ you kind of hope that the expected version of a function will be
used, and thats arguably far from ideal (You can't blame C++ for its
complex and loose approach to overloading. C++ is essentially quite a
nice expressive language mixed up with C. The fact that its mixed with C
is AFAIK a major reason for its success, but also the source of many of
its problems (I think this is said somewhere by Bjarne Stroustrup)

In fact I am currently trying to find that simple algorithm regarding
expressions and their relation to types. Its important enough IMHO to be
basis of a whole language. Programming is essentially about writing
expressions. You want conciseness, intuitiveness and clarity with
generality. I am very grateful to C++ for showing me these things and
can now sit back in my armchair and see if and how to improve how C++
goes about it(but in another language, C++ is already seriously
overweight with new stuff) Standing on the giants shoulders and all
that. So can you have expressiveness, but also precision. C++ shows the
problem but not the full solution.

BTW. Note that in the example you gave, because the argument is an int
IOW an inbuilt type there are only a few functions that can be
called(unless you have brought in other namespaces!). If the argument is
a class (a user defined type or UDT) then the list grows large and if
the class involves templates the list grows even larger.

<...>

because "smart guys" like inserting templates
and meta-programming wherever they don't need them or at least they will
include a couple of "cool" headers -- so a change/compile/debug
iteration in C is much shorter than in C++).
Unfortunately I am one of those guys ;-)

http://sourceforge.net/projects/quan

I wouldnt be without quan. It heavily used everyday in my work (though I
dont maintain publicaly any more) and currently C++ is the only language
it can be written practically in.

Not sure how to break this vicious cycle -- it seems the more powerful a
language is the more it gets abused and the more it hurts the
productivity. Java is getting there too, BTW, and C# is almost there
already (see version 3.0 of the language). I, for one, have never been
more productive than when I wrote in FORTRAN 66 in my University -- and
I can still easily read those subroutines after 25 years. I wish I could
say it of my C++ code after 25 years..
Its an interesting problem. All succesful languages grow more complex. I
guess there is a solution, which is the one taken by Haskell... "Avoid
success at all costs". Its an enigmatic motto, but after many years I
finally understand it. I think its the best motto... if you want to stay
expressive ;-)

regards
Andy Little
Aug 8 '08 #7
Pavel wrote:
kwikius wrote:
>On Aug 6, 5:09 pm, Matthias Buelow <m...@incubus.dewrote:
>>ebony.s...@gmail.com wrote:
To increase in emphasis on statically verifiable type safety. If
you want type safety, you should be expressive. I believe being
less expressive lead us to script programming.
I don't quite understand that statement. What do you mean? Static
typing and expressiveness in a language are two distinct
concepts. C++ is in some ways more expressive than C but not as
expressive as Lisp (which is a dynamically typed language).
What's got one to do with the other?

Wel heres my take on it.

If you have strong typing you can be more expressive in comfort
because errors in expressions will be caught by the compiler,
whereas dynamic typing postpones errors till runtime and it may
take much testing to try to locate all possible errors.

IOW the dynamic language is "expressive" of many things though some
are potentially incorrect, but the static typed language is
expressive, whilst being (arguably) proved correct prior to
execution.

regards
Andy Little

I am not sure one language is much more expressive than the other --
IMHO it is much more dependent on the style of use than the language
itself. I have seen quite understandable code in different
Assemblers and much more of inscrutable code in all possible
languages even including Python (although it is not too easy to
write something completely misleading in Python -- maybe only on
purpose). But the "cost of complete understanding" of a C++ program
was always among the highest for me -- often, I had to pre-process
a source file to understand with certainty what's coming from
where. Consider this fragment:
int i = 0;
f(i);
myprint(i);

If it is written in Java (or C, for that matter), I can tell with
some certainty that myprint() receives 0 as an argument. But to tell
something about it in C++ I have to know whether f() takes a
reference or a value
Using a better name than f() would help a lot!

Hardly a language problem.
>
To review C++ code with a reasonable speed (as compared to Java, C
or even PL/SQL code of the same functional complexity -- even
FORTRAN), one would have to put a lot of trust to the people who
wrote it. I personally got burned too many times and I do not trust
anymore so I have to bite the bullet and jump the sources back and
forth like crazy. Which brings us back to the productivity
question.. it should not come at a surprise that in a project of
any considerable size a developer spends more time reading,
researching and understanding the code than changing it. From this
perspective, unexpectedly, C is so much more productive than C++
(plus, an equivalent C program usually compiles 10 times faster
than C++ -- because "smart guys" like inserting templates and
meta-programming wherever they don't need them or at least they
will include a couple of "cool" headers -- so a
change/compile/debug iteration in C is much shorter than in C++).
As usual, "You can write bad programs in any language".

Here is an example of what you can do in C
(http://www.ioccc.org/2004/hoyle.c), hardly 10 times easier to read
than anything else.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define _ ;double
#define void x,x
#define case(break,default) break[O]:default[O]:
#define switch(bool) ;for(;x<bool;
#define do(if,else) inIine(else)>int##if?
#define true (--void++)
#define false (++void--)

char*O=" <60>!?\\\n"_ doubIe[010]_ int0,int1 _ Iong=0 _ inIine(int
eIse){int
O1O=!O _ l=!O;for(;O1O<010;++O1O)l+=(O1O[doubIe]*pow(eIse,O1O));return
l;}int
main(int booI,char*eIse[]){int
I=1,x=-*O;if(eIse){for(;I<010+1;I++)I[doubIe-1]
=booI>I?atof(I[eIse]):!O
switch(*O)x++)abs(inIine(x))>Iong&&(Iong=abs(inIin e(x
)));int1=Iong;main(-*O>>1,0);}else{if(booI<*O>>1){int0=int1;int1=int0-2*Iong/0
[O]switch(5[O]))putchar(x-*O?(int0>=inIine(x)&&do(1,x)do(0,true)do(0,false)
case(2,1)do(1,true)do(0,false)6[O]case(-3,6)do(0,false)6[O]-3[O]:do(1,false)
case(5,4)x?booI?0:6[O]:7[O])+*O:8[O]),x++;main(++booI,0);}}}

Bo Persson
Aug 8 '08 #8
On Aug 8, 10:32 am, kwikius <a...@servocomm.freeserve.co.ukwrote:
Pavel wrote:
<...>
int i = 0;
f(i);
myprint(i);
If it is written in Java (or C, for that matter), I can tell
with some certainty that myprint() receives 0 as an
argument. But to tell something about it in C++ I have to
know whether f() takes a reference or a value and, to make
things even more fun, I never know which of possible
overloaded f's is called, -- not until I pre-process the
code and line up all possible fs.
That's not preprocessing. Preprocessing is something else
entirely (which C++ inherits from C). And preprocessing is a
problem: if myprint (or f, for that matter) is a macro, who
knows what the above means.

One of the evolutions of C++ with respect to C is to reduce the
need for macros---good C++ makes very, very limited use of
macros. So you should have less problems with the above in C++
than in C.
Deducing automatically which function to call based on its
arguments is certainly an important feature in making C++ what
I would call "expressive".
Like everything which increases expressivity, it can be abused.
I'm tempted to say that if myprint is overloaded, and it matters
which instance of myprint is called, overloading has been
abused.

Of course, Pavel is right about one thing: the last line in the
above could be the declaration of a variable (which would be a
duplicate declaration, but if i were in some different scope, it
would be a legal declaration). IMHO, this goes beyond
"expressivity", and is frankly a defect. But it's one we
inherited from C, and the same ambiguity exists in C. (All
that's needed, in both cases, is that myprint is defined by a
typedef somewhere. And that's one ambiguity that isn't present
in Java.)
Its obviously not available in C.
(I cant remember if there is an overloading scheme available
in Java, but even if it is it would be of limited use because
Java is OOP and function overloading is actually about
expressions which are not part of the OOP vocabulary.
Never the less, Java's overloading is almost identical to that
of C++. If it's less of an issue, it's only because Java
doesn't support as many implicit conversions (another thing C++
has mainly because of C compatibility).
Note that Fortress Suns next generation language incorporates
overloading based on various constructs as well as many other
familiar general constructs that have been available in C++
for a long time)
I would prefer if the algorithm regarding which function is
actually called was more rigorously and concisely expressed
itself. In general in C++ you kind of hope that the expected
version of a function will be used, and thats arguably far
from ideal (You can't blame C++ for its complex and loose
approach to overloading. C++ is essentially quite a nice
expressive language mixed up with C. The fact that its mixed
with C is AFAIK a major reason for its success, but also the
source of many of its problems (I think this is said somewhere
by Bjarne Stroustrup)
I don't know if Stroustrup said it, but it's certainly true.
The biggest single problem in C++ is the declaration syntax,
which is inherited from C. To many implicit conversions
(especially lossy conversions) would be another inherited
problem. (And it's too many implicit conversions which makes
overload resolution so complicated.)
BTW. Note that in the example you gave, because the argument
is an int IOW an inbuilt type there are only a few functions
that can be called (unless you have brought in other
namespaces!).
Or you have classes which have non-explicit constructors which
take a single integral type.
If the argument is a class (a user defined type or UDT) then
the list grows large and if the class involves templates the
list grows even larger.
<...>
because "smart guys" like inserting templates
and meta-programming wherever they don't need them or at
least they will include a couple of "cool" headers -- so a
change/compile/debug iteration in C is much shorter than in
C++).
On the other hand, because of C++'s better type checking and
encapsulation, you normally need a lot less change/compile/debug
cycles than you would with C. Globally, development times in a
well run project are significantly less in C++ than in C (or in
Java, for that matter).
Not sure how to break this vicious cycle -- it seems the
more powerful a language is the more it gets abused and the
more it hurts the productivity.
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.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 8 '08 #9
On Aug 8, 10:46 am, "Bo Persson" <b...@gmb.dkwrote:
Pavel wrote:
I am not sure one language is much more expressive than the other --
IMHO it is much more dependent on the style of use than the language
itself. I have seen quite understandable code in different
Assemblers and much more of inscrutable code in all possible
languages even including Python (although it is not too easy to
write something completely misleading in Python -- maybe only on
purpose). But the "cost of complete understanding" of a C++ program
was always among the highest for me -- often, I had to pre-process
a source file to understand with certainty what's coming from
where. Consider this fragment:
int i = 0;
f(i);
myprint(i);
If it is written in Java (or C, for that matter), I can tell with
some certainty that myprint() receives 0 as an argument. But to tell
something about it in C++ I have to know whether f() takes a
reference or a value
Using a better name than f() would help a lot!
Hardly a language problem.
Yes and no. It's only a fragment; let's expand it some:

int i = 0 ;

void
myFunction()
{
f( i ) ;
myprint( i ) ;
}

Now throw in a "typedef double myprint;" before the first line.
Rather changes things, don't you think?

No matter how you consider it, the declaration syntax of C is a
mistake. A mistake which C++ inherits. It's the price we pay
for C compatibility.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 8 '08 #10
James Kanze wrote:
On Aug 8, 10:32 am, kwikius <a...@servocomm.freeserve.co.ukwrote:
>Pavel wrote:
<...>
>>int i = 0;
f(i);
myprint(i);
If it is written in Java (or C, for that matter), I can tell
with some certainty that myprint() receives 0 as an
argument. But to tell something about it in C++ I have to
know whether f() takes a reference or a value and, to make
things even more fun, I never know which of possible
overloaded f's is called, -- not until I pre-process the
code and line up all possible fs.

That's not preprocessing. Preprocessing is something else
entirely (which C++ inherits from C). And preprocessing is a
problem: if myprint (or f, for that matter) is a macro, who
knows what the above means.
I am afraid I was not clear enough. No macros was assumed to be involved
in the above (see "*some* certainty" cited above). The actual point is
that in C++ you cannot say whether

void f(int i);
or
void f(int &i);

is called, without looking elsewhere and getting distracted by that (on
some platforms, the fastest way for me to say is to vi the output of the
preprocessor -- that's from where the reference to the p).

"Expressive" to me means something close to the opposite to having to go
to the reference (header file, browser window etc) to understand what
the "expressive expression" really does. You will probably agree that
the syntactic meaning of something as simple as " int i = 0; f(i);" is
supposed to become obvious without much effort -- if it is not, getting
to a comfortable level of understanding of a syntactic meaning of a
little bit less trivial piece of code is supposed to take infinite
amount of time by definition -- isn't it?
...
Of course, Pavel is right about one thing: the last line in the
above could be the declaration of a variable (which would be a
duplicate declaration, but if i were in some different scope, it
would be a legal declaration). IMHO, this goes beyond
"expressivity", and is frankly a defect. But it's one we
inherited from C, and the same ambiguity exists in C. (All
that's needed, in both cases, is that myprint is defined by a
typedef somewhere. And that's one ambiguity that isn't present
in Java.)
No I just meant that reference/value ambiguity, all other would be
explicit abuses and this one is a matter of course. Now everyone is
saying "use C++ references instead of C pointers wherever a pointer
cannot be NULL" but, mind you, in C you would have "f(&i);" vs "f(i);"
-- no ambiguous reading possible.
I don't know if Stroustrup said it, but it's certainly true.
The biggest single problem in C++ is the declaration syntax,
which is inherited from C. To many implicit conversions
(especially lossy conversions) would be another inherited
problem. (And it's too many implicit conversions which makes
overload resolution so complicated.)
Again, I should not have probably mentioned the overloading above as the
point was about the by-value vs by-reference call; but it does add
insult to injury by stealing more of my time in the situations like
above (something "expressiveness" is not supposed to do, IMHO).
>>and meta-programming wherever they don't need them or at
least they will include a couple of "cool" headers -- so a
change/compile/debug iteration in C is much shorter than in
C++).

On the other hand, because of C++'s better type checking and
encapsulation, you normally need a lot less change/compile/debug
cycles than you would with C. Globally, development times in a
well run project are significantly less in C++ than in C (or in
Java, for that matter).
Apparently your mileage differs from mine. Java became quite agile
(somewhere after 2000-2001 when major bugs were eliminated from
implementations) but in my experience C++ projects blew by far more
deadlines than FORTRAN, Assembler, C or Java (after the latter matured
with the adoption of 1.3.1 and 1.4) -- and some of the firms I worked
for were really well-run hardware/software shops. Of course I mean the
deadlines for commercial products, not some semi-working prototypes. To
summarize my experience: while you are writing in C++ everything is so
much faster and more expressive than in another language; as soon as the
tables are switched and you are on the reading side, the situation
changes drastically.

Also, you are completely out of control: be you even the best C++
programmer in the world but given some hundreds KLOC of C++ written by a
"C++ scholar" or, worse, a by bunch of those guys, each with his/her
"principles", you face a nice choice between never giving you manager
"the date" and guaranteed blowing it up. Remember, you are never
expected to re-write a significant part of the existing code, but only
to "quickly fix few little issues we have" and "add a couple of new
features the business wants delivered yesterday". Under these
circumstances, I prefer inheriting even FORTRAN code to inheriting C++
(with the additional bonus of receiving some extra time for changing
FORTRAN code to something more modern :-) ). I guess, to be honest with
others, I have to leave to them the legacy I would be willing to inherit
myself, no matter how cool it feels to write "expressively".

...
>>Not sure how to break this vicious cycle -- it seems the
more powerful a language is the more it gets abused and the
more it hurts the productivity.

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 :-).

-Pavel
Aug 9 '08 #11
Bo Persson wrote:
Pavel wrote:
>kwikius wrote:
>>On Aug 6, 5:09 pm, Matthias Buelow <m...@incubus.dewrote:
ebony.s...@gmail.com wrote:
To increase in emphasis on statically verifiable type safety. If
you want type safety, you should be expressive. I believe being
less expressive lead us to script programming.
I don't quite understand that statement. What do you mean? Static
typing and expressiveness in a language are two distinct
concepts. C++ is in some ways more expressive than C but not as
expressive as Lisp (which is a dynamically typed language).
What's got one to do with the other?
Wel heres my take on it.

If you have strong typing you can be more expressive in comfort
because errors in expressions will be caught by the compiler,
whereas dynamic typing postpones errors till runtime and it may
take much testing to try to locate all possible errors.

IOW the dynamic language is "expressive" of many things though some
are potentially incorrect, but the static typed language is
expressive, whilst being (arguably) proved correct prior to
execution.

regards
Andy Little
I am not sure one language is much more expressive than the other --
IMHO it is much more dependent on the style of use than the language
itself. I have seen quite understandable code in different
Assemblers and much more of inscrutable code in all possible
languages even including Python (although it is not too easy to
write something completely misleading in Python -- maybe only on
purpose). But the "cost of complete understanding" of a C++ program
was always among the highest for me -- often, I had to pre-process
a source file to understand with certainty what's coming from
where. Consider this fragment:
int i = 0;
f(i);
myprint(i);

If it is written in Java (or C, for that matter), I can tell with
some certainty that myprint() receives 0 as an argument. But to tell
something about it in C++ I have to know whether f() takes a
reference or a value

Using a better name than f() would help a lot!
You are trying to avoid the point really hard -- I am clapping my hands!

Imagine you changed f() to doSomething() where Something really speaks
for itself. In C, you can just leave it at that, in C++ you have to say:

doSomethingAndNeverChangeTheArgument(i) or
doSomethingAndMaybeChangeTheArgument(i) to give the reader the same
level of understanding of just *syntactic meaning* of the code they
would otherwise have in C from simply doSomething(i). Note that the
issue has nothing to do with the topic of how well "Something"
represents the *business purpose* of the function, which IMHO is what it
should represent -- that's why I used f() in my example at the first
place, namely to avoid distracting my the reader's attention from the
*syntactic meaning* of which "the most expressive language" gives the
reader the vaguest idea in this example.

Please let me know if you have further questions about my example.
>
Hardly a language problem.
What is it then?
>To review C++ code with a reasonable speed (as compared to Java, C
or even PL/SQL code of the same functional complexity -- even
FORTRAN), one would have to put a lot of trust to the people who
wrote it. I personally got burned too many times and I do not trust
anymore so I have to bite the bullet and jump the sources back and
forth like crazy. Which brings us back to the productivity
question.. it should not come at a surprise that in a project of
any considerable size a developer spends more time reading,
researching and understanding the code than changing it. From this
perspective, unexpectedly, C is so much more productive than C++
(plus, an equivalent C program usually compiles 10 times faster
than C++ -- because "smart guys" like inserting templates and
meta-programming wherever they don't need them or at least they
will include a couple of "cool" headers -- so a
change/compile/debug iteration in C is much shorter than in C++).

As usual, "You can write bad programs in any language".
....
No arguing here. I am not talking about writing programs by the way, I
am talking about the competition between the languages in wasting my
time when I am given a program I have to read and understand to some
comfortable level. From my 25-year experience C++ and Perl share 1st and
2nd place with bash and Korn-shell closely following.

I am not saying there is no good C++ programmers (and, by now, you
should have an idea what I mean by "good" -- it includes "not extra
expressive") -- but my mileage says there are more Python, C and Java
good programmers than C++. The language must have to do something with
this pure observation, don't you think so? Or would you argue my 25
years in the industry are statistically insignificant?

-Pavel
Aug 9 '08 #12
Stefan Ram wrote:
Pavel <dot_com_yahoo@paultolk_reverse.yourselfwrites:
>In C, you can just leave it at that

It could still be implemented as a macro in C (as some
standard functions are, while still being spelled in lower
case letters). Such a macro could possibly modify the argument
object's value.

Also, »never change the argument« often is implied by the
name already.
....
Thank you, but we are not talking about you or me -- we *never* write
code like this, do we? Essentially, you and me say same thing: you say
"you have to imply by the name", and I even give 2 good examples of such
names -- or were those examples bad?

We are talking about *some* honest and naive programmer who wrote it and
moved on and you and me are now bound to read his or her writing. My
point is exactly that, in C, he or she would not have to "imply by the
name" whereas in C++ -- yes, he or she had better do so. I guess this is
because C++ it is the most "expressive language", and I guess this is
the main feature of an expressive language -- to make a programmer to
write more words or else his or her reader is screwed -- as opposed to
the less expressive languages, that do not require such extra words. I
guess, wordiness is the new synonym for both expressiveness and
conciseness (just for the record -- the conciseness of C++ was referred
to by Andy before in this thread, so I am not trying to change a subject
here).

-Pavel
Aug 9 '08 #13
Alf P. Steinbach wrote:
* Pavel:
>>
Imagine you changed f() to doSomething() where Something really speaks
for itself. In C, you can just leave it at that, in C++ you have to say:

doSomethingAndNeverChangeTheArgument(i) or
doSomethingAndMaybeChangeTheArgument(i) to give the reader the same
level of understanding of just *syntactic meaning* of the code they
would otherwise have in C from simply doSomething(i). Note that the
issue has nothing to do with the topic of how well "Something"
represents the *business purpose* of the function, which IMHO is what
it should represent -- that's why I used f() in my example at the
first place, namely to avoid distracting my the reader's attention
from the *syntactic meaning* of which "the most expressive language"
gives the reader the vaguest idea in this example.

Please note that the above difference between C and C++, favoring C,
holds only for primitive types.

When you're passing an array, or when you're passing a structure in the
most common way in C (namely as a pointer), then in C89 you can't see
from the call site what the called function does, whether it modifies or
not.

However, in C++ you can easily see that at the call site: if the
argument is const, it will not be modified unless the function is a very
bad 'un.

Summing up, you're drawing an invalid and very misleading generalization
based on very incomplete knowledge of or familiarity with the languages
you compare.

It is very common though, one of those irrational memes just floating
around and picked up uncritically by scores of novices.
Alf,

As before, for some reason you try to get personal immediately. Try one
more time -- and I will tell you what I think of the critical thinking
skills of those who have read only one book, learned only one language
etc (of course, my flame will be as well based as your ridiculing my
experience and proficiency level in C++). For now, I will try to stick
to the subject.

Yes, my 25 years of programming experience (of them 19 in C++) may be
not too much, but I respected everybody else's experience -- I am just
saying that my mileage is this: understanding C++ code wasted most of my
time because I could never assume I understood from where the other guy
was coming. I tried assuming that and got burned -- I don't assume
anymore. I recognize that the others' mileage could differ and certainly
do not try to deny their experience.

You appear ready to dismiss an example which I have seen so many times
in the code used in production that I have gotten sick from it. To me
this dismissal comes from either denial (maybe you dismiss any example
that contradicts your theory as marginal or by denigrating other's
experience of by any other means it takes) or feeling entitled for
disrespecting the others for no obvious reason -- you pick the one.

I have never argued one could not write poorly supportable code in other
language than C++. I just said that by far most of such code I have
personally seen was written in C++ and suggested that others share their
experience and ideas of why they observed what they observed. I gave one
example -- the simplest one I could come up with, but certainly not the
only one I could give of when C++ code, even supposedly following "best
C++ practices (using references rather than pointers)" is more difficult
to understand than C or Java code. What's important is that this example
comes from repeatable real practice, not from my "intrinsic feeling of
what's right" or "how it should be" or "how it could be". I did not even
say I knew how this code should have been written -- this does not mean
I do not have an opinion on that but I am trying to refrain from
expressing opinions in favor of data analysis and I remind you that the
goal of this analysis is to come with a good guess what the future of
C++ is and why people think so.

If you have anything to say you are welcome to throw your *observations*
and please try to avoid generalizations and immediate conclusions (even
if they are your convictions). I will not denigrate your experience if
it contradicts mine -- at least you can be sure of that. Please notice I
have not thrown a single "generalization" into the discussion -- I have
always quoted the word "expressive" to emphasize it was not me who
brought it in. Therefore, I suggest you to recall you "misleading
generalization" language until it has a relevant target.

-Pavel
Aug 9 '08 #14
Pavel wrote:
Bo Persson wrote:
>Pavel wrote:
Consider this fragment:
>>int i = 0;
f(i);
myprint(i);

If it is written in Java (or C, for that matter), I can tell with
some certainty that myprint() receives 0 as an argument. But to
tell something about it in C++ I have to know whether f() takes a
reference or a value

Using a better name than f() would help a lot!
You are trying to avoid the point really hard -- I am clapping my
hands!
No, I am not. You say that from

f(i);

you cannot understand what f does, but from

f(&i);

it is suddenly obvuious. How?

My claim is that readable code looks like

sort(i);
increment(i);

which will obviosuly change the value of i, whether it is &i or just
plain i.

total_amount += i;

probably would not.

Bo Persson
Aug 9 '08 #15
Bo Persson wrote:
Pavel wrote:
>Bo Persson wrote:
>>Pavel wrote:
Consider this fragment:
>>>int i = 0;
f(i);
myprint(i);

If it is written in Java (or C, for that matter), I can tell with
some certainty that myprint() receives 0 as an argument. But to
tell something about it in C++ I have to know whether f() takes a
reference or a value
Using a better name than f() would help a lot!
You are trying to avoid the point really hard -- I am clapping my
hands!

No, I am not. You say that from

f(i);

you cannot understand what f does, but from
I don't know where you read this. I did not make any references to "what
f does" and it would be out of context. I said (and you cited it 10
lines above, but I guess I have to repeat it):

"If it is written in Java (or C, for that matter), I can tell with
some certainty that myprint() receives 0 as an argument. But to
tell something about it in C++ I have to know whether f() takes a
reference or a value".

The business purpose of f (sort, increment or whatever) is absolutely
irrelevant to the clarity of the *syntactic meaning* of the code.
Sometimes the well-chosen name may help one to make a better guess of
the syntactic meaning but this fact does not tell anything about the
qualities of the programming language as a communication tool: I could
select a self-describing name even in Assembler. Ok, in FORTRAN 66 I
would have to limit myself by 6 characters -- I will give you that, but
this does not apply to either C or Java. Namely because all other
languages allow the user to select good names, they are equivalent in
this regard, so I am factoring this out and use non-telling name 'f' to
attract attention to the fact that, with same name, Java gives a better
idea of how i is changing than C++.

Also, you have to really understand the purpose of code review. It is
not to evaluate how well the API is -- for that, you can review header
files in C/C++ or Javadoc in Java. It is only partially to evaluate the
compliance of the code to the coding standards -- because 70% of such
evaluation can be automated and another 20% (like the quality of in-line
documentation) will be clear from same header files and javadoc.

Most of the time when someone reviews the code, the purpose is to spot
most dangerous bugs that all unit/integration/system tests may have
missed because the whole data universe of most of real-world programs
cannot be, for practical purposes, completely covered by tests. If this
is the purpose of the code review (or if it is to find some bug that
already demonstrated itself), the meaning of any apparently telling name
must be a suspect. Namely, the code reviewer should get an unassuming
attitude and say, "ok, this function name is `doSomething()' but I
cannot take it for granted; let me see whether it really does *that*
something or it does something completely or subtly different even
though its original author meant it to do *that* something *and nothing
but that something*".
>
f(&i);

it is suddenly obvuious. How?

My claim is that readable code looks like

sort(i);
increment(i);

which will obviosuly change the value of i, whether it is &i or just
plain i.

total_amount += i;

probably would not.
Probably.. I wrote already how often I have been burned by such
assumptions. To know for sure, I have to see the prototype, and, if it
does take a reference, review the body... Not in C or Java.

Besides, even functions with telling names can (and often do) return
value in different ways. I will take your example:

compare:

int increment(int i) { return i + 1; } // #1

and

int increment(int &i) { return ++i; } // #2

I know, I know.. but people (not you and me of course :-)) write things
like #2, sometimes for reason (of course on the hindsight and out of
context we are ready to blame them, but think of the standard C function
-- "time_t time(time_t *);" -- because it takes an old bad pointer,
nobody has any problem with it).

And obviously, with the possibility of the above 2 definitions, the
simple code

int i;
int j = increment(i);

poses very different different complexity to the reviewer of the C or
Java code, from one side, and C++, from another.
-Pavel
Aug 10 '08 #16
On Aug 10, 10:17 pm, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:

[...]
Besides, even functions with telling names can (and often do)
return value in different ways. I will take your example:
compare:
int increment(int i) { return i + 1; } // #1
and
int increment(int &i) { return ++i; } // #2
Increment is a verb. Thus, the first function is very purely
named, since it doesn't increment anything.

But all this is accademic, because we don't define such silly
functions. Real functions do something significant, and have
names which tell us what. (In practice, it's very, very rare
for a function to take a non-const reference to begin with. If
a function is going to modify something, it is a member of that
something.)
I know, I know.. but people (not you and me of course :-)) write things
like #2, sometimes for reason (of course on the hindsight and out of
context we are ready to blame them, but think of the standard C function
-- "time_t time(time_t *);" -- because it takes an old bad pointer,
nobody has any problem with it).
Historically, I think it was "void time( time_t* )". Because (I
think; I'm not really sure about this) the earliest versions of
C didn't support returning a long. When the return value was
added, they couldn't remove the argument without breaking code.
And obviously, with the possibility of the above 2
definitions, the simple code
int i;
int j = increment(i);
poses very different different complexity to the reviewer of
the C or Java code, from one side, and C++, from another.
I think you've chosen a poor example. Suppose you are dealing
with a user defined type. In Java, you can only pass a
reference to it, and there are no references to const. All you
have to go on is the name of the function. In C++, you can
implement value semantics, if that is appropriate to the type
in question, and the function can take the argument by value.
Or you can use a const reference. At the language level, you
can express in more detail what the function really does.

In practice, of course, it's not that important, since in Java,
too, the name of the function (and the semantics of the type
you are passing) make it clear whether the object will be
modified or not.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 11 '08 #17
James Kanze wrote:
On Aug 10, 10:17 pm, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:

[...]
>Besides, even functions with telling names can (and often do)
return value in different ways. I will take your example:
>compare:
>int increment(int i) { return i + 1; } // #1
>and
>int increment(int &i) { return ++i; } // #2

Increment is a verb. Thus, the first function is very purely
named, since it doesn't increment anything.
purely?

--
Ian Collins.
Aug 11 '08 #18
On Aug 11, 9:40 am, Ian Collins <ian-n...@hotmail.comwrote:
James Kanze wrote:
On Aug 10, 10:17 pm, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:
[...]
Besides, even functions with telling names can (and often do)
return value in different ways. I will take your example:
compare:
int increment(int i) { return i + 1; } // #1
and
int increment(int &i) { return ++i; } // #2
Increment is a verb. Thus, the first function is very purely
named, since it doesn't increment anything.
purely?
? What was I thinking of? (Clearly, maybe?)

Anyway, it's a bad example, because unlike most functionalities
you're likely to need, C, C++ and Java have a standard name for
this already: ++. If you don't name this function ++, it's
really obfuscation.

Of course, if the type is BigDecimal, rather than int, you're
going to have a difficult time naming it ++ in Java:-).

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 11 '08 #19
On Aug 11, 11:16 am, "Alf P. Steinbach" <al...@start.nowrote:
* James Kanze:
> [...]
Besides, even functions with telling names can (and often
do) return value in different ways. I will take your
example:
>>compare:
>>int increment(int i) { return i + 1; } // #1
>>and
>>int increment(int &i) { return ++i; } // #2
>Increment is a verb. Thus, the first function is very purely
named, since it doesn't increment anything.
purely?
? What was I thinking of? (Clearly, maybe?)
"poorly", <url:http://www.thefreedictionary.com/poorly>.
As I recall, in Pascal those Peano arithmetic functions were
called Succ and Pred.
I probably meant "clearly", but "poorly" is better. In C++,
it's name is ++.
If recursion was more used in C and C++ we'd presumably have
standard operators for them ("+ 1" works nicely for numeric
types, but not for e.g. enums).
What does that have to do with recursion? If enum's were
enumeration types, the language could doubtlessly define ++ and
-- for them, as well. They aren't, so it can't.
I haven't checked C++0x draft, but perhaps, if it isn't there already,
namespace std
{
template< typename T >
T succ( T x ) { ++x; return x; }
template< typename T >
T pred( T x ) { --x; return x; }
}
wouldn't be so bad an idea (for clarity I didn't sketch in use
of e.g. traits type to use for choice between implementations,
e.g. for an immutable arithmetic type T one would instead have
"return x + 1;" and "return x - 1;").
Sometimes when using iterators this functionality is needed.
They'd be useful for enum types as well, with the restriction
that they're really only meaningful for enum types without
explicit initializers for the enum values. Of course, for that,
you'd need a traits which caused the functions to add the
necessary casts, and which automatically chose the correct
underlying type.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 11 '08 #20
James Kanze <ja*********@gmail.comwrites:
They'd be useful for enum types as well, with the restriction
that they're really only meaningful for enum types without
explicit initializers for the enum values.
Why the restriction? On contrary, explicit enum initializers is only
an irrelevant low level mapping.

namespace Magic { enum Magic { normal = 1, more = 42, full = 13 }; }

Magic::Magic m=Magic::normal;
m++;
assert(m==Magic::more);
assert(m==/*low level value you don't really want to watch*/42);
m++;
assert(m==Magic::full);
assert(m==/* close your eyes till the eoln*/13);
--
__Pascal Bourguignon__
Aug 11 '08 #21
Alf P. Steinbach wrote:
>
I haven't checked C++0x draft, but perhaps, if it isn't there
already,
namespace std
{
template< typename T >
T succ( T x ) { ++x; return x; }

template< typename T >
T pred( T x ) { --x; return x; }
}

wouldn't be so bad an idea (for clarity I didn't sketch in use of
e.g. traits type to use for choice between implementations, e.g.
for an immutable arithmetic type T one would instead have "return x
+ 1;" and "return x - 1;").
They are there, called 'next' and 'prev', but intended for iterators
only.
Sometimes when using iterators this functionality is needed.
See! :-)
Bo Persson
Aug 11 '08 #22
James Kanze wrote:
On Aug 10, 10:17 pm, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:

[...]
>Besides, even functions with telling names can (and often do)
return value in different ways. I will take your example:
>compare:
>int increment(int i) { return i + 1; } // #1
>and
>int increment(int &i) { return ++i; } // #2

Increment is a verb. Thus, the first function is very purely
named, since it doesn't increment anything.

But all this is accademic, because we don't define such silly
functions. Real functions do something significant, and have
names which tell us what. (In practice, it's very, very rare
for a function to take a non-const reference to begin with. If
a function is going to modify something, it is a member of that
something.)
>I know, I know.. but people (not you and me of course :-)) write things
like #2, sometimes for reason (of course on the hindsight and out of
context we are ready to blame them, but think of the standard C function
-- "time_t time(time_t *);" -- because it takes an old bad pointer,
nobody has any problem with it).

Historically, I think it was "void time( time_t* )". Because (I
think; I'm not really sure about this) the earliest versions of
C didn't support returning a long. When the return value was
added, they couldn't remove the argument without breaking code.
Well, my point is that it is easy to understand whether this function
can change its argument just looking at the place in code where the
time_t variable is defined and time() is called (that is, locally).

That the issue has history only tells me that the language is viable
(good): even after redesign, under additional requirement to provide
compatibility, the syntactic meaning of the client code is still more
clear than if it were C++ function and the prototype used the reference
(of course, you can write in C++ like in C, but I mean "C++-ish" C++).
>
>And obviously, with the possibility of the above 2
definitions, the simple code
>int i;
int j = increment(i);
>poses very different different complexity to the reviewer of
the C or Java code, from one side, and C++, from another.

I think you've chosen a poor example. Suppose you are dealing
with a user defined type. In Java, you can only pass a
reference to it, and there are no references to const. All you
have to go on is the name of the function. In C++, you can
implement value semantics, if that is appropriate to the type
in question, and the function can take the argument by value.
Exactly. I think we are talking of the same things but our assessments
of them are directly opposite. Here is how I read what you wrote:

In C++, you can define a function in more ways (which have different
meanings, and these different meanings can be desirable in different
situations -- I agree with you) BUT the client code can look same for
more of these different meanings (which to me is equivalent to poor
readability, VERY poor).

Yes, to change the value of the argument in Java, you would have to
write something like (not necessarily this, but to localize, this seems
to be about the shortest way):

int i = 0;
int[] iHolder = new int[] { i };
int j = f(iHolder);
i = iHolder[0]; // line #4

Yes, it may look ugly (and, barring some optimizations about which I am
not 100% sure they are actually performed, be less efficient) --
however, syntactically, nobody would have any doubts that i may not be 0
after line #4, and that for this f() changing its argument is business
at normal, whether or not its name gives a good idea of its business
purpose.
Or you can use a const reference. At the language level, you
can express in more detail what the function really does.
But only where the function is defined, not where it is used. Remember,
we are talking about reading the client code of a function, where both a
function and a client code are written not by us, not about designing
the ideal prototype for a function. In any language, you will probably
not have problems with understanding functions written by yourself,
whether they are well or poorly designed.. at least for a first couple
of months.
>
In practice, of course, it's not that important, since in Java,
too, the name of the function (and the semantics of the type
you are passing) make it clear whether the object will be
modified or not.
Well, not "too". To see the semantics of the type, you need to jump to
the type definition (in both C and Java) -- but for the primitive types
it is not necessary (in C++, you have to jump to the definition of the
function in any case, even if just to see whether it takes const
reference or what).

-Pavel
Aug 12 '08 #23
James Kanze wrote:
>
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; 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.)
Pair programming and collective code ownership are even more effective
in preventing arcane or overly complex code. It's unlikely for a pair
to add such code and if by chance they do, the next pair to edit the
code will probably remove it!

--
Ian Collins.
Aug 12 '08 #24
On Aug 12, 12:15 pm, Ian Collins <ian-n...@hotmail.comwrote:
James Kanze wrote:
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; 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.)
Pair programming and collective code ownership are even more
effective in preventing arcane or overly complex code. It's
unlikely for a pair to add such code
It's unlikely for an individual programmer to add such code,
since he knows it won't pass code review. And code review is
far more cost effective than pair programming (in most cases, at
least).
and if by chance they do, the next pair to edit the code will
probably remove it!
With effective code review, there's almost no chance of the code
ever getting checked in with such a problem.

Of course, if we're talking about a public function, used by
many people on the team, it will be reviewed as part of design
review. And there's no risk of the developer changing it, since
he can't even check out the header files. (But such an
organization is only justified on fairly large projects.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 12 '08 #25
James Kanze wrote:
On Aug 12, 12:15 pm, Ian Collins <ian-n...@hotmail.comwrote:
>James Kanze wrote:
>>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; 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.)
>Pair programming and collective code ownership are even more
effective in preventing arcane or overly complex code. It's
unlikely for a pair to add such code

It's unlikely for an individual programmer to add such code,
since he knows it won't pass code review. And code review is
far more cost effective than pair programming (in most cases, at
least).
Possibly maybe in isolation, but pair programming coupled with
collective code ownership is at least as effective as code review
because it equates to continuous code review. It gives you the quality
of code review without interrupting programmer's work flow. Having
worked for many years with both styles, I don't think I could ever go
back to formal code reviews.

--
Ian Collins.
Aug 12 '08 #26
On Tue, 12 Aug 2008 06:06:57 +0000, Pavel wrote:
They were not even stopped by the fact a Java instance would take
several times more memory -- apparently most of them had more memory
than us... again, this is a pure observation and you can draw your
conclusions. Just remember a client cannot be stupider than a provider:
otherwise they would not have money to pay for the provider's wares and
still make profit...
I found your discussion interesting, but what the hell are you talking
about here? You seriously think there is a high correlation between
intelligence and wealth? I would think that just a wee big of real world
experience would destroy that misconception. But if you still hold on to
it, I'd recommend "Fooled by randomness", which has some words to say on
the subject.
Aug 12 '08 #27
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::operator++() :-) (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.

-- 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.

-- 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.

For the rest, expressivity is there for you to use, when
appropriate. It can obviously be abused, but that's not the
point. 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. 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. 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.)

(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.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 13 '08 #28
James Kanze wrote:
On Aug 12, 9:11 pm, Ian Collins <ian-n...@hotmail.comwrote:
>James Kanze wrote:
>>It's unlikely for an individual programmer to add such code,
since he knows it won't pass code review. And code review is
far more cost effective than pair programming (in most cases, at
least).
>Possibly maybe in isolation, but pair programming coupled with
collective code ownership is at least as effective as code
review because it equates to continuous code review.

By "collective ownership", I presume you mean rotating the teams
working on each part regularly (weekly, or whatever), so that
each bit of code gets someone new working on it on a regular
basis.
Pairs should rotate often. How often depends on the team. Some change
every 90 minutes or so, we found half a day worked for us.
I'll admit that I was unaware of this possibility until
a few months ago, when someone posted it here; it does address
one major problem with pair programming: that both people
working on the code (and those reviewing each other's work) are
"insiders", and that it's important for someone from "outside",
who wasn't involved with the code, to review it. I'm still not
convinced, however:

First of all, of course, pair programming more expensive.
That's simply not true. My (and other teams) experience is that a pair
is more productive then two individuals.
>
And is the original programmer present in the discussion when
the new team takes over?
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.
One of the most important aspects of
code review is that after a while, programmers end up writing
for the review, and not just for the compiler (and their
collegue who is as involved in the code as they are). They
learn from the feedback they get from the review, and end up
writing code that is clean, correct and maintainable from the
start.
When your code is continuously reviewed the same is true.
I find, too, that psychologically, the pride factor plays an
important role. It's *my* code that I present for review, and I
want something that I'm proud of, and that others will estime.
In XP teams, the team owns the pride :)
The "collective ownership" aspect shouldn't come into play until
a higher level---once I've delivered. In the end, it's much
like a team sport; you're proud of your teams accomplishments,
and you want to do your best for the team. But you're also
proud of your own contributions to that team (including your
contributions as a reviewer); you're proud that anyone can take
your code and understand it and modify it without problems.
To stretch the analogy further, teams function better with player who
know when to pass the ball rather than run with it.
But you sometimes want to interrupt the work flow. You want the
programmer to think about something else for awhile, before
coming back to what he was doing. (For the most part, this
happens naturally---at the end of the work day, I go home. And
the correct solution to the problem I was working on often pops
up automatically, as soon as I'm thinking about something else.)
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.
>Having worked for many years with both styles, I don't think I
could ever go back to formal code reviews.

Well, I've done a little pair programming (not much), and I
didn't care for it very much. Where as I just love reviews;
there's something particularly satisfying to have someone who's
only looked at my code for an hour or so come out and say they
liked it, because it was so easy to understand what was going
on, and to find the pertinent parts. And I learn from them,
even from relatively inexperienced programmers.
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.
(Again,
psychology plays a role: the times I've done pair programming,
I've always had considerably more experience than my partner,
to the point where the partner seems to consider me more of a
mentor than a peer, and was, perhaps, afraid to make any real
open comments. Where as in the code reviews, it seems clearer
that comments are wanted, since that's the only reason the
reviewer is there.
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.
Officially, at least: it's good policy to
mix the experience levels in code review, too, so that the
lesser experienced programmers learn from the more experienced
ones.)
Again, think how much faster they learn working in pairs with the more
experienced ones.

--
Ian Collins.
Aug 13 '08 #29
Ian Collins wrote:
<...>
In XP teams, the team owns the pride :)
For a real rush try Extreme Ironing ...

http://www.extremeironing.com/

meanwhile...aint this way O.T for clc++ ?

regards
Andy Little

Aug 13 '08 #30
On Aug 13, 11:17 am, Ian Collins <ian-n...@hotmail.comwrote:
James Kanze wrote:
On Aug 12, 9:11 pm, Ian Collins <ian-n...@hotmail.comwrote:
James Kanze wrote:
I'll admit that I was unaware of this possibility until
a few months ago, when someone posted it here; it does address
one major problem with pair programming: that both people
working on the code (and those reviewing each other's work) are
"insiders", and that it's important for someone from "outside",
who wasn't involved with the code, to review it. I'm still not
convinced, however:
First of all, of course, pair programming more expensive.
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.
And is the original programmer present in the discussion
when the new team takes over?
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.
One of the most important aspects of
code review is that after a while, programmers end up writing
for the review, and not just for the compiler (and their
collegue who is as involved in the code as they are). They
learn from the feedback they get from the review, and end up
writing code that is clean, correct and maintainable from the
start.
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.
I find, too, that psychologically, the pride factor plays an
important role. It's *my* code that I present for review, and I
want something that I'm proud of, and that others will estime.
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.
The "collective ownership" aspect shouldn't come into play until
a higher level---once I've delivered. In the end, it's much
like a team sport; you're proud of your teams accomplishments,
and you want to do your best for the team. But you're also
proud of your own contributions to that team (including your
contributions as a reviewer); you're proud that anyone can take
your code and understand it and modify it without problems.
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.
But you sometimes want to interrupt the work flow. You want the
programmer to think about something else for awhile, before
coming back to what he was doing. (For the most part, this
happens naturally---at the end of the work day, I go home. And
the correct solution to the problem I was working on often pops
up automatically, as soon as I'm thinking about something else.)
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.
Having worked for many years with both styles, I don't think I
could ever go back to formal code reviews.
Well, I've done a little pair programming (not much), and I
didn't care for it very much. Where as I just love reviews;
there's something particularly satisfying to have someone who's
only looked at my code for an hour or so come out and say they
liked it, because it was so easy to understand what was going
on, and to find the pertinent parts. And I learn from them,
even from relatively inexperienced programmers.
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.
(Again, psychology plays a role: the times I've done pair
programming, I've always had considerably more experience
than my partner, to the point where the partner seems to
consider me more of a mentor than a peer, and was, perhaps,
afraid to make any real open comments. Where as in the code
reviews, it seems clearer that comments are wanted, since
that's the only reason the reviewer is there.
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.
Officially, at least: it's good policy to mix the experience
levels in code review, too, so that the lesser experienced
programmers learn from the more experienced ones.)
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.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 13 '08 #31
#include <streamline>
#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
Aug 15 '08 #32
James Kanze wrote:
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::operator++()
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.hand 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:ja*********@gmail.com
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

Aug 15 '08 #33
Pavel wrote:
James Kanze wrote:
>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.
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'.

--
Ian Collins.
Aug 15 '08 #34
On Aug 15, 6:16 am, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:
#include <streamline>
#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;}
----------
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.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 15 '08 #35
On Aug 15, 9:50 am, Ian Collins <ian-n...@hotmail.comwrote:
Pavel wrote:
James Kanze wrote:
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.
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.
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'.
You've got considerable C experience as well:-).
cout << a << endl;
return 0;
}
(compiles and run without a warning on my cygwin, g++ 3.4.4).
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.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 15 '08 #36
James Kanze wrote:
On Aug 15, 9:50 am, Ian Collins <ian-n...@hotmail.comwrote:
>Pavel wrote:
>>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'.

You've got considerable C experience as well:-).
Not really, only about 28 years :)
>>(compiles and run without a warning on my cygwin, g++ 3.4.4).
>As it should.

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!

--
Ian Collins.
Aug 15 '08 #37
James Kanze wrote:
On Aug 15, 6:16 am, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:
>>#include <streamline>
#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;}
----------

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
Aug 15 '08 #38
Ian Collins wrote:
Pavel wrote:
>James Kanze wrote:
>>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.
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.
>
>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'.
It's not the address, but the value, but ok.
>
> cout << a << endl;
return 0;
}

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

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).
>Then tell me how much time it took you to guess.

Less time than it took to write this!
Good for you. I should have known..

....

-Pavel
Aug 16 '08 #39
James Kanze wrote:
On Aug 15, 9:50 am, Ian Collins <ian-n...@hotmail.comwrote:
>Pavel wrote:
>>James Kanze wrote:
>>>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.
>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?
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.
>>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'.

You've got considerable C experience as well:-).
>> cout << a << endl;
return 0;
}
>>(compiles and run without a warning on my cygwin, g++ 3.4.4).
>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
Aug 16 '08 #40
Pavel wrote:
James Kanze wrote:
>On Aug 15, 6:16 am, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:
>>----------
#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.
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.

--
Ian Collins.
Aug 16 '08 #41
Pavel wrote:
James Kanze wrote:
>On Aug 15, 9:50 am, Ian Collins <ian-n...@hotmail.comwrote:
>>Pavel wrote:
James Kanze wrote:
>>>>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.
>>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?
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.
>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.
I think the above comment form James is very pertinent here.

--
Ian Collins.
Aug 16 '08 #42
On Aug 16, 1:55 am, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:
James Kanze wrote:
On Aug 15, 6:16 am, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:
>#include <streamline>
#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;}
----------
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..
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.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 16 '08 #43
On Aug 15, 12:02 pm, Ian Collins <ian-n...@hotmail.comwrote:
James Kanze wrote:
On Aug 15, 9:50 am, Ian Collins <ian-n...@hotmail.comwrote:
Pavel wrote:
>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'.
You've got considerable C experience as well:-).
Not really, only about 28 years :)
You beat me by two.
>(compiles and run without a warning on my cygwin, g++
3.4.4).
As it should.
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.
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).
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.
Supposing the scripting language supports numeric addition.
(Historically, the Bourne shell didn't, and I've still the habit
of using expr, instead of ((...)).)
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.
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.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 16 '08 #44
On Aug 16, 4:33 am, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
Ian Collins <ian-n...@hotmail.comwrites:
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.
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.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 16 '08 #45
On Aug 16, 11:15*am, James Kanze <james.ka...@gmail.comwrote:
On Aug 16, 4:33 am, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
Ian Collins <ian-n...@hotmail.comwrites:
>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.

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

Aug 16 '08 #46
On Aug 15, 7:55 am, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:
James Kanze wrote:
On Aug 12, 8:06 am, Pavel <dot_com_yahoo@paultolk_reverse.yourself>
wrote:
[...]
Second, with regards to the function "increment":
-- Even in the case of Percentage, the way C++ spells it is
Percentage::operator++()

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.
:-) (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).
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..
-- 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?
Exactly. Why look further.
-- 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?
I would assume that any code which passed code review was
conform to the conventions in use in the company.
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.
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.
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".
The ability to say exactly what you want, clearly and concisely.
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).
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.
(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.
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.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Aug 16 '08 #47
Ian Collins wrote:
Pavel wrote:
>James Kanze wrote:
>>On Aug 15, 9:50 am, Ian Collins <ian-n...@hotmail.comwrote:
Pavel wrote:
James Kanze wrote:
>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.
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?
>A typedef would be an alternative.

How?
Truly, I am not sure what I meant. Apparently thought of replacing
template parameters. Did not read clear :-).
>
>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.
I think one of us is confused here. Java has BigDecimal as a regular
Java class -- it is in fact written in pure Java and the source is a
part of Sun's JDK distribution.

No, Java BigDecimal *cannot* be used with operators -- my point was
exactly that it cannot and nobody seems to suffer from it, and nobody
seems to even have voted or created a bug to add operator support there.
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.
Now what you refer to as expressiveness seems to be closer to what I
call syntax sugar. And my attitude to syntax sugar is: "nice to have
when it is safe". Safe includes unambiguous (not only technically, but
also from the point of view of some representative population of the
users -- that they understand the code and the consequences).
>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.

I think the above comment form James is very pertinent here.
well, you do not even want to know whether b*b - 4*a*c >= 0 and whether
a is a zero or very close to zero before taking sqrt?

In real programs, you have to introduce breaks often -- you almost never
just translate math formulas into a programming language. Not to mention
you often need to first re-factor formulas for reasons other than
catching pure domain errors; for example for numerical stability or for
efficiency reasons and after such re-factoring they often become
algorithms with much shorter formula-like pieces; but instead become
pliable to factoring out useful functions (think Horner scheme).

But even assuming such breaks are unnecessary, how really bad something
like

div(add(neg(b), sqrt(sub(mul(b, b), mul(4, mul(a, c))))), mul(2, a));

is (especially considering all editors now do parenthesis matching for
you)? Don't get me wrong, I would prefer operators and I will use them
in C++ myself for clearly numeric types -- unfortunately the language
does not limit their use for such types even though it has all the
information about the type at a point where an operator is used.

-Pavel
Aug 17 '08 #48
Pavel wrote:
Ian Collins wrote:
>Pavel wrote:
>>A typedef would be an alternative.

How?
Truly, I am not sure what I meant. Apparently thought of replacing
template parameters. Did not read clear :-).
OK.
>>
>>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.
I think one of us is confused here. Java has BigDecimal as a regular
Java class -- it is in fact written in pure Java and the source is a
part of Sun's JDK distribution.

No, Java BigDecimal *cannot* be used with operators -- my point was
exactly that it cannot and nobody seems to suffer from it, and nobody
seems to even have voted or created a bug to add operator support there.
I didn't realise it was a regular class (I don't do Java!).
>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.
Now what you refer to as expressiveness seems to be closer to what I
call syntax sugar. And my attitude to syntax sugar is: "nice to have
when it is safe". Safe includes unambiguous (not only technically, but
also from the point of view of some representative population of the
users -- that they understand the code and the consequences).
I still think most C++ programmers are familiar and at ease with
operator overloading. I'd even go so far as to saying they aren't C++
programmers if they are not. Don't forget the C++ design goal of
enabling user defined types to be as close to built in ones as possible.
well, you do not even want to know whether b*b - 4*a*c >= 0 and whether
a is a zero or very close to zero before taking sqrt?
Most of my types are integer and the operations used are basic arithmetic.
In real programs, you have to introduce breaks often -- you almost never
just translate math formulas into a programming language. Not to mention
you often need to first re-factor formulas for reasons other than
catching pure domain errors; for example for numerical stability or for
efficiency reasons and after such re-factoring they often become
algorithms with much shorter formula-like pieces; but instead become
pliable to factoring out useful functions (think Horner scheme).
I have a number of real world examples where I objects as parameters for
templates that perform basic arithmetic on their type. I'd hate to have
to specialise them for all non-POD types.
But even assuming such breaks are unnecessary, how really bad something
like

div(add(neg(b), sqrt(sub(mul(b, b), mul(4, mul(a, c))))), mul(2, a));
Close to indecipherable!
is (especially considering all editors now do parenthesis matching for
you)? Don't get me wrong, I would prefer operators and I will use them
in C++ myself for clearly numeric types -- unfortunately the language
does not limit their use for such types even though it has all the
information about the type at a point where an operator is used.
The most important parser is the human reading the code. We are used to
seeing arithmetic expressed with standard operators and can pretty well
subconsciously parse them. With anything else we have to consciously
parse the expression.

--
Ian Collins.
Aug 17 '08 #49
kwikius wrote:
On Aug 16, 11:15 am, James Kanze <james.ka...@gmail.comwrote:
>On Aug 16, 4:33 am, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
>>Ian Collins <ian-n...@hotmail.comwrites:
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.
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
See, they tried to confine themselves to smaller language.. They have
introduced a lot of other stuff later (like annotations) but for a long
time they were keeping the language small and it helped to attract
people and create useful libraries. Not they did not know operator
overloading, but they consciously rejected it. Generics IMHO is an
unfortunate addition to Java language; it is such additions that will
lead it to its death (given them out once, you cannot take them back);
but IMHO C++ is much ahead there, with operator overloading, implicit
template argument deduction and their intended and unintended
combinations with standard conversions being the worst culprits.

-Pavel
Aug 17 '08 #50

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

47 posts views Thread by David Eng | last post: by
35 posts views Thread by GTO | last post: by
reply views Thread by Fuzzyman | last post: by
29 posts views Thread by Zootal | last post: by
190 posts views Thread by blangela | last post: by
5 posts views Thread by KimmoA | last post: by
51 posts views Thread by Jon Harrop | last post: by
reply views Thread by NPC403 | last post: by
reply views Thread by zattat | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.