IWETHEY v. 0.3.0 | TODO
1,095 registered users | 0 active users | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New Something like that, yes
At this point, I vote we hunt up Bjarne and kick him in the nuts.


Who's with me?

I'm just about ready to throw up my hands and say to my class, "Screw this, you're learning Python!"

Tom Sinclair

"Man, I love it when the complete absence of a plan comes together."
- [link|http://radio.weblogs.com/0104634/|Ernie the Attorney]
Expand Edited by tjsinclair April 25, 2003, 01:57:53 AM EDT
New I've been trying to do that for years
and then we go after Gosling...



"Packed like lemmings into shiny metal boxes.
Contestants in a suicidal race."
    - Synchronicity II - The Police
Expand Edited by tuberculosis Aug. 21, 2007, 05:47:23 AM EDT
New Barney is not responsible...
...for the fucked-up pile that passes as the STL in GNU 2.x.y!!!

It's the implementation, stupid!

I got no problem with nut-kicking. Just pick the correct target, OK?
jb4
"" We continue to live in a world where all our know-how is locked into binary files in an unknown format. If our documents are our corporate memory, Microsoft still has us all condemned to Alzheimer's."
Simon Phipps, SUN Microsystems
New Move farther up the food chain
The decision to create a language that requires automation of extra code generation at compile time simply to try to get around storing a little metadata is at the core of the problem.

If C++ had a sane philosophy, then templates would be unnecessary and you could have collections that worked properly across arbitrary types.

At the very bottom of it all is the attempt to build an OO-like language on top of a portable assembler by abusing the linker. This attempt to use conventional static linking technology to produce simulated late binding has, with a bit of experience, turned out to be a really stupid idea.

For his dogged refusal to admit he was wrong, his nuts ought to be considered targets for boots.



Within C++, there is a much smaller and cleaner language struggling to get out. (Bjarne Stroustrup)

Uh huh, we used to call it C. (me)
Expand Edited by tuberculosis Aug. 21, 2007, 06:14:23 AM EDT
New OK, I'll bite...
If C++ had a sane philosophy, then templates would be unnecessary and you could have collections that worked properly across arbitrary types.

OK, then, How?

Or do you advocate allowing a given collection instance to collect any old thing (or, more accurately several different types of any old thing)?

If the answer to the above is YES, we've already got that...its called Visual Basic (among other things...)!
jb4
"We continue to live in a world where all our know-how is locked into binary files in an unknown format. If our documents are our corporate memory, Microsoft still has us all condemned to Alzheimer's."
Simon Phipps, SUN Microsystems
New Errr...
Dude, that's exactly how Objective C, Smalltalk, Python, Perl, Java, and many other OO languages work. By allowing collections of arbitrary objects.

C++ is the only "OO" language I've used that constrains that behavior, and it's a friggin' major pain in the ass.
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New I've heard strong typing called several different things...
...including "a major pain in the ass".

People who call it that are, of course, wrong (or VB programmers).

So containers in your world would simple contain pointers...err...'scuse me!...references... to the base-level object. And, of course, since everything is derived from that base-level object, I could store instances of any object type I want, so long as I make it look to the collection as an instance of the Base Class(tm).

Seems to me that whatever I might gain in "flexibility", I'm going to pay back in error checking or RTTI checking...with interest not seen since the 90's.

Great!

I'd rather not live in your world...I'll just continue applying discipline and design my programs ahead of time, thankyewverymuch!
jb4
"We continue to live in a world where all our know-how is locked into binary files in an unknown format. If our documents are our corporate memory, Microsoft still has us all condemned to Alzheimer's."
Simon Phipps, SUN Microsystems
New Strict typing is like training wheels.
Once you know how to design properly, it isn't necessary any longer. ;-)

People who call it that are, of course, wrong (or VB programmers).
Wrong. See? Two can play at that game.

So containers in your world would simple contain pointers...err...'scuse me!...references... to the base-level object. And, of course, since everything is derived from that base-level object, I could store instances of any object type I want, so long as I make it look to the collection as an instance of the Base Class(tm).
Correct, minus the snide remarks.

Seems to me that whatever I might gain in "flexibility", I'm going to pay back in error checking or RTTI checking...with interest not seen since the 90's.
Emphasis mine. Come back when you have actually done a serious amount of programming in Perl, Python, Smalltalk, Objective C, or Java. Until then, you simply don't know what you're missing. Not to mention you're just plain wrong. There is no lack of error checking or RTTI with this model. That's a non-sequitur.

I'd rather not live in your world...
It would appear that you don't live in my world. Therefore your opinion in this matter is lacking the experience to make it a valuable one. Sorry.

I'll just continue applying discipline and design my programs ahead of time, thankyewverymuch!
Nice jab. Wrong-headed, however. See my comment above.

If all you have is snide remarks, then I'll file your opinion along with other opinions from people without actual experience (like Bryce -- sorry, jb, but if the shoe fits...).

Now, on a more serious note: design and discipline are necessary NO MATTER WHAT the paradigm. Once you are a capable designer, however, the strict typing becomes more of a pedantic hassle than a help -- it's all just unnecessary bookkeeping.

In my experience, the lack of strict typing makes a negligible difference for safety. ESPECIALLY if you are using unit tests properly (you do use them, don't you?). It Simply Is Not An Issue, and the only people I see arguing that it is an issue, are the ones who don't have the experience in using it that I do.
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New Re: Strict typing is like training wheels. Or Helmuts?
Look, Scott, in your paradigm I can store in one of your untyped collections an integer right next to a Locomotive object...when what I really wanted was a collection of Strings. And nothing keeps me from doing that...well, except your vaunted "unit testing" (In answer to your question, Yes. But let me tell you a little anecdote about relying on unit testing. The last two medical device projects I worked on did extensive unit testing, under protocol. The code base was somewhere on the order of 300,000+ lines of code each. Unit testing of the entire code base found a grand total of 2 legitimate defects (both having to do with the possibility of dereferencing NULL) for each of the projects...4 total over 600,000 LOC. Cost about US$500,000, each. Code inspection identified about 30 times that number of defects. So relying on unit testing to identify defects is not always cost effective). Further, it's not clear that unit testing would detect the mistake that I describe above, either, unless the tests were specifically designed to trap such mismatches.

And what would you unit test? The container? No...that won't work, as the ability to store anything from Soup (objects) to Nuts (objects), in any order, in any ratio, is correct operation. So we unit test the classes that contain the containers, right? OK, except that storing the "wrong" thing in such a container wouldn't be identifiable until you pulled the item from the container, and tried to use it inappropriately. Which, in general, would result in some form of a crash. Since it is known to be inpossible to unit test all permutations of inputs in certain environments, one must then up the ante to try to trap these things at the integration level (you do use integration testing, don't you?). As trapping such defects at the integration level is generally understood to cost an order of magnitude more than catching the same defect at the unit testing level (which in turn, is generally recognized to cost an order of magnitude more than catching the same defect and the implementation level), catching this sort of bug in the way you describe can become rather expensive.

In the mean time, my "training wheels" as you so snidely refer to them (Pot. Kettle. Black.), would catch this error at the implementation level (by not letting me even compile the error), at pennies on the dollar.

Now, I'm very willing to admit that misusing a container is an error that I'd occasionally make. And, as good as you are, Scott, it's one that you are probably equally likely to make. Neither of us would make this error often, and we would both certainly design apps so as to know what we're storing (and pulling) from a given container. Nonetheless, given human frailty, errors do happen. For my part, I'd prefer to find my error sooner rather than later. Wouldn't you?
jb4
"We continue to live in a world where all our know-how is locked into binary files in an unknown format. If our documents are our corporate memory, Microsoft still has us all condemned to Alzheimer's."
Simon Phipps, SUN Microsystems
New You have much to learn
There are some developers in this forum with deep experience in several different languages and some of us are C++ experts with large scale implementation experience.

So don't take that superior tone here - it won't fly. Scott certainly knows whereof he speaks having just survived a particularly nasty porting ordeal.

in your paradigm I can store in one of your untyped collections an integer right next to a Locomotive object...when what I really wanted was a collection of Strings. And nothing keeps me from doing that


First - Smalltalk, ObjectiveC, Python, etc are dynamically typed and the typing is plenty strong. In fact, its strong enough to allow you to recover from your errors in your program without crashing. Only C and C++ routinely crash as a result of errors.

Second - there's a lovely special value called NULL in C++ that you can store along with the locomotives, the integers, and the strings, that will still crash your program when accessed and your vaunted static type checking won't catch this. Nor will it save you from another programmer deleting your object prematurely. These are both really common errors in C++ (and the NullPointerException is probably the most common error in Java).

Third, how much extra memory do you have to store container<foo*> and container<bar*> which are going to produce identical chunks of machine code? The template mechanism is stupid about combining this code to minimize size.

each. Code inspection identified about 30 times that number of defects.


Code inspection is unit tests you run in your head. Write the tests that will make the code you are inspecting demonstrate the problem and you're on your way to doing a good job writing unit tests.

storing the "wrong" thing in such a container wouldn't be identifiable until you pulled the item from the container, and tried to use it inappropriately. Which, in general, would result in some form of a crash.


Actually, in Smalltalk it would put a debugger on the screen and I'd tinker a bit, fix the problem, and click "proceed". The environment that helps you fix found defects fastest is the one that helps you produce the highest quality of code.

ObjectiveC would try to forward the message to a delegate, then throw a catchable exception, you could code for that and identify the problem with some decent idea about where the problem was. You'd do the same in Java BTW, which has static typing but no template mechanism.

In practice these kinds of problems are easy to identify and fix quickly. They seldom make it to a shipping product. Its the memory errors that are usually subtle.

my "training wheels" as you so snidely refer to them (Pot. Kettle. Black.), would catch this error at the implementation level (by not letting me even compile the error),


That particular error is probably the least common error I see. I understand the motivation to put this effort into catching the error at compile time. There are no runtime facilities for dealing with it if it happens (and it still happens). IOW, the cost of fixing an error in C++ is magnitudes higher than fixing errors in dynamic languages - not the least of which is the excessive expense in recompile and relink time that C++'s brain dead runtime model requires. Thus, fixing such an error in Smalltalk costs minutes, ObjectiveC or Java cost hours, and C++ would take at least a day (that was our metric - one to two days per reported bug).

I did that for 5 years, climbed to the top of the mountain, and concluded it was a shit pile. I don't bother with the language anymore except to write glue to connect libraries to other things. The C++ philosophy just isn't true. Its propaganda (which you seem to have absorbed in full measure). They use adjectives to describe software development in C++ like "guarantee", "correctness", "dicipline", "strong", "process", "robust", and so forth. Whatever.

I only know that 12 years of professional systems development in 5 different languages (C, C++, Objective C, Java, and Smalltalk), have given me a pretty good feel for what factors produce reliable systems at reasonable cost and what is detrimental. C++'s swiss cheese type system, lack of meta data, sneaky type conversions, and stupid link mechanism are A) not helpful B) overly restrictive C) cause bugs.




There are only two things wrong with C++, The initial concept and the implementation -- Bertrand Meyer

Expand Edited by tuberculosis Aug. 21, 2007, 06:25:06 AM EDT
New Irony
I am astounded at C++ people who refuse to use dynamically typed languages because they can't bear to take the risk, who don't want to talk about memory management issues.

Comments about beams and motes come to mind...

Cheers,
Ben
"good ideas and bad code build communities, the other three combinations do not"
- [link|http://archives.real-time.com/pipermail/cocoon-devel/2000-October/003023.html|Stefano Mazzocchi]
New Additionally...
I am a lot more impressed with arguments like, "I tried language Foo for 5 years, and here are the exact problems with it" as opposed to ones like, "I think language Foo is a bad thing, because this might happen, and this might happen, and this might be a problem."

:-)
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New That's the C++ propaganda
the whole thing is based on fear (of mis-using a pointer).

That's the only kind of error the type checker/template madness helps with.

Here's a lovely little canonical example. Much is made of using a template to implement a max function rather than the old macro.

template<class T>
const T& max(const T& t1, const T& t2) { return t1 > t2 ? t1 : t2; }

now try it with:
int i = 7;
long j = 5;

max(i,j); // compile error WTF? This is useless.

they both have to be the same type.

Things I want to compare are hardly ever the same type (due to odd choices in int, long, short, char, unsigned variants, etc...

And templates don't do type promotion. So you'll have to cast (which is a great way to shoot yourself in the foot - like a certain rocket telemetry system showed).

Or use the macro - which does the correct promotion (like you would expect).

const char * type(int i) { return "int"; }
const char * type(long i) { return "long"; }

cout << "max " << type(i > j ? i : j) << " " << (i > j ? i : j) << endl;
// prints "max long 7"

So templates are still stupid.




"Packed like lemmings into shiny metal boxes.
Contestants in a suicidal race."
    - Synchronicity II - The Police
Expand Edited by tuberculosis Aug. 21, 2007, 06:28:02 AM EDT
New Wrong usage
template <class T1, class T2>
T1 max(T1 a, T2 b) {
if (a > b) return a;
return b;
}

int main(int argc, char *argv[])
{
float v1 = 10;
int v2 = 20;

max(v1, v2);
}


And, I am sure that someone who knows templates better than me can figure out the return value problem.

--

Want to be original? Start with a great template!
New Return value problem
you nailed it - how do you tell which type, T1 or T2 should be the return value? And how do you write the code such that the correct precision is maintained in the result?

Answer: you specialize the template - to the point that you've fully specified all possible overload sequences and then the template has shown itself to be worthless in this case (except for the everything-is-a-T case).

you could try this:

template<class T>
double max(double x1, T x2) // if there's one double they're all double
{
return x1 > x2 ? x1 : x2;
}

to save some work - but you'll get an ambiguity if you try max(double, double) between the max is all T's and max T1 T2 definitions.

Thus, C++ can help you expand work to fill all available time with no trouble at all.

Or you could use a macro.



"Packed like lemmings into shiny metal boxes.
Contestants in a suicidal race."
    - Synchronicity II - The Police
Expand Edited by tuberculosis Aug. 21, 2007, 06:33:56 AM EDT
New I'll take a look for the solution for ret value
In the meantime, have a fill of this: a guy at the place where I work uses templates to overload _integers_ with tracking code. He will then use those overloaded integers in the contexts wher he wants to collect stats. For the user, it's still an integer, slightly larger in memory. Stats collector has a thread to get snapshots and remember them.

This struck me as a very Smalltalk-ish thing to do. :)
--

Want to be original? Start with a great template!
New Re: Return value problem
It's interesting - I've done most of my C++ coding in some numerical/mathematical context - needless to say, the occasion to use templates came up again and again - and then I'd think - no, the very fact that I'm thinking about this means these things are enough different to treat differently, and so forget this stupid template.

See, it's not really a template - it's a second, backdoor attempt to have a scalable type of data, since the objectness in the front door effort is a sort of fake.

Finally I'd accomplish making the differences manifest with overloading by hand - which no doubt is all the template is doing in the first place, and the code made much more sense.

-drl
New In the end
you do need different implementations for different types, so "overloading by hand" is inevitable. It's nice to have compiler do it for you.

I agree that templates represent another, backdoor attempt at real type system, after virtual functions failed to deliver. I am beginning to think that templates are simply Smalltalk-style metadata, represented in many, many versions of generated code. Just like in Lisp one can implement lists with closures, the same way one can replace metadata with lots of generated code. To some extent. There have to be better statically-typed languages.
--

Want to be original? Start with a great template!
New A better statically typed language - have you tried Haskell?
"good ideas and bad code build communities, the other three combinations do not"
- [link|http://archives.real-time.com/pipermail/cocoon-devel/2000-October/003023.html|Stefano Mazzocchi]
New Read the tutorials
it is somewhat related to the ML series IIRC, the most popular being OCAML I think.

There are some interesting ideas in there and I can think of two language research projects that are also working on similar typing ideas - one called slate which is being implemented in squeak, and the needle project.

The thing that keeps me from bothering to write code in languages like these is lack of platform interface support - ie, is there a bridge to most system routines I might want or a reasonably complete library availble. (for instance oberon was touted as being a great oo environment for awhile - but it had its own everything and always looke really ugly and alien on all the platforms I've seen it run on).



"Packed like lemmings into shiny metal boxes.
Contestants in a suicidal race."
    - Synchronicity II - The Police
Expand Edited by tuberculosis Aug. 21, 2007, 12:41:27 PM EDT
New Today's link at /.
An [link|http://www.paulgraham.com/hp.html|article] on "hackers".

>>>>>>>>>>>>>>>>>>>
We need a language that lets us scribble and smudge and smear, not a language where you have to sit with a teacup of types balanced on your knee and make polite conversation with a strict old aunt of a compiler.
<<<<<<<<<<<<<<<<<<<
--

Want to be original? Start with a great template!
New Interesting example, Todd
template<class T>
const T& max(const T& t1, const T& t2) { return t1 > t2 ? t1 : t2; }

I must say, I'm a bit confused by this, as what you've done by typing the parametters as const T& is using the C++ mechanism for enjoining the compiler from doing a type promotion on a parameter, then complaining that it won't do type promotions.

If you want it to do type promotions, specify the template thus:

template <class T>
const T& max (T t1, T t2)
{ return t1 > t2 ? t1 : t2; }

But wait, you'll complain, what if T is a BigAssClass type? Passing a BigAssClass object by value is not recommended, as its too big, and you don't want to load the stack with such a monstrosity. That's quite true, but then, you wouldn't want to convert a BigAssClass to an int (or float, or double, or whatever), either, would you?

[edit: used the same name for the BigAssClass type...consistency, you know...]
jb4
"We continue to live in a world where all our know-how is locked into binary files in an unknown format. If our documents are our corporate memory, Microsoft still has us all condemned to Alzheimer's."
Simon Phipps, SUN Microsystems
Expand Edited by jb4 May 6, 2003, 05:26:41 PM EDT
New Umm...
wouldn't that require that t1 and t2 be of the same type and return only that type?

(course, you could do a return of the address of the object, casted to a void pointer...then you could return either object, but that's just me).
New And what would you cast the void* back to afterwards?



"Packed like lemmings into shiny metal boxes.
Contestants in a suicidal race."
    - Synchronicity II - The Police
Expand Edited by tuberculosis Aug. 21, 2007, 06:38:46 AM EDT
New Yeah, you'd have to test for the type...
or assign it to a base class pointer that the two types are dervived from.

Of course, there are cases were you'd have to the for type for your max macro.
sprintf("%d", max(long, float));


New Aaaaaahhhhhhh!

sprintf("%d", max(long, float));


Why don't you just juggle torches while you gas up your car?

First, you're short an argument to sprintf - you forgot the destination buffer.
Second, the xxxxf family (scanf, printf, and their variants), have no place in C++.

Use strstreams.

char buffer[50];
ostrstream ost(buffer,sizeof(buffer));

ost << (max(aLong, aFloat)) << ends;



"Packed like lemmings into shiny metal boxes.
Contestants in a suicidal race."
    - Synchronicity II - The Police
Expand Edited by tuberculosis Aug. 21, 2007, 06:39:11 AM EDT
New *chuckle*
d00d, that was off the cuff. It wasn't meant to be code perfect - just to illustrate a problem with max.

Second, use stringstreams. strstreams are the old style char* stuff, iirc. You have to unfreeze any .str() you create via them...yuk.
New Oh, you illustrated several problems
max was the least of them.

Thanks for the tip on the updated streams. I can't say they're an improvement though.

Item 1: YTF did they blend istream and ostream in stringstream? Can you use it as a queue? Will it block on reads or throw an exception? We already have pipes for this stuff.

Item 2: The new version is written in terms of string. This is OK, but string does heap allocation all the time so for small buffers its likely to suck compared to stack memory. You'll note that in my code I don't need to call str or freeze as I already have the buffer. So it looks like streaming to a known memory location is no longer supported. So much for high performance code.

Item 3: You can construct one with no buffer (it'll use a string) or a const string&. Nifty. Suppose I want to stream into my own string. I'll miss WriteStream on: myString.

WTF are this people thinking?



"Packed like lemmings into shiny metal boxes.
Contestants in a suicidal race."
    - Synchronicity II - The Police
Expand Edited by tuberculosis Aug. 21, 2007, 06:39:47 AM EDT
New Your code should crash
returning a reference to a temporary stack variable like that. I'm assuming this was a copy paste error - its one that can crash your program with a memory access violation though (if you're lucky).

Tell me again about the safety of the language and how it keeps you from screwing yourself.

I must say, I'm a bit confused by this, as what you've done by typing the parametters as const T& is using the C++ mechanism for enjoining the compiler from doing a type promotion on a parameter, then complaining that it won't do type promotions.


Funny, I thought I was employing the C++ mechanism for reducing stack growth.

But wait, you'll complain, what if T is a BigAssClass type? Passing a BigAssType object by value is not recommended, as its too big, and you don't want to load the stack with such a monstrosity. That's quite true, but then, you wouldn't want to convert a BigAssObject to an int (or float, or double, or whatever), either, would you?


Really? I can imagine all kinds of scenarios of BigAssOrderedType. Here's a good one - suppose I have 2DVector and 3DVector. It makes sense that I can promote a 2Dvector to a 3Dvector - and if I mixed them, I'd certainly like promotion to happen towards 3Dvector. So maybe I implement operator 3Dvector on 2Dvector (being careful not to implement operator 2Dvector on 3Dvector lest we end up in ambiguity hell).

Boy, we've sure thought a lot about types without giving what the heck we're supposed to be doing a lick of thought. Thats why I think C++ is unredeemable shit. Working the type system consumes all available cycles and often - you still don't have an ironclad solution (like here).

The bottom line in this scenario is clearly, passing classes by value is just not worth the trouble it causes and the feature ought not to be there at all. Yes C allows you to pass structs by value - no that wasn't a good idea.

The smart thing to do would be to simply ignore the feature like Objective C did (objects only live on the heap - object references can live on the stack). The attempt to unify classes and structs was, in retrospect, a really bad choice.



"Packed like lemmings into shiny metal boxes.
Contestants in a suicidal race."
    - Synchronicity II - The Police
Expand Edited by tuberculosis Aug. 21, 2007, 06:38:33 AM EDT
New My code does crash, but not as often as you think.
First, if you follow my posts, you'll know that my typing skills (such as they are) are nothing short of abyssmal. ;-)

I must say, I'm a bit confused by this, as what you've done by typing the parametters as const T& is using the C++ mechanism for enjoining the compiler from doing a type promotion on a parameter, then complaining that it won't do type promotions.

Funny, I thought I was employing the C++ mechanism for reducing stack growth.

To a degree, that's true. But you have also enjoined the compiler from doing the standard promotions. Which is OK, but if you're going to do that, you need to be aware of the side effects. (I understand that Perl has similar syntatical quirks that will screw up the illiterati if they're not fully grokked.)

Boy, we've sure thought a lot about types without giving what the heck we're supposed to be doing a lick of thought.

I disagree. We have been spending a lot of time decising the kinds of operations we need to do on a BigAssClass, or a BigAssOrderedType. Your preceding paragraph specified what we want to be able to do. Now, given the tools available to do that, we start planning how to do it. If my tool set includes C++ , then I worry about how to manipulate the types to permit me to get where I want. If I have access to Python, or Objective C, then a whole different set of manipulations will have to occur. (If all I have is C# or Visual Basic, please put me out of my misery ASAP....) I will freely admit that the implementational issues that C++ presents are...unique...and and not always straightforward. But you will have a tough time convincing me that these other languages bandied about in this thread as panaceas to all the ills of programming ever foisted upon mankind are without their own set of problems, peculiarities, and pecadilloes.



jb4
"We continue to live in a world where all our know-how is locked into binary files in an unknown format. If our documents are our corporate memory, Microsoft still has us all condemned to Alzheimer's."
Simon Phipps, SUN Microsystems
New Re: My code does crash, but not as often as you think.
But you will have a tough time convincing me that these other languages bandied about in this thread as panaceas to all the ills of programming ever foisted upon mankind are without their own set of problems, peculiarities, and pecadilloes.

Answer #1: especially if you never try them out.
Answer #2: I don't think anyone is trying to convince you of that. What we are trying to convince you of is the fact that C++ has serious problems, much more so than other languages.

Still waiting for you to respond to the two large posts that Todd and I put together for you, BTW.
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New Replies coming
Posts read, and comments pending. Hard to find a suitable time to respond in full under current workload (esp considering my typing skilz...;-) )
jb4
"We continue to live in a world where all our know-how is locked into binary files in an unknown format. If our documents are our corporate memory, Microsoft still has us all condemned to Alzheimer's."
Simon Phipps, SUN Microsystems
New Re: My code does crash, but not as often as you think.

We have been spending a lot of time decising the kinds of operations we need to do on a BigAssClass, or a BigAssOrderedType. Your preceding paragraph specified what we want to be able to do. Now, given the tools available to do that, we start planning how to do it.


Well, unfortunately, when you define that max function in terms of T, you know have to keep in the back of your mind the potential effects of calling max(SomethingYouDidntReallyThinkThatHardAbout,SomethingElseYouDidntReallyThinkThatHardAbout);

IOW, that template mechanism paints with an infinitely broad brush and you now have to understand its exact expansion, along with expansions of any possible specializations you have (or your team mate wrote and didn't tell you about), and any automatic type conversion operators you've written along with any single argument constructurs you have.

To illustrate this, allow me to tell you about a short little gig I had as a porting engineer. During a development cycle when everybody was working on windows (except me, 'cause I just don't do windows), I would check out the code every morning and spend hours trying to build it - fixing portability issues and sending out hate mail to the team about some of their stupid assumptions.

One day I hit a compile error on something like:

CustomString str = "foo";
... return foo + "bar";

I looked up the developer and showed him the header for CustomString (this is before stl compiled anywhere other than Borland btw) and pointed out that there was no operator+ implemented on CustomString. He seemed perplexed because it worked fine on Windows. And so it did. As CustomString had an operator const char* defined, the MSString object had a ctor for const char*, an operator+, and an operator const char*. As we traced the execution we found that the compiler on windows had figured out it could construct a temp MSString (whatever they call it, I forget), do the operator+, then construct CustomString temp off the MSString's operator const char*.

Something like that - but the type conversions/automatic operator calls were several layers deep and of course there is no MSString for unix.

This lead me to conclude that the C++ type system is too complex for any human to predict what will happen for a given bit of code, and the introduction of a single function linking a couple types together and have far reaching unintended consequences on the system's overall behavior.

Thus, I boldly make the statement "C++ doesn't scale".



"Packed like lemmings into shiny metal boxes.
Contestants in a suicidal race."
    - Synchronicity II - The Police
Expand Edited by tuberculosis Aug. 21, 2007, 06:39:07 AM EDT
New Finally, something other than hand-waving.
[Your comments taken slightly out of order for the sake of the cheeeldrun]

And nothing keeps me from doing that...well, except your vaunted "unit testing"
And your vaunted discipline and design. ;-)

Unit testing of the entire code base found a grand total of 2 legitimate defects [...] Further, it's not clear that unit testing would detect the mistake that I describe above, either, unless the tests were specifically designed to trap such mismatches.
Sounds like pretty pathetic unit testing. Errors of the sort caused by improper type in a collection are extremely easy to catch in a proper unit test. (at pennies on the dollar, since you should be covering every line of code in a unit test anyway).

OK, except that storing the "wrong" thing in such a container wouldn't be identifiable until you pulled the item from the container, and tried to use it inappropriately.
Exactly. Which is what the unit test will exercise.

Since it is known to be inpossible to unit test all permutations of inputs in certain environments, one must then up the ante to try to trap these things at the integration level (you do use integration testing, don't you?). As trapping such defects at the integration level is generally understood to cost an order of magnitude more than catching the same defect at the unit testing level (which in turn, is generally recognized to cost an order of magnitude more than catching the same defect and the implementation level), catching this sort of bug in the way you describe can become rather expensive.
Except that the chance of such an egregious error making it past the code/compile/test cycle is so vanishingly small. And by the way, yes, I do integration testing. And blackbox testing. And whitebox testing. And code reviews. And regression suites. And acceptance testing. And design testing. Do we have that covered now? Point being, type misuse errors simply have a very small TTL.

And, as good as you are, Scott, it's one that you are probably equally likely to make.
Actually, no, I have not ever had this kind of error make it past the immediate code/compile/test cycle. And even then it's vanishingly rare. It Simply Isn't An Issue. I see a lot of you saying, "this might be an issue! beware the type misuse bugbears, they gonna getcha!". Which is direct contradiction to my own experience. At the same time, you've done very little non-strict typed programming (if I understand you correctly) but you're fully prepared to believe that your compiler is protecting you from teeming hordes of typing mistakes. Yes, your compiler prevents them right during the compile. I'm telling you that if the compiler doesn't catch them, they get caught right afterwards anyway. Negligible waste of time. And the benefits of a more flexible design without compiler complexity are enormous. Which brings up:

Look, Scott, in your paradigm I can store in one of your untyped collections an integer right next to a Locomotive object...when what I really wanted was a collection of Strings.
And the fact that you're typing 'branchCodes.put(new Locomotive("Burlington Zephyr"))' or 'pathNames.add(new Integer(42))' doesn't register at that point? Then you have issues other than type misuse... These glaring problems you're attempting to fabricate are easily handles with naming conventions, unit tests, and a little bit of experience and common sense.

In the mean time, my "training wheels" as you so snidely refer to them (Pot. Kettle. Black.), would catch this error at the implementation level (by not letting me even compile the error), at pennies on the dollar.
And in the meantime, you're wasting an order of magnitude greater time dealing with the unnecessary bookkeeping that strict typing requires. Because what you do, as a strict-typing expert, is spend all your time thinking through declarations and naming conventions and everything else you do to make sure you don't even have to waste time letting the compiler catch it. Which is exactly the same thing I do, except I don't have to worry about the wasting time part, and I don't have to worry about the bookkeeping either, or the extra finger presses needed to get my template declaration exactly right (so I don't have to waste time tracking down errors in generated template code three levels deep).

Now, to show you that I'm not just waving my hands or making suppositions (like you are), I'll tell you exactly where non-strict typing does cause problems, because you're barking up the wrong tree. The only place it causes issues is in method parameter order. If you bobble that, there's nothing that immediately tells you that you passed the quantity first and the branch code second, when they should be the other way around. However, three things: 1) you almost always immediately catch this, because something that's expecting an int gets "ABC", 2) you have exactly the same problem with strict-typed methods that have signatures like getFirmDesk(String branch, String correspondent), and 3) these issues go away completely if you use named parameters like Python has: getFirmDesk(branch = "ABC", quantity = 42).

(Pot. Kettle. Black.)
Hey, you started it. *cough*bullshitcommentsaboutvisualbasicusers*cough* I responded in kind.

...

Now at this point, we're going to have to decide if this is an argument about strict-typing vs. non-strict typing, or an argument about template collections vs. inherited base class systems. Because they aren't the same argument, by far.

Here's why: in Java, which IS a strict-typed language, the collections take the base class (Object) as input. So even if you do screw up and put a Car in when you expected an Integer, at the point you take it out to use it, or try to pass it in to the method that adds it, you will get a ClassCastException if it isn't what you expect it to be. So the only time you could ever make this sort of mistake is if you do it all within the confines of a single method. Doing so is either vanishingly unlikely, or the signs of a method that is way too large. So (at least in an otherwise strictly typed language), there's pretty much no chance of type misuse with a base-class collection system. This leaves the argument about strict-typing vs. non-strict typing (which isn't the same as dynamic typing [like ObjC, or Python, or Smalltalk] or non-typing [like Visual BASIC, or Javascript, or Perl], but that's another discussion by far ;-).

Nonetheless, given human frailty, errors do happen. For my part, I'd prefer to find my error sooner rather than later. Wouldn't you?
First an answer, then an important point which this question raises.

The answer: yes, I do. And unit testing and my own coding discipline have always found these errors very early in the process (if they weren't designed out in the first place with a design that insured asinine type mixups wouldn't happen). I have never had a type misuse error make it past the current code/compile/test cycle, let alone into the source code control system. In fact, my formal unit tests are a part of my code/compile/test cycle, and as a result I code even more quickly.

And now the very interesting point: IIRC, earlier (last time we had the "c++ sux0rs" flame war) you mentioned that all the complexity of C++ isn't an issue for you because you are an expert in it, and know how to use it properly. This is an argument for "C++ is fine, when it's just me". Now, I'm making the same argument in reverse: strict-typing and language complexity are unnecessary for me, because I'm an expert. Which is an argument for "non-strict typing is fine, when it's just me".

Why is this important? Because the middle-ground is where all this meets in large projects. There will be people like you who know C++ up and down. Templating errors, wedging designs into byzantine type structures, const craziness, buggy compilers, convoluted syntax, etc. -- none of these hold you up; you're a C++ expert. However, there will be a large number of people on that large project with you for whom these ARE issues. On the other end of the spectrum on a different large project, there will be people like me who find strict-typing more of a hindrance than a help. Collection misuse, adding strings to integers, catching type errors late in the process, etc. -- none of these hold me up; I'm an expert in avoiding these issues. However, there will be a large number of people on that large project with me for whom these ARE issues.

Where's the middle ground? Java. The collections are soft-typed and there's a single base class, so there's isn't all this mucking about with uber-complex template schemes requiring oodles of design. At the same time, there's type checking at method and casting boundaries, so there won't be any gratuitous type misuse errors created by inexperienced programmers. I submit that this combination is exactly why Java is so ubiquitous today, despite its relative youth. This combination is also guaranteed to drive experts like you and I and Todd nuts, because it is a compromise. However, practicality dictates that for large projects, this compromise is a necessary evil. A combination of training wheels and helmets, if you don't mind the analogy... :-)

Now, a suggestion: find a medium sized home project. Write it using something like Python (or Objective C). Then write it in Java. Then in C++. Savor the difference. Because until you've done this, you really don't know what you're talking about. And I further submit that you will find very few people who have done such a comparison who will stick to a belief that C++ is anything other than a mess. And one of them is probably named Stroustrup. ;-) You should notice that the people arguing against you here have done exactly this: Todd knows Smalltalk, ObjC, Java, and C++ intimately (and probably more languages beyond that). Myself, I've done major things with Python, Perl (probably my weakest, but I'm still considered one of the experts here at work), Java, C++ (ported 500K lines to Linux), and Objective C (a complete HTML parsing system in it - like the one that runs here on zIWT - enough to be confident that my command of the language is fairly complete).
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
Expand Edited by admin May 2, 2003, 07:51:43 PM EDT
New Hey I know Java
enough to hate it in the special way only an intimate can. ;-)

Good post.



The thing that I really hate about Smalltalk ,though, is the fact that every time I wish C++ or Java did something differently it turns out that Smalltalk does it the way I want it to. I've never even used Smalltalk on a real project. I just learned it so that I could read source code, now I keep running into things that would be easier if I were using it. It's really annoying.--Phil Goodwin

Expand Edited by tuberculosis Aug. 21, 2007, 06:25:18 AM EDT
New Whoops, forgot that one.
I wondered what that sloppy feeling was I get from using Java... ;-)
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New I always sit on a towel when using it
helps minimize the accidents when reading the api specs.



Java's primary roots are out of the C++ world. From that standpoint, Java is a big step up. It's a cleaner, object-oriented language. And the benefits of a Virtual Machine on every platform are obvious.

But I came to Java from a different world of programming, the Smalltalk world. For people who program in Smalltalk, Java is a 30-year step back. Smalltalk is what made object-oriented programming real. It had a mature class library and culture from the day it was released, whereas the C++ world just kind of happened. Its class library still isn\ufffdt stable. The result for me is that Java is an absolute requirement in today\ufffds software world, but sometimes it hurts me to use it.

--Steven T. Abell, formerly Java Technology evangelist at Netscape
Expand Edited by tuberculosis Aug. 21, 2007, 06:25:43 AM EDT
New Interesting... I find I get more use out of...
... an air sickness bag.
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New I've done it
(medium-sized project, that is)

It turned out to be a small-sized project in Smalltalk. Including unit tests and refactoring :)

I still do not think C++ is "anything but a mess". It's usable. Smalltalk (and Python, and TCL to a lesser degree) are joy to code in. But I still don't trust them for critical loop stuff. And that's where I spend a lot of time, myself. From that point on, it's a matter of investing into some coupling, or continuing with C++ all the way up.

(Side note on unit tests: I realized that in Smalltalk, unit tests cover a lot of stuf that compiler checks in C. So, in C I write unit tests to verify control logic, and in Smalltalk I write them for every line of code indeed.)

--

Want to be original? Start with a great template!
New Re: I've done it
"Usable" vs. "a joy to code in" == a mess, IMO. ;-)
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New How?
By using an efficient memory model for storing objects and then making everything an object with a minimal useful protocol. (there's a lot of fat in the C++ memory model in places - using 32 bits to store a boolean for instance and lots of stuff are padded up for the convenience of the memory bus - makes for very wasteful space usage).













C++ type sizes in bytes
bool:4
char:1
short:2
int:4
long:4
long long:8
float:4
double:8
void*:4
EmptyClass:1
EmptyVirtualClass:4


So a boolean is mostly wasted space! Minimum "Object" size is 4 bytes (pointer for to vtable). The empty class has no virtual method so its the size of the sum of its elements with a lower bound of 1 byte. Certainly most C++ has lots of unused memory space in little fragments all over the place.

Smalltalk OTOH uses "a variable-length header format which seldom requires more than a single 32-bit word of header information per object. The format is given in Tables 1 and 2.
Table 1: Format of a Squeak object header offset contents occurrence
-8 size in words (30 bits), header type (2 bits) 1%
-4 full class pointer (30 bits), header type (2 bits) 18%
0 base header, as follows...
storage management (3 bits)
object hash (12 bits)
compact class index (5 bits)
object format field (4 bits, see below)
size in words (6 bits)
header type (2 bits) 100%


Table 2: Encoding of the object format field in a Squeak object header 0 no fields
1 fixed pointer fields
2 indexable pointer fields
3 both fixed and indexable pointer fields
4 unused
5 unused
6 indexable word fields (no pointers)
7 unused
8-11 indexable byte fields (no pointers):
low 2 bits are low 2 bits of size in bytes
12-15 compiled methods: low 2 bits are low 2 bits of size in bytes.
The number of literals is specified in method header, followed by the indexable bytes that store byte codes.

Our design is based on the fact that most objects in a typical Smalltalk image are small instances of a relatively small number of classes. The 5-bit compact class index field, if non-zero, is an index into a table of up to 31 classes that are designated as having compact instances; the programmer can change which classes these are. The 6-bit size field, if non-zero, specifies the size of the object in words, accommodating sizes up to 256 bytes (i.e., 64 words, with the additional 2 bits needed to resolve the length of byte-indexable objects encoded in the format field). With only 12 classes designated as compact in the 1.18 Squeak release, around 81% of the objects have only this single word of overhead. Most of the rest need one additional word to store a full class pointer. Only a few remaining objects (1%) are large enough to require a third header word to encode their size, and this extra word of overhead is a tiny fraction of their size. "

From here: [link|ftp://st.cs.uiuc.edu/Smalltalk/Squeak/docs/OOPSLA.Squeak.html|ftp://st.cs.uiuc.edu...OPSLA.Squeak.html]

So which language is more type safe at runtime? The one where you can tell what the bits mean that you are looking at or the one that struggles to prevent the creation of instructions that misinterpret the bits and thus makes assumptions with every memory access?

C++ is a naive hack that got way out of hand.

Edit - fixed html table



It has been discovered that C++ provides a remarkable facility for concealing the trival details of a program -- such as where its bugs are. (David Keppel)
Expand Edited by tuberculosis May 2, 2003, 03:28:52 PM EDT
Expand Edited by tuberculosis May 2, 2003, 07:01:38 PM EDT
Expand Edited by tuberculosis Aug. 21, 2007, 06:23:01 AM EDT
New Erm?
C++ type sizes in bytes
bool: 4 [...]

What compiler are you using?!?

There isn't a C++ compiler That I'm aware of (Visual C++ 4.2 notwithstanding) that uses more than a byte to hold a bool (and that includes g++ 2.9x.x)
jb4
"We continue to live in a world where all our know-how is locked into binary files in an unknown format. If our documents are our corporate memory, Microsoft still has us all condemned to Alzheimer's."
Simon Phipps, SUN Microsystems
New GNU CPP version 2.95.2 19991024 (release)



"Packed like lemmings into shiny metal boxes.
Contestants in a suicidal race."
    - Synchronicity II - The Police
Expand Edited by tuberculosis Aug. 21, 2007, 06:38:43 AM EDT
New Sorry to hear that...:-(
Interesting...the 2.95.2 version I was using with QNX used a single byte to represent a bool.
jb4
"We continue to live in a world where all our know-how is locked into binary files in an unknown format. If our documents are our corporate memory, Microsoft still has us all condemned to Alzheimer's."
Simon Phipps, SUN Microsystems
New Well said, exactly correct
-drl
     C++ File I/O: Windows vs. Linux - (tjsinclair) - (85)
         Wild guess - (JayMehaffey) - (1)
             Nope - (tjsinclair)
         Permissions problem? - (tuberculosis) - (16)
             Possibly - (tjsinclair) - (15)
                 The only dumb question is... - (jbrabeck) - (14)
                     Thanks - (tjsinclair) - (13)
                         I'd second the permissions... - (jbrabeck) - (12)
                             Played with error bits - (tjsinclair) - (11)
                                 C++ for real work - (tuberculosis) - (10)
                                     telco's use lots of c++ -NT - (boxley) - (7)
                                         on UNIX? - (tjsinclair) - (6)
                                             well several softswitches and other software (added link) - (boxley) - (2)
                                                 Yeah - OS level code I think - (tuberculosis) - (1)
                                                     Stacked based types? - (deSitter)
                                             some more info on c++ Unix and Telcos and jobs - (boxley) - (2)
                                                 CORBA == Objects, so makes sense - (tjsinclair)
                                                 Resume mailed -NT - (tuberculosis)
                                     Someone somewhere must be using it - (tjsinclair)
                                     Network Management software - (Arkadiy)
         I don't know C++ but... - (ben_tilly) - (6)
             Seems like it ought to raise an exception on failure -NT - (tuberculosis) - (5)
                 It does - (tjsinclair) - (4)
                     Erroring out? - (tuberculosis) - (3)
                         I checked the ios error flags - (tjsinclair) - (2)
                             Thats not raising an exception - (tuberculosis) - (1)
                                 Agreed - (tjsinclair)
         Got it! - (tjsinclair) - (58)
             Now, this is really scary - (Arkadiy) - (53)
                 Even scarier - (tjsinclair) - (52)
                     At this point, one wants to,, - (deSitter) - (3)
                         Ross, do we need a refresher... - (jb4) - (2)
                             I would completely agree with you except - (tjsinclair) - (1)
                                 Wow! - (jb4)
                     Which version of gcc? - (admin)
                     So, let me get this straight... - (Arkadiy) - (46)
                         Something like that, yes - (tjsinclair) - (44)
                             I've been trying to do that for years - (tuberculosis)
                             Barney is not responsible... - (jb4) - (42)
                                 Move farther up the food chain - (tuberculosis) - (41)
                                     OK, I'll bite... - (jb4) - (39)
                                         Errr... - (admin) - (34)
                                             I've heard strong typing called several different things... - (jb4) - (33)
                                                 Strict typing is like training wheels. - (admin) - (32)
                                                     Re: Strict typing is like training wheels. Or Helmuts? - (jb4) - (31)
                                                         You have much to learn - (tuberculosis) - (23)
                                                             Irony - (ben_tilly) - (22)
                                                                 Additionally... - (admin) - (21)
                                                                     That's the C++ propaganda - (tuberculosis) - (20)
                                                                         Wrong usage - (Arkadiy) - (7)
                                                                             Return value problem - (tuberculosis) - (6)
                                                                                 I'll take a look for the solution for ret value - (Arkadiy)
                                                                                 Re: Return value problem - (deSitter) - (4)
                                                                                     In the end - (Arkadiy) - (3)
                                                                                         A better statically typed language - have you tried Haskell? -NT - (ben_tilly) - (1)
                                                                                             Read the tutorials - (tuberculosis)
                                                                                         Today's link at /. - (Arkadiy)
                                                                         Interesting example, Todd - (jb4) - (11)
                                                                             Umm... - (Simon_Jester) - (5)
                                                                                 And what would you cast the void* back to afterwards? -NT - (tuberculosis) - (4)
                                                                                     Yeah, you'd have to test for the type... - (Simon_Jester) - (3)
                                                                                         Aaaaaahhhhhhh! - (tuberculosis) - (2)
                                                                                             *chuckle* - (Simon_Jester) - (1)
                                                                                                 Oh, you illustrated several problems - (tuberculosis)
                                                                             Your code should crash - (tuberculosis) - (4)
                                                                                 My code does crash, but not as often as you think. - (jb4) - (3)
                                                                                     Re: My code does crash, but not as often as you think. - (admin) - (1)
                                                                                         Replies coming - (jb4)
                                                                                     Re: My code does crash, but not as often as you think. - (tuberculosis)
                                                         Finally, something other than hand-waving. - (admin) - (6)
                                                             Hey I know Java - (tuberculosis) - (3)
                                                                 Whoops, forgot that one. - (admin) - (2)
                                                                     I always sit on a towel when using it - (tuberculosis) - (1)
                                                                         Interesting... I find I get more use out of... - (admin)
                                                             I've done it - (Arkadiy) - (1)
                                                                 Re: I've done it - (admin)
                                         How? - (tuberculosis) - (3)
                                             Erm? - (jb4) - (2)
                                                 GNU CPP version 2.95.2 19991024 (release) -NT - (tuberculosis) - (1)
                                                     Sorry to hear that...:-( - (jb4)
                                     Well said, exactly correct -NT - (deSitter)
                         This is frigging runtime lib bug, not language - (Arkadiy)
             You were mis-using the flags... - (Simon_Jester) - (3)
                 I thought of that - (tjsinclair) - (2)
                     For what it's worth, code also runs... - (a6l6e6x) - (1)
                         Figured that -NT - (tjsinclair)

He's so far to the right of the bell curve he could drop a marble and it wouldn't roll away.
433 ms