[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Strong Typing, Dynamic Languages, What to do?



Anton van Straaten <anton@appsolutions.com> writes:

> > Also, you are assuming that every access in C++ is unsafe, or that
> > for every potentially unsafe access some validating abstraction has
> > to be written.  Sometimes it comes in handy, but if you write code
> > that depends on range
> > checking, I'd claim that the program is seriously buggy.
> 
> Of course!  The point about protecting the integrity of a language's
> types is that it prevents problems from escalating from simple,
> reportable logic errors, into hard-to-detect bugs that may end up in
> production code, even unbeknownst to the developer.  In many
> circumstances, turning off runtime integrity checks for performance
> reasons may be perfectly acceptable.  Never being able to turn them
> on, and suffering hard-to-detect bugs as a result, is not.

Such a feature would be a nice addition, and could be marketable.  A
debug-mode automatic range checker.  They do have tools to do runtime
memory debugging, to watch these things, but they're add-ons.  Borland
does have CodeGuard, for example, which compiles some additional
information into your application, to enable CG to detect buffer
overruns, multiple deletes, range errors, leaks, and a few other types
of problems.

As long as this stuff is optional, it's all prefectly fine with me.  :)


> > * the original bug remains in your code, which keeps on
> > calculating the wrong value (which is now "allowed" by your
> > program)

> I don't understand what you mean.  Type-safe languages generate an
> exception in the case of an error like this, so there's no sense in
> which this is "allowed".  In fact, it's C++ that can "allow" this in
> the sense that memory corruption due to an error like this may not
> be detected until much later (too late).

I meant that the bug is allowed in the sense that if you catch/handle
the exception, your program continues to run.  (In C++ it keeps
running too but usually will crash, which unambiguously brings the
problem to your attention, even if it's mysterious.)

But I agree with you that throwing an exception is a good way to catch
the problem.  I think in either case, extensive testing is the only
way to be sure a program works, regardless of how the language treats
the error.

Ideally, the bug is caught before the program is running in
production.  With sufficient testing this will be the case.  Then the
range checking is no longer necessary, but is a nice "safety net" just
in case.  It's for those time-critical loops where if you know it's
bug-free you might not want to keep checking ranges that you can be
sure are valid.


> > * now that the access has translated into an error, recovery code
> > is written to handle the error.  This is misleading to people,
> >   because they think that it's OK to go out of bounds in the first
> >   place, and that if they do, all that is necessary is to handle the
> >   error.
> 
> Sorry, but I think you're way off-base here.  If a programmer
> doesn't take the correct action in response to an error that's
> reported clearly and accurately by the language, that's the
> programmer's fault.  I'm saying that C++ doesn't report the error in
> the first place, and that can't reasonably be construed as a good
> thing.

I do not argue with your point here, it is the programmers fault,
100%.  Perhaps I'm jaded by the large number of bad programmers I've
run into who do just consume exceptions and do nothing about it, not
even log it or bring the problem to the user's (nor programmer's)
attention.  


> The only way to justify these kinds of shortcoming is historically,
> and by the current state of software technology in general.  I can't
> see how it can reasonably be argued that the inability of a language
> to protect its types is a feature.  Being able to turn off runtime
> checks for performance reasons, once a program is debugged and
> tested, can be desirable, but the inability to automatically guard
> against this, if you want to, especially during development, is bad.
> In C++, The switch for the "unsafe" feature is permanently turned
> on.

I can only partially agree.  If you use the bare-bones language, you
have all the troubles you suggest.  But few people work at that level,
except the "C++ as a better C" programmers.  You write a class to do
some work, and you can add all the range checking you want to
encapsulate/abstract whatever it is you're doing.

Then you work in terms of your abstractions, and the problems you
describe become much more rare.

The real point of difference we have, I think, is where this logic
belongs.  You think it's the language compiler's job to do the
checking, and I think that it can rightfully be put in user code.  I'm
sure to hold the unpopular position, especially in a Scheme group, but
it has worked very well for me, and I like having the control over my
code that I have.

> I'm not saying C++ is an unusable or useless language.  I've written
> hundreds of thousands of lines in it myself, shipped commercial
> products written in it, and I'm still using it.  I'm merely pointing
> out that aspects of it which many people take for granted as
> inevitable could be improved, and that the current behavior
> shouldn't be defended as being somehow fundamentally valid.

Absolutely.  C++ is ugly, difficult, slow-to-compile, produces large
binaries (template bloat), and has all sorts of issues.  It's far from
the perfect language, but on the other hand, all the other language
that come along trying to be "just the good from C++ and none of the
bad" almost always end up less capable, or require huge libraries to
compensate. 


>  Many C++ developers are very used to running bounds-checking tools
> and the like to compensate for its deficiencies.  They also
> regularly rely (even if inadvertently) on operating system memory
> protection to tell them when a range or pointer bug is present.

This is true.

> This is accepted as a status quo, but it's unlikely to remain
> acceptable as mainstream technology improves.  (C++ is already
> taking market-share heat from Java over this issue).

Perhaps, I don't follow Java.

> Sure, you can guard against these problems, and most competent
> developers don't tend to find them a burden.  You've found this to
> be the case. But if you've worked with teams of programmers using
> C++, you can't tell me you've never seen any of them spending time
> tracking down an access violation due to these kinds of issues.  One

Of course we all have, but clearly some programmers cause this type of
hunting far more often than others.  It may be related to the amount
of attention to details that programmers in general have (or lack.)
I'm amazed by how bad most C++ programmers I meet actually are.  Is it
the language problem for being so difficult, or is it the industry's
fault for tolerating underqualified programmers acting as if they were
competant? 

> only has to look at commercial shrinkwrapped software to see this,
> where unclean crashes are a common occurrence.  If everything were

... which is one of the reason I'm on Linux.  :)

> written in type-safe languages, software would be significantly more
> reliable.  What I'm talking about is an issue related to the costs -
> in both developer and user time, and cash - of using the language.

For what it's worth, I've posted several times on the C++ groups I'm
on that I'd rather program in Scheme.  It is a fun, safe, and easy
language to use, and with a good interpreter/compiler it can be very
fast as well.  For most applications it would be a great choice, I
think, and as you say, it may be less expensive to use.  (I've never
used Scheme for anything large, and have no idea how/if it breaks down
under large projects...)

> I'm not suggesting that everything *can* be written in safe
> languages, as of today.  Theoretically, it's possible to write
> everything in a safe language and have it perform on par with the
> best compiled code out there.  Various examples of such languages
> exist.  But in practice today, mainstream and commercially accepted
> tools to do this aren't always available, so language selection is
> often driven by the realities of performance requirements.  Often,

... and developer availability.  In the last three years of resumes
I've seen, only one has listed Scheme, for example.  (Though many list
C++ that shouldn't... :)

> such choices are quite valid or at least easily defended: the case
> of importing hundreds of millions of stock quotes sounds like one
> such case.  In many, *many* other cases, though, languages like C or
> C++ are used without good technical reasons, and their shortcomings
> are accepted when they don't have to be, and probably shouldn't be.

I totally agree.  Still, I can write an extension that handles the
time critical code and use Scheme for most of the rest.  So even then,
when a concession needs to be made, it doesn't have to be a big one.

> > C++ has changed a lot since then.
> 
> Yes, I know.  My comment was intended to indicate that I didn't just
> read "Teach Yourself C++ in 21 Days" and draw my conclusions from
> that.

Sorry.  (Most C++ programmers I run into learned from brightly colored
books, unfortunately.) 

>  I've avidly consumed every new book on advanced C++ techniques,
> absorbed new features as they come out, and worked with some of the
> most advanced frameworks.  But there's a sense in which this is all
> window dressing on an insufficiently robust base.  I don't like
> doing work that I know I shouldn't have to do, and C++ makes me do
> that.  Being aware of its shortcomings and the underlying technical
> factors allows for more appropriate choice of tools.

I know what you mean, and have started digging into my scheme books
again (I've been away from it for a few months) and really appreciate
having such languages available.  They do allow things to be done in
ways that are so much easier than in C++ that sometimes it's hard to
believe.  (For example, networking and multi-threadding in mzscheme is
incredibly easy, but in C++ it requires immense amounts of detail, or
huge libraries like ACE.)  You give up some low-level control, but for
something that doesn't need those details, it sure is a nice way to go.

-- 
Chris