> I don't know much about Ruby, but Python, unlike C and C++,
> has "tracebacks" when it encounters a problem, and throws exceptions
> that you can catch, rather than just segfaulting on you.
Ruby does. So do C/C++, although they are called "backtraces" there.
I've never used nonstandard C Structured Exception Handling (or the more
standard setjmp()/longjmp()) but C++ exceptions have not given me
trouble. Old versions of g++ had problems throwing exceptions across .so
boundaries however.
> Plus of course you can do high-level programming that eliminates a huge
> category of bugs (bounds-checking, memory management, side-effects,
> etc).
Yup. Ruby/Python add some categories of their own of course. This is
probably due to my C++ background but the fact that everything is like a
reference in Ruby (ie. a = b translated to Obj *a = b instead of being a
copy constructor) has tripped me up to no end. Freezing Ruby objects is
handy for tracking down that kind of bug however. I simply will never
get used to having to use self.foo in Python however, no matter how hard
I try. That alone has caused me so much grief.
I will point out that you will still get resource leaks using Ruby and
Python if you're not careful. They will simply not be memory leaks.
This is one area where C++ shines (C# managed to steal a good chunk as
well). I'm referring to the Resource Acquistion Is Initialization idiom
(http://en.wikipedia.org/wiki/RAII). Even among C++ programmers it's not
used often enough due to the need to define a class for more resources
you use first but if you use it consistently you can practically
eliminate resource leaks entirely. It's also useful with stuff like
mutexes/thread-locks, etc.
> And it's easy to read, so you catch logical bugs by inspection.
And the C++ compiler catches them with 10-page template errors messages.
ah well. :) Seriously though, this hasn't typically tripped me up, and
the next revision to C++ should help with auto variables that infer their
type automatically. i.e.:
for(std::list<Foo>::const_iterator i = list.begin(); i != list.end();
++i) {...}
becomes
foo(auto i = list.begin(); i != list.end(); ++i) { ... }
i still has a static type and it's still checked, but you don't have to
type it all out.
> Programming in python takes me a tenth the time it would take in C, and
> it is always my choice when speed is not absolutely critical.
Who programs in C anymore? You'll notice I never mentioned it. People
like to ding on C++ as just C with objects but that's simply not true. I
especially like how Java 1.5 has finally almost caught up to the syntax
mess of C++.
Python is a great language though, although I only use it over Ruby
when... speed is an issue but not so much to where I turn to C++. I
still do one-off scripts in Perl just out of habit. But anytime I've
tried to make a large program in Python I've typically been able to get
the prototype working in Python first but the extra debugging time makes
the coding time difference not as drastic.
> (And when speed is important but not totally critical, I have used
> ocaml and am seriously looking at haskell now.)
I've looked at them both (and Erlang, and Common Lisp, and Scheme/guile,
and etc.) but functional languages to be honest still completely kick my
ass. I understand and like things like lambda functions and closures,
and I think I mostly understand the concept, but it doesn't translate to
a program design so I just sit there at the editor feeling dumb. :)