I come not to bury C++, but to praise it...

J

John J. Lee

Andrew Koenig said:
Perhaps you should cast around for a different C++ book while you're
at it, too -- maybe the one you found isn't well suited to your
particular learning style.

Andrew's own "Accelerated C++" is good (written with Barbara Moo). :)


John
 
P

python newbie

Are you against using C++ wrapped in a library such as wxWindows? This
library makes it pretty easy painless to write cross-platform stuff, but
even on Windows alone, it beats MFC or the going price of Delphi.
 
J

Jp Calderone

Are you against using C++ wrapped in a library such as wxWindows? This
library makes it pretty easy painless to write cross-platform stuff, but
even on Windows alone, it beats MFC or the going price of Delphi.

Except when it causes memory corruption and segmentation faults :(

Jp
 
G

Graham Dumpleton

.
.
.
.
.
.
I was still fussing with cfront in the early '90s.
Its era *had* passed by then, though.

Ahh yes, the good old days. Well maybe not.

I once played with version E of cfront once. Ie., before even version
1.0, the E
being for experimental. At least that is from memory what is was
called. That
was back in 1984 and even at that time version 1.2 of cfront was
already out
I think. At the end of that year I got a student vacation job at the
first company
in Australia to be using C++. We had access to beta versions of the
compiler
from AT&T/USL and I think during that time a beta version of 2.0
turned up.
Not sure how long after that it actually got released properly. It was
after that
that Sun and Centerline brought out compilers based on cfront. Note
that these
compilers still didn't implement templates, they only turned up some
number
of years later in version 3.0 in the early 90's some time. In the
interim we were using
a hacked up cpp which could understand enough of the C++ template
syntax
to allow us to make decent use of them. From memory, the first C++
compiler
to actually come out with support for templates wasn't even the
AT&T/USL
version 3.0 of cfront, instead it was a hacked up version of cfront
2.1 made to
support templates and was released by ObjectStore, the OODBMS
developer.
Don't think it supported template functions though, only template
classes.
Anyway later cfront 3.0 became more available. Actually, it was
version 3.0.1.
Version 3.0 mustn't have lived very long because we never actually got
to
see it. There was a subsequent cfront 3.0.2 and I think that was the
last of
them from USL. Sun and Centreline also came out with versions based on
cfront 3.0.1 before Centerline dissappeared altogether and Sun changed
to
the cafe based compiler which they developed. There was GNU C++ as
well,
but it was quite late to the game in providing a version with
templates which
actually worked. Lucid C++ was an interesting compiler but it also
died. At
that time the best compilers were probably those based on the EDG
engine. Oh
must not forget the SGI and HP versions of cfront 3.0.1. Ah, but then
maybe
we should forget the HP version. Anyway, there were a number of other
C++
compiler vendors as well, especially in the cross development arena,
but enough
already.
 
D

Derek

[...]
Maybe I didn't make myself clear. I counted the ease
with which memory can be corrupted in C++ as a minus for
C++ and a plus for Python. I agree with you.

No, you don't (assuming I understand Jp's post), because...
On the flip side, C++ can catch errors immediately that
Python will not complain about until runtime, and in this
imperfect world tests may not catch all such errors up
front. In this respect I consider C++ safer.

...you made no evaluation of the relative importance of
these two qualities (memory-safety and static type-safety).
Nor of the fact that C++ comes unavoidably packaged with the
more-lines-of-code-per-function-point anti-feature -- KIS!

Are you joking? Because if you have some magical way to assign a
meaningful relative importance to unrelated language features that is
sufficiently general to be useful, I'd like to hear it.

For *me* memory safety in C++ is not an issue. I use range-checked
containers, scoped pointers, shared pointers, etc. and don't encounter
memory management/safety problems.

For *me* the lack of static type safety in Python is an issue. We
have a lot of developers working on a relatively large Python
codebase, and sooner or later some edge case calls a function with an
argument who's type makes no sense. Sometimes tests catch the problem
early, sometimes they don't.
 
A

Andrew Koenig

The argument runs like this: If you don't have near-100% test
coverage, you are missing many bugs that static typechecking will not
catch. So don't do that (the fact that it's perfectly feasible to
have near-100% coverage, when given support from bosses where
relevant, has been repeatedly demonstrated recently). OTOH, if you do
have 100% coverage, the set of bugs that *are* caught by the static
typechecks, but *not* by the tests is usually very small, in practice.

There is a subtle fallacy in this argument, at least in the context of C++
and Python, namely that there is a significant category of errors that
static type checking (as C++ and some other languages do it) can detect but
can escape even 100% test coverage.

Before you get out your flame-thrower, please hear me out -- I am not saying
that this reasoning applies to all errors, or even a majority of them, but
only to a significant category. That category consists of programs where
the types of key objects are not known when the program is written, but are
known when the program is compiled.

Here's an example. Suppose you're writing a library sort function, which
you intend to be able to work with any kind of sequence. Suppose further
that you test it only with vectors. Then you might well have 100% test
coverage, but the code might break when you call it with another kind of
sequence, because it relies on some property of vectors that not all
sequences share.

