By: JasonB (no.delete@this.spam.com), March 10, 2008 1:12 am
Room: Moderated Discussions
Foo_ (foo@nomail.com) on 3/9/08 wrote:
---------------------------
>It's not just syntax, it's semantics. Compare the lame std::string type with Python's
>str and unicode types, for example.
OK, what are the differences?
>Compare the garbage collector with the burden
>of managing memory by hand.
In the RBTree example I linked to, the entire memory management burden equates to:
... and that's if you decide to manage memory by hand rather than using smart pointers.
>Compare the standard library.
Am I allowed to include Boost?
>Compare the fact that
>everything is an object (including functions, methods...) with C++'s typing mess. etc.
The fact that not everything has to be an object is an important part of C++'s support for multiple programming paradigms. OO isn't always the simplest way to represent something.
>Unless you only program Mandelbrot-calculation loops it is quite clear how Python is more concise than C++.
I was hoping for something a little more concrete than being asked to compare a bunch of things and told the answer was "quite clear".
>For a start, C++'s crippled standard library should be a big warning against using
>that language for general-purpose tasks, unless you are masochistic.
I actually quite like C++'s standard library and the underlying concepts. I also use Boost and many other libraries, as any serious programmer would.
>>I look at examples like http://www.dmh2000.com/cjpr/cmpframe.html
>
>Sorry that's a stupid example. You don't write red-black trees in pure Python,
>it is not "idiomatic" by any meaning of the word. And the example itself is a straight
>translation from a textbook algorithm, no wonder line counts end up quite similar.
That's not the point. I wouldn't bother writing a red-black tree anyway. The point is to express a set of concepts in a language to see how they turn out.
To illustrate what I was talking about, however, this is the code that the author gave to implement the Visitor design pattern on his tree:
Over 30 lines and it doesn't even work with plan functions!
This was his Python effort:
15 lines of code and it supports both classes that implement the "visit" method and functions.
But this is how I would do it in C++, especially since it's a template class anyway:
This replaces all of the C++ code I quoted above, and supports both plain functions and functor classes; duplicate for classes that have a Visit method if you like. It is line-for-line identical to the Python version except:
1. The "template" line.
2. It will give a compile-time error if you try to use it with a function or object that does not have the required signature.
3. You don't have to keep typing "self" all the time. (It reminds me of when I used to program OO-style in C.)
>>Also, one of the things I like most about C++
>>is that doing nice stuff is concise;
>
>IMO only a Java or Pascal programmer can find C++ concise. There is no conciseness
>in the way you declare and use function types, method pointer types, etc., in C++.
It's a tradeoff. If I want to tell the compiler what type I think a variable should be so that it can give me a compile-time error if I'm wrong (it happens), then I have to tell it somehow, and saying what the type is when I declare and use it the first time isn't a huge burden. (It also means that VisualAssist (http://www.wholetomato.com/) knows what methods to show me when I start typing something and it wants to auto-complete them for me.)
In the next version of C++ the "auto" keyword is going to be redefined to allow the class to remain unspecified, i.e.
auto Blah = ...;
The concrete type will still be known and enforced at compile time, but you don't have to state it if you don't care.
This can be useful in some cases, but I will generally continue to state the type for the same reason I use assert() in my code -- the more information I give the compiler about what I think is going on, the more likely it is going to be able to tell me if I'm wrong.
>>Perhaps some concrete examples would be nice to highlight what I've overlooked.
>
>You can find some concrete examples here:
>http://shootout.alioth.debian.org/
>
>Since those examples are very short and calculatory programs, they don't really
>highlight what the high-level semantics of Python or Ruby can bring in terms of conciseness.
They also seem to want to write everything as low-level as possible. Take this for example:
This is the simple Python version:
But why not simply write it like this in C++?
Or, to emulate the "print sum(itertools.imap(int, sys.stdin))" version:
That's 10 lines of C++ code in their main function vs 1 line in mine.
These are just silly toy examples, but every one I look at is like this, and I haven't even used anything outside of the current STL, let alone TR1 or Boost or any of the other libraries I normally use.
>>>C++ is good for some applications, python is good for some applications.
>>
>>As I said right at the beginning. A classic Pentium is fine for plenty of applications as well.
>
>Your classic Pentium does not have abstraction, maintainability and robustness
>advantages over a Core 2 Duo, while Python has over C++.
Well, I disagree that Python has abstraction, maintainability, or robustness advantages over C++. Abstraction-wise they seem pretty much the same as far as I can tell, and I think static typing is a win for maintainability and robustness simply because you are far more likely to detect a mistake at compile time rather than hoping you have the right test cases to catch it at run time rather than your customer.
---------------------------
>It's not just syntax, it's semantics. Compare the lame std::string type with Python's
>str and unicode types, for example.
OK, what are the differences?
>Compare the garbage collector with the burden
>of managing memory by hand.
In the RBTree example I linked to, the entire memory management burden equates to:
void copy(RedBlackTree *x)
{
...
// Delete x
x->m_left = NULL;
x->m_right = NULL;
delete x;
}
~RedBlackTree() {
delete m_left;
delete m_right;
}
... and that's if you decide to manage memory by hand rather than using smart pointers.
>Compare the standard library.
Am I allowed to include Boost?
>Compare the fact that
>everything is an object (including functions, methods...) with C++'s typing mess. etc.
The fact that not everything has to be an object is an important part of C++'s support for multiple programming paradigms. OO isn't always the simplest way to represent something.
>Unless you only program Mandelbrot-calculation loops it is quite clear how Python is more concise than C++.
I was hoping for something a little more concrete than being asked to compare a bunch of things and told the answer was "quite clear".
>For a start, C++'s crippled standard library should be a big warning against using
>that language for general-purpose tasks, unless you are masochistic.
I actually quite like C++'s standard library and the underlying concepts. I also use Boost and many other libraries, as any serious programmer would.
>>I look at examples like http://www.dmh2000.com/cjpr/cmpframe.html
>
>Sorry that's a stupid example. You don't write red-black trees in pure Python,
>it is not "idiomatic" by any meaning of the word. And the example itself is a straight
>translation from a textbook algorithm, no wonder line counts end up quite similar.
That's not the point. I wouldn't bother writing a red-black tree anyway. The point is to express a set of concepts in a language to see how they turn out.
To illustrate what I was talking about, however, this is the code that the author gave to implement the Visitor design pattern on his tree:
// ===============================================================
// C++ NEEDS SOME DECLARATIONS BEFORE THE MAIN RedBlackTree class.
// skip down a little to line this up with the other side
// ===============================================================
// requires forward declaration to resolve cycle between NodeVisitor and RedBlackTree
template<class T> class RedBlackTree;
// use an abstract class for the node visitor. it is templatized to match the templated RedBlackTree declaration
template<class T> class NodeVisitor {
public:
// need a virtual destructor for the concrete classes
virtual ~NodeVisitor() {}
// ise a pure virtual function so a concrete class must implement
// the proper signature
virtual void visit(const RedBlackTree<T> *node,int depth) = 0;
};
...
// 'const' means this method doesn't change the object state
// and the visitor is not allowed to change the object state.
// that may not be what is desired but is used here to
// illustrate something you can do in C++ that you can't do
// in the other languages and that illustrates the bias towards
// extensive static type checking
void inorder(NodeVisitor<T> *visitor,int depth) const {
if (m_left != 0) {
m_left->inorder(visitor,depth+1);
}
visitor->visit(this,depth);
if (m_right != 0) {
m_right->inorder(visitor,depth+1);
}
}
Over 30 lines and it doesn't even work with plan functions!
This was his Python effort:
# inorder traversal using a class as the visitor
def inorderClass(self,visitor,depth):
if self.__left != None:
self.__left.inorderClass(visitor,depth+1)
visitor.visit(self,depth)
if self.__right != None:
self.__right.inorderClass(visitor,depth+1)
# inorder traversal using a function as the visitor
def inorderFunction(self,visit,depth):
if self.__left != None:
self.__left.inorderFunction(visit,depth+1)
visit(self,depth)
if self.__right != None:
self.__right.inorderFunction(visit,depth+1)
15 lines of code and it supports both classes that implement the "visit" method and functions.
But this is how I would do it in C++, especially since it's a template class anyway:
// inorder traversal using either a class or a function as the visitor
template <class Visitor>
void inorder(Visitor& visitor, int depth) const {
if (m_left != NULL)
m_left->inorder(visitor, depth + 1);
visitor(*this, depth);
if (m_right != NULL)
m_right->inorder(visitor, depth + 1);
}
This replaces all of the C++ code I quoted above, and supports both plain functions and functor classes; duplicate for classes that have a Visit method if you like. It is line-for-line identical to the Python version except:
1. The "template" line.
2. It will give a compile-time error if you try to use it with a function or object that does not have the required signature.
3. You don't have to keep typing "self" all the time. (It reminds me of when I used to program OO-style in C.)
>>Also, one of the things I like most about C++
>>is that doing nice stuff is concise;
>
>IMO only a Java or Pascal programmer can find C++ concise. There is no conciseness
>in the way you declare and use function types, method pointer types, etc., in C++.
It's a tradeoff. If I want to tell the compiler what type I think a variable should be so that it can give me a compile-time error if I'm wrong (it happens), then I have to tell it somehow, and saying what the type is when I declare and use it the first time isn't a huge burden. (It also means that VisualAssist (http://www.wholetomato.com/) knows what methods to show me when I start typing something and it wants to auto-complete them for me.)
In the next version of C++ the "auto" keyword is going to be redefined to allow the class to remain unspecified, i.e.
auto Blah = ...;
The concrete type will still be known and enforced at compile time, but you don't have to state it if you don't care.
This can be useful in some cases, but I will generally continue to state the type for the same reason I use assert() in my code -- the more information I give the compiler about what I think is going on, the more likely it is going to be able to tell me if I'm wrong.
>>Perhaps some concrete examples would be nice to highlight what I've overlooked.
>
>You can find some concrete examples here:
>http://shootout.alioth.debian.org/
>
>Since those examples are very short and calculatory programs, they don't really
>highlight what the high-level semantics of Python or Ruby can bring in terms of conciseness.
They also seem to want to write everything as low-level as possible. Take this for example:
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
#define MAXLINELEN 128
int main(int argc, char * * argv) {
ios_base::sync_with_stdio(false);
char line[MAXLINELEN];
int sum = 0;
char buff[4096];
cin.rdbuf()->pubsetbuf(buff, 4096); // enable buffering
while (cin.getline(line, MAXLINELEN)) {
sum += atoi(line);
}
cout << sum << 'n';
}
This is the simple Python version:
import sys
def main():
count = 0
for line in sys.stdin.xreadlines():
count += int(line)
print count
But why not simply write it like this in C++?
#include <iostream>
using namespace std;
int main()
{
int i, count = 0;
while (cin >> i)
count += i;
cout << count;
}
Or, to emulate the "print sum(itertools.imap(int, sys.stdin))" version:
#include <iostream>
#include <numeric>
using namespace std;
int main()
{
cout << accumulate(istream_iterator<int>(cin), istream_iterator<int>(), 0);
}
That's 10 lines of C++ code in their main function vs 1 line in mine.
These are just silly toy examples, but every one I look at is like this, and I haven't even used anything outside of the current STL, let alone TR1 or Boost or any of the other libraries I normally use.
>>>C++ is good for some applications, python is good for some applications.
>>
>>As I said right at the beginning. A classic Pentium is fine for plenty of applications as well.
>
>Your classic Pentium does not have abstraction, maintainability and robustness
>advantages over a Core 2 Duo, while Python has over C++.
Well, I disagree that Python has abstraction, maintainability, or robustness advantages over C++. Abstraction-wise they seem pretty much the same as far as I can tell, and I think static typing is a win for maintainability and robustness simply because you are far more likely to detect a mistake at compile time rather than hoping you have the right test cases to catch it at run time rather than your customer.
Topic | Posted By | Date |
---|---|---|
Multicore is unlikely to be the ideal answer. | Anders Jensen | 2008/02/14 04:24 AM |
And the links.. | Anders Jensen | 2008/02/14 04:25 AM |
Disappointing.. | Linus Torvalds | 2008/02/14 10:17 AM |
Disappointing.. | Mark Roulo | 2008/02/14 11:03 AM |
LOL (NT) | Linus Torvalds | 2008/02/14 05:43 PM |
Disappointing.. | David Patterson | 2008/02/15 11:53 AM |
Disappointing.. | Linus Torvalds | 2008/02/15 05:01 PM |
Disappointing.. | anon | 2008/02/15 08:54 PM |
Disappointing.. | JasonB | 2008/02/19 07:45 PM |
Disappointing.. | Ilya Lipovsky | 2008/02/22 06:27 PM |
Disappointing.. | Scott Bolt | 2008/03/16 11:36 AM |
Need for new programming languages | Vincent Diepeveen | 2008/02/19 06:18 AM |
Need for new programming languages | Pete Wilson | 2008/02/24 11:41 AM |
Disappointing.. | Zan | 2008/02/25 10:52 PM |
Disappointing.. | Robert Myers | 2008/02/19 09:47 PM |
Disappointing.. | Fred Bosick | 2008/02/22 06:38 PM |
Disappointing.. | Robert Myers | 2008/03/01 01:17 PM |
The limits of single CPU speed are here. | John Nagle | 2008/03/14 10:55 AM |
The limits of single CPU speed are here. | Howard Chu | 2008/03/15 01:02 AM |
The limits of single CPU speed are here. | slacker | 2008/03/15 08:08 AM |
The limits of single CPU speed are here. | Howard Chu | 2008/03/17 01:47 AM |
The limits of single CPU speed are here. | slacker | 2008/03/17 10:04 AM |
And the links.. | Howard Chu | 2008/02/14 12:58 PM |
I take some of that back | Howard Chu | 2008/02/14 01:55 PM |
And the links.. | Jesper Frimann | 2008/02/14 02:02 PM |
And the links.. | Ilya Lipovsky | 2008/02/15 02:24 PM |
And the links.. | iz | 2008/02/17 10:55 AM |
And the links.. | JasonB | 2008/02/17 07:09 PM |
And the links.. | Ilya Lipovsky | 2008/02/18 01:54 PM |
And the links.. | JasonB | 2008/02/18 10:34 PM |
And the links.. | Thiago Kurovski | 2008/02/19 07:01 PM |
And the links.. | iz | 2008/02/20 10:36 AM |
And the links.. | Ilya Lipovsky | 2008/02/20 03:37 PM |
And the links.. | JasonB | 2008/02/20 06:28 PM |
And the links.. | JasonB | 2008/02/17 06:47 PM |
And the links.. | Ilya Lipovsky | 2008/02/18 02:27 PM |
And the links.. | JasonB | 2008/02/18 10:00 PM |
And the links.. | JasonB | 2008/02/19 03:14 AM |
And the links.. | Ilya Lipovsky | 2008/02/20 04:29 PM |
And the links.. | JasonB | 2008/02/20 06:14 PM |
And the links.. | Ilya Lipovsky | 2008/02/21 11:07 AM |
And the links.. | Howard Chu | 2008/02/14 01:16 PM |
And the links.. | Jukka Larja | 2008/02/15 03:00 AM |
Berkeley View on Parallelism | David Kanter | 2008/02/15 11:41 AM |
Berkeley View on Parallelism | Howard Chu | 2008/02/15 12:49 PM |
Berkeley View on Parallelism | David Kanter | 2008/02/15 03:48 PM |
Berkeley View on Parallelism | Howard Chu | 2008/02/17 05:42 PM |
Berkeley View on Parallelism | nick | 2008/02/17 09:15 PM |
Berkeley View on Parallelism | Howard Chu | 2008/02/18 04:23 PM |
Berkeley View on Parallelism | nick | 2008/02/18 10:03 PM |
Berkeley View on Parallelism | Howard Chu | 2008/02/19 01:39 AM |
Berkeley View on Parallelism | rcf | 2008/02/19 12:44 PM |
Berkeley View on Parallelism | Howard Chu | 2008/02/19 03:25 PM |
Average programmers | anon | 2008/02/18 12:40 PM |
Berkeley View on Parallelism | JasonB | 2008/02/15 08:02 PM |
Berkeley View on Parallelism | JasonB | 2008/02/15 08:02 PM |
Berkeley View on Parallelism | Dean Kent | 2008/02/15 08:07 PM |
Berkeley View on Parallelism | Ray | 2008/02/20 03:20 PM |
Berkeley View on Parallelism | JasonB | 2008/02/20 06:11 PM |
Berkeley View on Parallelism | FritzR | 2008/02/24 03:08 PM |
rubyinline, etc. | nordsieck | 2008/02/22 03:38 PM |
rubyinline, etc. | JasonB | 2008/02/23 05:53 AM |
rubyinline, etc. | nordsieck | 2008/03/02 01:40 AM |
rubyinline, etc. | Michael S | 2008/03/02 02:49 AM |
rubyinline, etc. | Dean Kent | 2008/03/02 07:41 AM |
rubyinline, etc. | Michael S | 2008/03/02 08:19 AM |
rubyinline, etc. | Dean Kent | 2008/03/02 08:30 AM |
rubyinline, etc. | JasonB | 2008/03/02 05:26 PM |
rubyinline, etc. | JasonB | 2008/03/02 06:01 PM |
rubyinline, etc. | Anonymous | 2008/03/03 02:11 AM |
rubyinline, etc. | JasonB | 2008/03/03 09:40 AM |
rubyinline, etc. | Foo_ | 2008/03/09 09:59 AM |
rubyinline, etc. | JasonB | 2008/03/10 01:12 AM |
rubyinline, etc. | Gabriele Svelto | 2008/03/10 02:22 AM |
rubyinline, etc. | JasonB | 2008/03/10 04:35 AM |
C++ for beginners | Michael S | 2008/03/10 05:16 AM |
C++ for beginners | JasonB | 2008/03/10 06:35 AM |
C++ | Michael S | 2008/03/10 04:55 AM |
rubyinline, etc. | Linus Torvalds | 2008/03/03 11:35 AM |
rubyinline, etc. | Dean Kent | 2008/03/03 02:35 PM |
rubyinline, etc. | JasonB | 2008/03/03 03:57 PM |
rubyinline, etc. | Dean Kent | 2008/03/03 08:10 PM |
rubyinline, etc. | Michael S | 2008/03/04 01:53 AM |
rubyinline, etc. | Dean Kent | 2008/03/04 07:51 AM |
rubyinline, etc. | Michael S | 2008/03/04 08:29 AM |
rubyinline, etc. | Dean Kent | 2008/03/04 08:53 AM |
rubyinline, etc. | Michael S | 2008/03/04 11:20 AM |
rubyinline, etc. | Dean Kent | 2008/03/04 02:13 PM |
read it. thanks (NT) | Michael S | 2008/03/04 04:31 PM |
efficient HLL's | Patrik Hägglund | 2008/03/04 03:34 PM |
efficient HLL's | Wes Felter | 2008/03/04 09:33 PM |
efficient HLL's | Patrik Hägglund | 2008/03/05 01:23 AM |
efficient HLL's | Michael S | 2008/03/05 02:45 AM |
efficient HLL's | Wilco | 2008/03/05 05:34 PM |
efficient HLL's | Howard Chu | 2008/03/05 07:11 PM |
efficient HLL's | Wilco | 2008/03/06 02:27 PM |
efficient HLL's | anon | 2008/03/05 08:20 AM |
And the links.. | Groo | 2008/02/17 04:28 PM |
And the links.. | Vincent Diepeveen | 2008/02/18 02:33 AM |