In practice, C++ programmers often solve such problems by using templates,
which defer type checking until the last possible moment during the
compilation process. In effect, the compiler looks at each call to our
hypothetical sort function, and verifies that the type assumptions that the
sort function makes are valid in the context of that particular call. The
result is that the compiler can detect type errors that would show up in a
dynamically typed environment only if the function were tested with the
specific types that revealed the error.

The price one pays for this extra checking, of course, is that one cannot
call such a sort function with an argument with a type that is known only at
run time. But in practice, there are many cases where being able to defer
type checking until the end of compilation is just as useful as being able
to defer it until run time. I believe that many people who dislike static
type checking are unaware of this distinction.
 
J

John J. Lee

Andrew Koenig said:
There is a subtle fallacy in this argument, at least in the context of C++
and Python, namely that there is a significant category of errors that
static type checking (as C++ and some other languages do it) can detect but
can escape even 100% test coverage.

It may be subtle, but it's also the starting point for most of these
debates.

Before you get out your flame-thrower, please hear me out -- I am not saying

OK... :)

that this reasoning applies to all errors, or even a majority of them, but
only to a significant category. That category consists of programs where
the types of key objects are not known when the program is written, but are
known when the program is compiled.

Agreed.

[...snip example...]
In practice, C++ programmers often solve such problems by using templates,
which defer type checking until the last possible moment during the
compilation process. In effect, the compiler looks at each call to our
hypothetical sort function, and verifies that the type assumptions that the
sort function makes are valid in the context of that particular call. The
result is that the compiler can detect type errors that would show up in a
dynamically typed environment only if the function were tested with the
specific types that revealed the error.
Yes.


The price one pays for this extra checking, of course, is that one cannot
call such a sort function with an argument with a type that is known only at
run time. But in practice, there are many cases where being able to defer
type checking until the end of compilation is just as useful as being able
to defer it until run time. I believe that many people who dislike static
type checking are unaware of this distinction.

I do like static type checking. I *don't* like the price that C++
makes me pay for it in terms of lines of code and inflexibility. When
comparing Python and C++, the longer, more inflexible programs
required to solve problems in C++ introduce more bugs than its static
typechecking system removes. It's a shame some tiny fraction of the
trillion dollars recently allocated to George Bush's electoral
campaign <0.2 wink> can't be diverted to experiments to test this
hypothesis (but I guess those dollars are mostly fictional anyway ;-).

So, I think the various interface proposals that have been made for
Python are interesting. Also, it seems attractive to have static type
inference wedged into Python somehow (not holding my breath: I don't
even know if that idea really makes any sense in the context of
Python). But I see Python in its current state as a safer language
than C++.

Alex Martelli goes much further than I do:

http://www.google.com/[email protected]&rnum=1

[...]
I see static typing
as a theoretically-interesting field of no real applicability to my
work. If I felt otherwise about it, I would most likely be coding
in Haskell or some kind of ML, of course -- nobody's come and FORCED
me to choose a dynamically-typed language, you know?

And perhaps he's right: my attraction to static type inference in a
Python-like language is both theoretical and almost maximally vague
(and my grasp of the issues is weaker than Alex's), and I don't have
any decent ML or Haskell experience with to compare with my Python
experience...

See also the couple of posts near this article in the exchange between
Alex and David Abrahams (same one I posted in a followup to Cameron
earlier):

http://www.google.com/[email protected]&rnum=2


John
 
J

John J. Lee

Derek said:
[...]
Maybe I didn't make myself clear. I counted the ease
with which memory can be corrupted in C++ as a minus for
C++ and a plus for Python. I agree with you.

No, you don't (assuming I understand Jp's post), because...
On the flip side, C++ can catch errors immediately that
Python will not complain about until runtime, and in this
imperfect world tests may not catch all such errors up
front. In this respect I consider C++ safer.

...you made no evaluation of the relative importance of
these two qualities (memory-safety and static type-safety).
Nor of the fact that C++ comes unavoidably packaged with the
more-lines-of-code-per-function-point anti-feature -- KIS!

Are you joking?
No.


Because if you have some magical way to assign a
meaningful relative importance to unrelated language features that is
sufficiently general to be useful, I'd like to hear it.

(No funny business here, just straightforwardly trying to answer your
question to advance the debate:) Well, yes, I do: I think about it
rationally, just as you do. I think about the "unrelated" language
features (though I suppose few language features are truly unrelated),
consider their impact on things like detection and location of bugs,
and make a judgement about how they, as a result, affect the success
and costs of the development process.

I'm afraid I'm probably completely missing what you're getting at
here, though! (again, not trying to make any rhetorical point, just
puzzled)

For the particular issues at hand, Jp made an evaluation that looked
quite rational to me, as do your comments immediately below.

For *me* memory safety in C++ is not an issue. I use range-checked
containers, scoped pointers, shared pointers, etc. and don't encounter
memory management/safety problems.

Oh. That's interesting. Do those practices get rid of all such
issues?

For *me* the lack of static type safety in Python is an issue. We

Yes, many people -- including me! -- agree on this, I think (but not
everyone -- see the quote from Alex Martelli in my reply to Andrew
Koenig). The question is one of the relative sizes of the various
costs and benefits, and of the way those costs and benefits are tied
to each other in current languages. If only we could pick language
properties a la carte...

have a lot of developers working on a relatively large Python
codebase, and sooner or later some edge case calls a function with an
argument who's type makes no sense. Sometimes tests catch the problem
early, sometimes they don't.

I think we've been round this loop already. Schematically, though:
Static typechecking tests reliably for a small set of bugs. Unit
testing tests unreliably for a very large set of bugs. No controversy
so far, I hope. Now, the bugs found by unit testing are in practice
almost a simple superset of those found by static typechecking
(clearly, this point can generate much debate!). C++ buys you static
typechecking (gain: a small number of bugs found that your unit tests
miss), but also buys you a big jump in lines of code (loss: many extra
bugs created (amongst other losses)). I don't argue that this is a
fundamental limitation of static typechecking, or that Python is the
best of all possible worlds. I do claim that Python achieves a net
gain in safety over C++ by dropping the naive static checking found in
C++.


John
 
O

Oren Tirosh

[snip]

I also use C++ and Python as my main languages and I agree with your
comments. However, I don't agree that Python is inherently "safer"
than C++. At best I see it as a tie. For example, C++ let's you
corrupt memory among other "unsafe" things, most of which can be
avoided by using standard containers, smart pointers, etc. Python
lets you do "unsafe" things such as passing an object to a function
when it makes no sense to do so, which can lead to nasty runtime
surprises.

A traceback is *much* less nasty than memory corruption.

A traceback is also much less nasty than deciphering a 1000-character
long compiler error message reported in code that uses a heavily
templated library.

Oren
 
V

Valentino Volonghi aka Dialtone

Donn Cave said:
Python may have stricter dynamic typing than C++ has
static typing, but that's hard to quantify. On the
other hand, Python has no static typing at all. There
is no way to tell it ``this function must be applied
to a string and must return an int.'' If applied to
a list instead, there's a non-trivial chance it will
manage to do something absurd with it. If it returns
None under certain circumstances, there's a non-trivial
chance that value will be stashed away somewhere and
you'll later wonder where the heck that None came from.

You clearly don't know enough of python to talk like this about the
language features...

You need static typing (why then... I cannot see any good reason,
anyway...)? Well then, use pyrex. You'll find yourself writing code
like this:

cdef int a, b
def sum(int a, int b):
return a+b

Then using pyrex parser you would build a python extension module
which you will compile it. If you do errors using types it will catch
it. Anyway there's no need to use this stuff... absolutely no
reasonable need. Except if you need a lot of speed and you need to
implement an algorithm directly in C using native C types and not
python objects.
 
D

Derek

Oren Tirosh said:
A traceback is also much less nasty than deciphering a
1000-character long compiler error message reported in
code that uses a heavily templated library.

Absolutely correct. But remember that ugly template-related compiler
error messages are a reflection of current compiler technology, not a
fundamental limitation of C++. I suspect future compilers will make
debugging templates much easier.
 
P

Peter Hansen

Derek said:
Absolutely correct. But remember that ugly template-related compiler
error messages are a reflection of current compiler technology, not a
fundamental limitation of C++. I suspect future compilers will make
debugging templates much easier.

I believe I heard that claim, almost verbatim, sometime around the last time
I was actively using C++, which was about a decade ago...

-Peter
 
V

Ville Vainio

Peter> I believe I heard that claim, almost verbatim, sometime
Peter> around the last time I was actively using C++, which was
Peter> about a decade ago...

Yes, C++ doesn't suck, it's the implementations. C++ will rock any day
now. Honest.

The same is true for Python - Python isn't slower than C, it's just an
artifact of the current implementation. Python-in-the-sky actually
runs 10-20% faster than C++ code.
 
D

Derek

Peter Hansen said:
I believe I heard that claim, almost verbatim, sometime
I around the last time was actively using C++, which was
I about a decade ago...

Hmmm. As late as 1997 I couldn't get consistent template behavior
between BCC, GCC, and MSVC. To this day most compilers are broken in
some way or other with respect to templates. Even basic STL
containers like std::vector were often improperly implemented or
incomplete just a few years ago (try GCC 2.95 or VC6 to see what I
mean). I also don't remember typelists, traits, policies, or other
modern template techniques being popular a decade ago.

My point is that while templates aren't new, their widespread use is.
I'm not surprised that compiler vendors are only now looking at ways
to improve template-related compiler errors.
 

Ask a Question

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

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

Ask a Question

Members online

Forum statistics

Threads
474,283
Messages
2,571,407
Members
48,101
Latest member
LinetteDeg

Latest Threads

Top