By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,600 Members | 1,683 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,600 IT Pros & Developers. It's quick & easy.

Python vs C for a mail server

P: n/a
Hello guys,
I am a novice in python.I have to implement a full fledged mail server
..But i am not able to choose the language.Should i go for C(socket API)
or python for this project? What are the advantages of one over the
other in implementing this server.which language will be easier? What
are the performance issues?In what language are mail servers generally
written?

Jan 28 '06 #1
Share this Question
Share on Google+
25 Replies


P: n/a
On Fri, 27 Jan 2006 22:43:48 -0800, abhinav wrote:
Hello guys,
I am a novice in python.I have to implement a full fledged mail server
Because that's just what the world needs, yet another mail server.

Why don't you use an existing mail server?
.But i am not able to choose the language.Should i go for C(socket API)
or python for this project?
If you aren't able to choose the language, what does it matter what we
say? Somebody else will choose.

What are the advantages of one over the
other in implementing this server.
C can be faster.
which language will be easier?
Python is easier to read, and write, and debug, and you will have fewer
hard-to-debug memory issues.
What are the performance issues?
You will spend hundreds of man-hours re-inventing the wheel.

In what language are mail servers generally written?


Google is your friend. The first four mail servers listed are, in order:

sendmail
postfix
Microsoft Exchange
qmail

Of the four, source code is available free of charge for three of them.
Can you guess which is the odd man out? :-)
--
Steven.

Jan 28 '06 #2

P: n/a
>> Why don't you use an existing mail server?

Probably because that was his homework assignment for a networking
class. Not uncommon to be told to implement a server from the scratch
from the RFC. Although that does not explain his concern about
performance.

Abhinav, if that is the case, using sockets is more or less the same
from any language. Python as usual will be cleaner than C. You might
want to look at Twisted Mail. Use SocketServer module in the standard
library to implement the RFC. Other than that it is silly to try to
write a Mail Server unless you have some extra ordinary need.

Jan 28 '06 #3

P: n/a
>but i am not able to choose the language.Should i go for C(socket API)

Ravi is right
(>using sockets is more or less the same
from any language.)

...try JSP(java server pages), some guys in nit warangal implemented a
mail server
(foa LAN though)for their minor project.

my contention is that using sockets(in c++) will improve your
understanding of the protocol
suite and improve your programming as well.


Ravi Teja wrote:
Why don't you use an existing mail server?


Probably because that was his homework assignment for a networking
class. Not uncommon to be told to implement a server from the scratch
from the RFC. Although that does not explain his concern about
performance.

Abhinav, if that is the case, using sockets is more or less the same
from any language. Python as usual will be cleaner than C. You might
want to look at Twisted Mail. Use SocketServer module in the standard
library to implement the RFC. Other than that it is silly to try to
write a Mail Server unless you have some extra ordinary need.


Jan 28 '06 #4

P: n/a
In article <11*********************@g43g2000cwa.googlegroups. com>,
Ravi Teja <we*********@gmail.com> wrote:
Why don't you use an existing mail server?


Probably because that was his homework assignment for a networking
class. Not uncommon to be told to implement a server from the scratch
from the RFC. Although that does not explain his concern about
performance.

Abhinav, if that is the case, using sockets is more or less the same
from any language. Python as usual will be cleaner than C. You might
want to look at Twisted Mail. Use SocketServer module in the standard
library to implement the RFC. Other than that it is silly to try to
write a Mail Server unless you have some extra ordinary need.


Any lecturer assigning "write a mail server" as a class project is
doing his/her students a true dis-service. Mail server RFC compliance is a
nightmare to get right, performance issues and mail routeing are both
material for at least a full year's university study.

A student who tries to make an even vaguely RFC compliant mail server
probably won't finish their project, as student who completes such a
project might come away with the mistaken belief that they actually
have done it correctly.

The number of software products which use eail and do so incorrectly
is astounding and depressing. There's a reason that the source for
sendmail is about 120K lines, exim is nearly 270K lines. Doing it
right is _hard_.

--
Jim Segrave (je*@jes-2.demon.nl)

Jan 28 '06 #5

P: n/a
jim you are probably right.

i have had exp. with this. i had to create a server(multipurpose such
as file sharing, games (pretty simple tho like tic tac toe..) we were
in 6th sem with learning OS and comp. n/w for the first time.

it seems like these jack ass jerks (proffs/instuctors) like to bully
students...
obviously we cud not complete the project as most of the time was spent
on
learning the stuff(like TCP, multithreading..) .

i don't know how things work out in the west, but i feel the faculty
really care about their students in american colleges..in contrast to
here (in inida, though things are little different in the IITs)
Jim Segrave wrote:
In article <11*********************@g43g2000cwa.googlegroups. com>,
Ravi Teja <we*********@gmail.com> wrote:
Why don't you use an existing mail server?


Probably because that was his homework assignment for a networking
class. Not uncommon to be told to implement a server from the scratch
from the RFC. Although that does not explain his concern about
performance.

Abhinav, if that is the case, using sockets is more or less the same
from any language. Python as usual will be cleaner than C. You might
want to look at Twisted Mail. Use SocketServer module in the standard
library to implement the RFC. Other than that it is silly to try to
write a Mail Server unless you have some extra ordinary need.


Any lecturer assigning "write a mail server" as a class project is
doing his/her students a true dis-service. Mail server RFC compliance is a
nightmare to get right, performance issues and mail routeing are both
material for at least a full year's university study.

A student who tries to make an even vaguely RFC compliant mail server
probably won't finish their project, as student who completes such a
project might come away with the mistaken belief that they actually
have done it correctly.

The number of software products which use eail and do so incorrectly
is astounding and depressing. There's a reason that the source for
sendmail is about 120K lines, exim is nearly 270K lines. Doing it
right is _hard_.

--
Jim Segrave (je*@jes-2.demon.nl)


Jan 28 '06 #6

P: n/a
ya its supposed to be some stupid 6 month project which my friend has
to do.I am just helping him out.he may not be implementing a full
fledged rfc compliance mail server but may support some of the major
functionalities.so basically its an extra ordinary need.I just wanted
to know which language would be better for implementation and has
faster development cycle.I have heard a lot about python and its ease
of use.My point is it should be worth a 6 month project and speedy
development since he is already proficient in C/C++ socket programming
and taking the pain of learning python should be worth the effort.

Jan 28 '06 #7

P: n/a
If your friend is proficient in C/C++ then learning Python should not
be a pain. Quite the contrary, it should be an enlightnement. Being
good in C/C++ AND Python is a killer combination, as you can promptly
and efficiently code big chunks of your application in Python and
interface with C/C++ code where (and if) high performance is required.

Now, you should definitely check the requirements for the homework.

If the assignment is about being able to decipher an RFC and implement
it correctly with a nice software design, then I would definitely opt
for Python. Having to squish memory management, string manipulation and
character encoding bugs in C/C++ is not fun and not related to
high-level design nor RFC support.

If it's just a way to throw a programming challenge at your friend's
face, then you should check whether it's okay to use Python rather than
C/C++, otherwise he could be charged of cheating by using a more
productive language :).

Regards,
Nicolas

Jan 28 '06 #8

P: n/a
Nicolas wrote:
If it's just a way to throw a programming challenge at your friend's
face, then you should check whether it's okay to use Python rather than
C/C++, otherwise he could be charged of cheating by using a more
productive language :).


Though this comment of mine is likely to start a religious war, it might
also bring up some useful points.

I'm a bit relucted to swallow the common view of Python being a so-
productive language, especially compared to C++. I value C++
productiveness actually much higher than it's performance.

To stick to the mailserver example, I'm pretty sure I'd do it in C++. I
got very exited about Python when I first saw it, but I've encountered
several problems that hindered productivity dramatically.

One thing is the lack of static types. The problem is not only that the
compiler can't tell you very basic things you're doing wrong but also that
code isn't intrinsically documented:

def send_mail(mail):
...

What can I do with mail? In C++, you're looking up what type it is
(presumably by pressing M-x in Emacs on the word before it) and have a
look on it's type definition. In Python, it can be quite difficult to tell
what you can do with it because the information of what will be passed in
can be several layers up.

Also there is not even symbol-safety: self.not_defined will never rise a
compile-time error.

And to address the memory management critisism about C++: Unless you have
cyclic structures (you probably won't have in a mail server), just use
smart pointers and you don't have to be concerned more about it than you'd
have to be in Python.

I aggree on C++ libraries being weak on unicode strings though, or even
generally weak in the libraries (you have the C libraries, but they're not
very type safe or elegant to use).

I'm aware that C++ is a horrible monstrosity, an argument whiches weight
depends on the OP's friends C++ experience.

Please don't be offended, but if anyone could make a point of how Python's
disadvantages in these regards could be alleviated, I'd be very
interested.

Jens

Jan 28 '06 #9

P: n/a
Jim Segrave enlightened us with:
Any lecturer assigning "write a mail server" as a class project is
doing his/her students a true dis-service.


At one time, I got an assignment "Write a robust, user friendly SMTP
client". That was just after we learned how to user 'for' loops and
'if' statements. Talk about dis-services ;-)

Sybren
--
The problem with the world is stupidity. Not saying there should be a
capital punishment for stupidity, but why don't we just take the
safety labels off of everything and let the problem solve itself?
Frank Zappa
Jan 28 '06 #10

P: n/a
Jens Theisen <jt***@arcor.de> wrote:
...
Please don't be offended, but if anyone could make a point of how Python's
disadvantages in these regards could be alleviated, I'd be very
interested.


<http://www.artima.com/weblogs/viewpost.jsp?thread=4639>
<http://www.mindview.net/WebLog/log-0025>

Since Robert Martin and Bruce Eckel (the authors of the two documents
linked above) are both acknowledged gurus of statically typechecked
languages such as C++, the convergence of their thinking and experience
indicated by those documents is interesting.

Tools such as pychecker, pylint, etc, are also considered by some to be
a useful backstop, but unit-tests are the real answer.

The "but without declaration it can't be self-documenting" issue is a
red herring. Reading, e.g.:

int zappolop(int frep) { ...

gives me no _useful_ "self-documenting" information about the role and
meaning of frep, or zappolop's result. The code's author must obviously
add a little comment here to clarify -- and in that little comment,
adding the information about type, if at all relevant, is an obvious
task.

At Google, we collectively have rather a lot of experience in these
issues, since we use three general-purpose languages: Python, Java, C++.
In this mix, the role of C++ is essentially that of allowing the
programmer to have complete control on memory allocation issues: the
only widespread modern language to do that, since all others, including
both Java and Python, have garbage-collection. In the internal style
guide for C++, we forbid the use of so-called ``smart'' pointers which
would basically amount to a hacked-up garbage collection system (which
can never be as solid and thorough as those built into the virtual
machines used in Java or Python -- a GC system that's thread-safe is a
nightmare to build and debug based only on those "smart pointers", for
example, and if you start locking and mutexing all over the place for
that purpose you'll soon see performance plummet...): if you want
garbage collection you use a garbage-collected language -- the choice of
C++ for a component implies that you need complete control of memory
issues for that component, therefore choosing C++ and ``too smart for
their own good'' pointers would be mutually contradictory. Our style
guides for all languages also impose using unit-tests, code reviews, and
standard formats for internal documentation, from naming of variables,
functions and classes to structure and form of comments. As a result,
quality and reliability are remarkably consistent and uniform.

We could say that Python is Google's "secret weapon", except it's not so
very secret, since, in order to attract and hire Python experts, we do
of course need to let it be known that Python's important to us;-). In
a sense, I guess, we are fortunate that our competitors still appear not
to be fully aware of this -- it gives us a better chance to hire Python
luminaries and maintain a productivity edge;-).
Alex
Jan 28 '06 #11

P: n/a
Jens Theisen wrote:
Please don't be offended, but if anyone could make a point of how Python's
disadvantages in these regards could be alleviated, I'd be very
interested.

Jens


Well, I write Java, C++ and Python code, and I have posted a few
thoughts about this on my blog :

http://nicolas.lehuen.com/

My two latest problems with coding in C++ are due to the environments :
libraries using different string types and the whole problem with the
building system. I love the language, but I get a much better leverage
through Python and Java due to the quality and ease of use of their
built-in and third party libraries. I use C++ only for my core data
structure (namely a tuned version of a ternary search tree which I use
to build full text indices).

Regards,
Nicolas

Jan 28 '06 #12

P: n/a
On 2006-01-28, Steven D'Aprano <st***@REMOVETHIScyber.com.au> wrote:
I am a novice in python.I have to implement a full fledged mail server
Because that's just what the world needs, yet another mail server.


:)
C can be faster.


And "can be" is the key. It's easy to write slow programs in C
if you don't choose the right algorithms and architecture.
which language will be easier?


Python is easier to read, and write, and debug, and you will
have fewer hard-to-debug memory issues.


And you'll have fewer security issues with Python since you
don't have to worry about buffer and stack exploits.

--
Grant Edwards grante Yow! There's enough money
at here to buy 5000 cans of
visi.com Noodle-Roni!
Jan 28 '06 #13

P: n/a

On Jan 28, 2006, at 8:39 PM, Dennis Lee Bieber wrote:
On Sat, 28 Jan 2006 18:03:56 +1100, Steven D'Aprano said:

Google is your friend. The first four mail servers listed are, in
order:

sendmail
postfix
Microsoft Exchange
qmail

Dig a bit deeper, and exim might be a candidate for the list. I'm
pretty sure O'Reilly has books for sendmail, postfix, and exim; don't
know about qmail.


O'Reilly does have an Exim book, but it is out of date. It covers the
3.x family, while 4.x has been out for quite a while now. The 4.x
family is very different from 3.x, so the book isn't worth a whole
lot these days.

I'm on my second major mail system deployment built around Exim, and
would recommend it to anybody needing a robust, flexible mail server.

-dan

--
Well sure the government lies, and the press lies, but in a democracy
they aren't the same lies. -Alexis A. Gilliland
Jan 29 '06 #14

P: n/a
Dan Lowe enlightened us with:
I'm on my second major mail system deployment built around Exim, and
would recommend it to anybody needing a robust, flexible mail
server.


Same here. I used Sendmail, QMail, Exim 3 and Exim 4, and out of
those, Exim 4 came out winner.

Sybren
--
The problem with the world is stupidity. Not saying there should be a
capital punishment for stupidity, but why don't we just take the
safety labels off of everything and let the problem solve itself?
Frank Zappa
Jan 29 '06 #15

P: n/a
Nicolas wrote:
http://nicolas.lehuen.com/ My two latest problems with coding in C++ are due to the environments :
libraries using different string types and the whole problem with the
building system. I love the language, but I get a much better leverage
through Python and Java due to the quality and ease of use of their
built-in and third party libraries. I use C++ only for my core data
structure (namely a tuned version of a ternary search tree which I use
to build full text indices).


Those points are all valid. I'm using Python for that reason. And there is
another point that there are good Python bindings for the the more
important C libraries, but usually no decent C++ wrapper for it.

Jens

Jan 29 '06 #16

P: n/a
Alex wrote:
<http://www.artima.com/weblogs/viewpost.jsp?thread=4639>
<http://www.mindview.net/WebLog/log-0025> Since Robert Martin and Bruce Eckel (the authors of the two documents
linked above) are both acknowledged gurus of statically typechecked
languages such as C++, the convergence of their thinking and experience
indicated by those documents is interesting.
Indeed, especially Eckels article shed some light about testing as an
alternative to static typing. I still can't quite understand why you can't
do both. Clearly unit tests should be part of any software, not only
Python software.

Test failures, however, don't tell you anything about the current usage of
your program - just about the inteded usage at the point where the test
was writte. Clearly you can't test _anything_? And clearly you can never
be sure that all you collegues did so as well? This not only about type
safety, but simply name safety.

What do you do when you want to no if a certain method or function is
actually used from somewhere, say "foobar", it a language which allows
(and even encourages) that it could be called by:

getattr(obj, "foo" + "bar")()

?

There is no systematic way to find this call.

In C++, just commend out the definition and the compiler will tell you.

I'm pretty sure I red a PEP about static type safety in Python at some
point. It was even thinking about generics I think.
The "but without declaration it can't be self-documenting" issue is a
red herring. Reading, e.g.: int zappolop(int frep) { ... gives me no _useful_ "self-documenting" information
That's true. If the programmer wants to obfuscate his intention, I'm sure
neither Python nor C++ can stop him. The question is how much more work is
to write comprehensible code in one language or the other. I'm a bit
afraid about Python on that matter.

Python provides ways to easy literal documentation. But I'd really like to
have a way of indicating what I'm talking about in a way that's ensured to
be in-sync with the code. Tests are not where the code is. I have
difficulties remembering the type of a lot of symbols, and looking at
testing code to fresh up usage is more difficult that just jumping to the
definition (which the development envirnment is likely to be able to).
[smart pointers and GC]
As you say, smart pointers are not full-blown garbage collection, which is
usually what you want, isn't it? I my (admittedly short) life as a
professional developer I have not yet come accross a situation where
reference counting was not sufficient to model the memory management.

As for the locking: Apart from locking your whatever you need to lock in
your user code, I don't think any special locking is necessary for the
memory management. Smart pointer can increment and decrement their ref
counts atomically as far as I know.

We use boost::shared_ptr in multi-threaded code just out of the box. We
also use a reference counted string implementation in multi threaded code.
At Google, we collectively have rather a lot of experience in these
issues, since we use three general-purpose languages: Python, Java, C++.


I have no doubt that goolge know what they're doing, and if you're working
there then you're likely to know what you're talking about.

I found it especially astonishing what you had to say against the use of
smart pointers.

Jens

Jan 29 '06 #17

P: n/a
Jens Theisen wrote:
Test failures, however, don't tell you anything about the current usage of
your program - just about the inteded usage at the point where the test
was writte. Clearly you can't test _anything_? And clearly you can never
be sure that all you collegues did so as well? This not only about type
safety, but simply name safety.

What do you do when you want to no if a certain method or function is
actually used from somewhere, say "foobar", it a language which allows
(and even encourages) that it could be called by:

getattr(obj, "foo" + "bar")()
?

There is no systematic way to find this call.


While this isn't really a "test", as you are really asking about
something to do with managing your code base, it is quite possible to
write a test which *does* check whether foobar() is called, and even to
pinpoint all places from which it is called, if that's really what you
want to do. Believing you can't do that suggests you have no real
experience with writing tests for code, so it might be best not to argue
so strenuously against them.

-Peter

Jan 29 '06 #18

P: n/a
Jens Theisen <jt***@arcor.de> wrote:
...
Indeed, especially Eckels article shed some light about testing as an
alternative to static typing. I still can't quite understand why you can't
do both. Clearly unit tests should be part of any software, not only
Python software.
Clearly. Given this, adding static typing as well still has all the
costs in terms of productivity, but much diminished benefits. So it's
not a question of "can't", but of "not worth the cost".
Test failures, however, don't tell you anything about the current usage of
your program - just about the inteded usage at the point where the test
was writte. Clearly you can't test _anything_? And clearly you can never
be sure that all you collegues did so as well? This not only about type
safety, but simply name safety.
So you are now arguing against any kind of introspection abilities? Do
dlopen and dlsym sap the power you attribute to C++, then?
What do you do when you want to no if a certain method or function is
actually used from somewhere, say "foobar", it a language which allows
(and even encourages) that it could be called by:

getattr(obj, "foo" + "bar")()

?
"Encourages"? What a silly assertion. Python makes introspection
easier than Java's Reflection, C#'s similar capabilities, and C/C++'s
primitive dlopen/dlsym, but the existence of similar dynamic name
resolution abilities in each of these languages reflects similar
underlying real needs. The functionality is there for those cases in
which it's needed, but it's silly to use it when not needed.

There is no systematic way to find this call.

In C++, just commend out the definition and the compiler will tell you.
You're too optimistic re C++: given its complex rules, the compiler
might well find a different 'foobar' once you comment out that one.

But more: if that function is called via dlopen and dlsym, or similar
functionalities on Windows etc, what can the compiler tell you? It will
tell you nothing, and if you take that as meaning the function is not
called, you're in for a surprise.

So, in C++ like in any of the other languages offering handier
introspection facilities, Python included, you need integration tests
(harder than unit tests) or heuristics based on source analysis (which
won't catch the cases in which the namestrings are constructed
dynamically).

If you're arguing against introspection and dynamic libraries, then
you're not arguing against Python per se, but rather against the whole
grain of modern component-oriented development; since C++, as much as
Java, Python and C#, is most often used for such kind of development,
you should take the debate to a more general forum.

I'm pretty sure I red a PEP about static type safety in Python at some
point. It was even thinking about generics I think.
You're probably thinking of Guido's musings in his blog, never actually
formalized to the point of being a PEP. Of course, he soon realized
that there was nothing "static" about the typechecking functionality he
was (and is) thinking of introducing in Python 3000 -- it's entirely
dynamic, just like a Java cast or a C++ dynamic_cast. Just like
decorators are just syntax sugar over existing higher-order-function
possibilities, so the typing checks will be syntax sugar over either
existing or propoposed (my PEP246) dynamic adaptation ones.

E.g., you may (in a few years when Python3000 comes) write:

def f(x: Foo): ...

just like you may write (in fewer years if and when PEP246 is accepted):

def f(x):
x = adapt(x, Foo)
...

or perhaps (if PEP246 is rejected) the semantics will be

def f(x):
assert isinstance(x, Foo)
...

Syntax sugar matters: people will be vastly more likely to use
adaptation or typechecking if a nice syntax is provided, just like they
now use HOFs more freely thanks to decorator syntax. But it does not in
any way change the abilities of the language, there's nothing static
about it, and it doesn't really address any of the criticisms such as
yours -- although it may reduce the volume of complaints if it takes
good understanding of the language to realize the functionality is
indeed dynamic, but that's just like saying that Java's goofy:

zap = (Zapper) gup;

is better than C++'s more explicit:

zap = dynamic_cast<Zapper>(gup);

because the latter immediately ADMITS it's dynamic, while the former
LOOKS (confusingly;-) more static (even though its semantics isn't).

I prefer truth in advertising: call dynamic what's dynamic, let the
critics criticize (just like they criticize dynamic_cast), and ignore
them (except when you're looking for excuses not to work, just like I'm
doing now since I should be slaving over the 2nd edition of my Nutshell
book;-).

The "but without declaration it can't be self-documenting" issue is a
red herring. Reading, e.g.:

int zappolop(int frep) { ...

gives me no _useful_ "self-documenting" information


That's true. If the programmer wants to obfuscate his intention, I'm sure
neither Python nor C++ can stop him. The question is how much more work is
to write comprehensible code in one language or the other. I'm a bit
afraid about Python on that matter.


Well then, look at some Python codebase vs C++ codebase with fair
assessment, rather than theorize. The standard libraries of the
languages are both vast and available in source form, so they're a good
place to start -- Python's is vaster, because it addresses issues quite
different from C++'s (since Python's library need not strive to provide
containers and iterators), but you can find open-source C++ libraries
for direct comparison (a wonderful example is Boost).

Python provides ways to easy literal documentation. But I'd really like to
have a way of indicating what I'm talking about in a way that's ensured to
be in-sync with the code. Tests are not where the code is. I have
Actually, tests ARE code, which is part of what makes them better than
comments -- they don't go out of sync like comments may.
difficulties remembering the type of a lot of symbols, and looking at
testing code to fresh up usage is more difficult that just jumping to the
definition (which the development envirnment is likely to be able to).
It's actually harder to find all definitions in C++ given name
overloading; the development environment, just like the programmer, may
get confused as to whether you mean 'int foo(float)' or rather 'float
foo(int)'. Python doesn't have name overloading, so you just find 'def
foo(', which is an easier task. I believe IDEs such as Wing and Komodo
offer this. Personally, being a dinosaur, my 'IDE' is vim+commandline
in either C++ or Python, so I care more about the abilities of
"exuberant ctags", which vim supports nicely; developers who prefer
fancier tools (emacs, Eclipse, or the various IDEs) surely have more
features at their fingertips, not fewer.

At Google, we collectively have rather a lot of experience in these
issues, since we use three general-purpose languages: Python, Java, C++.


I have no doubt that goolge know what they're doing, and if you're working
there then you're likely to know what you're talking about.


Well, Google reached all the way across the Atlantic to hire me as uber
technical lead, making it worth my while to drop my freelance
professional practice and move 9 timezones west; and no doubt my
authorship of "Python in a Nutshell", widely used at Google, helped me
get attention, but I had to prove my excellence in C++ and many other
subjects as well during the extremely strict selection process (no
sweat: before discovering Python, I made my living mostly as a guru in
C++ [and many other technologies, of course], with nice pieces of 'MVP'
parchment &c, though I never wrote books on the subject).

The funny thing is that I found myself starting at Google at about the
same time as Matt Austern, whose many claims at guruhood are in good
part about C++ and generic programming -- we hadn't met before, but
since we already loved each other's books and works, and share many
"side" technical interests (such as functional programming and strict
type theory), it was fortunate that we soon found ourself cooperating.

I've often noticed that many REAL C++ gurus tend to understand and
appreciate the tradeoffs involved in programming language design, and,
whether they end up _preferring_ dynamic languages (like [he said
immodestly;-)] me, Tim Peters, Robert Martin, Bruce Eckel), or still
prefer to stick mostly with mostly-static ones (like Matt Austern,
Andrew Koenig, Scott Meyers) don't exhibit the tendency to assume that
one set of choices is somehow inherently inferior. There are, of
course, exceptions (just like there are Python gurus who intensely
detest C++...;-), and you'd seem to be one such exception.

I found it especially astonishing what you had to say against the use of
smart pointers.


If using a properly garbage-collected language was not an option, I'd be
suffering with "smart" pointers too (I did for many years, and that was
before Boost came to the world with its excellent libraries). But once
you realize that the main difference of C++ vs Java, Python and all the
rest is exactly that C++ doesn't DO gc, trying to shoehorn gc in it
anyway starts to make little sense. Performance issues related to CPU
cycles are pretty minor these days, particularly on server-side tasks
where having a few more servers is no big deal and bottlenecks come up
in database access and network operations anyway. Java's JITs have
matured, and the typical performances of (e.g.) Java SciMark vs the ANSI
C version can show you that CPU cycles aren't really a big deal any
more; Python's JITs are not as mature as Java's, but psyco has been
around a while to show that the possibilities are extremely similar.

But memory - ah, memory! A 32-bit CPU may let you use 2GB or maybe 3GB
of RAM for your tasks; and depending on how your servers are designed,
you might have four dual-core 32-bit CPUs sharing the same meager 3GB...
pretty obviously, if 4 or 8 cores are splitting that little RAM, then
RAM is the scarce resource, CPU cycles are throw-away. The situation
may get better with 64-bit CPUs _if_ RAM costs (including ones related
to supplying power and dissipating heat;-) finally crash once again, but
they've been relatively steep for a while, even while CPU-cycle costs
kept dropping; and 64-bit CPUs are still, after years, in the "almost
there but not quite" stage -- consider that Apple has been shipping for
a month a computer where a 64-bit CPU ("G5" PPC) has been replaced with
a dual-core 32-bit one (intel "Yonah" aka Core Duo), and the latter is
faster than the former (it even holds its own, in some cases, where it
has to _emulate_ the former's instruction set, to run some of the many
programs that haven't yet been ported to the new ISA... btw, of course,
Python and Java programs don't have such porting problems, the issue is
with the stuff in C, Objective-C, C++...;-).

As long as memory is THE scarce resource, it makes sense to be able to
be entirely in control of what happens to your memory, even though that
carries the cost of risking dangling pointers, memory leaks, buffer
overflows -- a heavy cost, but (for speed-critical applications) worth
paying to ease the bottlenecks. Java's particularly bad in this regard:
JVMs suck up memory like there's no tomorrow, and the more they JIT, the
more memory-hungry they are (Python's not quite as memory-greedy, but
still, particularly with psyco JITting away, it's no picnic either).

But if you introduce "too smart for their own good" pointers in the mix,
then suddenly it's not clear any more if you ARE still in total and
exact control of your memory consumption -- you're back into gc land.
And if you must gc, why not use a language with gc built right in? The
gc designed as an integral part of the system will perform better and
avoid (e.g.) embarassments with reference-cycles causing memory leaks.

So, I would advise: where you can afford to spend a bit more memory than
strictly necessary, go for a gc language; where you can't, C or C++ are
the best choice today. Of course, there is no requirement to use just
one language for any given program: if you build reusable components,
you may build them in several languages, and use them from applications
coded in other languages yet. SWIG helps (or, Boost Python, if you
specifically care only about C++ and Python). Java doesn't really play
well in this space -- you can use Python with it, but interoperating it
well with C++ basically requires separate processes and RPC or the like.
But Python and C++ do work very well together.

Ah well, back to the writing -- apologies in advance if I prove unable
to further continue this thread, but I don't want my editor to come
after me with a cudgel, considering how late the 2nd edition of "Python
in a Nutshell" is already;-).
Alex

Jan 29 '06 #19

P: n/a
In article <11*********************@o13g2000cwo.googlegroups. com>,
abhinav <ab***********@gmail.com> wrote:
ya its supposed to be some stupid 6 month project which my friend has
to do.I am just helping him out.he may not be implementing a full
fledged rfc compliance mail server but may support some of the major
functionalities.so basically its an extra ordinary need.I just wanted
to know which language would be better for implementation and has
faster development cycle.I have heard a lot about python and its ease
of use.My point is it should be worth a 6 month project and speedy
development since he is already proficient in C/C++ socket programming
and taking the pain of learning python should be worth the effort.


In that case, you'll come closer to having a working mail server in
Python. I just hope that it's understood you won't have a mail server
which is ready to be used on the Internet for any but very limited
applications.
--
Jim Segrave (je*@jes-2.demon.nl)

Jan 29 '06 #20

P: n/a
In article <ma***************************************@python. org>,
Dan Lowe <da*@tangledhelix.com> wrote:

On Jan 28, 2006, at 8:39 PM, Dennis Lee Bieber wrote:
On Sat, 28 Jan 2006 18:03:56 +1100, Steven D'Aprano said:

Google is your friend. The first four mail servers listed are, in
order:

sendmail
postfix
Microsoft Exchange
qmail

Dig a bit deeper, and exim might be a candidate for the list. I'm
pretty sure O'Reilly has books for sendmail, postfix, and exim; don't
know about qmail.


O'Reilly does have an Exim book, but it is out of date. It covers the
3.x family, while 4.x has been out for quite a while now. The 4.x
family is very different from 3.x, so the book isn't worth a whole
lot these days.

I'm on my second major mail system deployment built around Exim, and
would recommend it to anybody needing a robust, flexible mail server.


There is an exim 4 book out, but not via O'Reilly - I gather sales
were insufficient to persuade O'Reilly to do an update. As we use Exim
heavily, we have both the 3 and 4 books in our NOC, as well as sending
almost all new staff to Phil Hazel's excellent courses in Cambridge.


--
Jim Segrave (je*@jes-2.demon.nl)

Jan 29 '06 #21

P: n/a
Jens Theisen wrote:
What do you do when you want to no if a certain method or function is
actually used from somewhere, say "foobar", it a language which allows
(and even encourages) that it could be called by:

getattr(obj, "foo" + "bar")()
No. The recommended way to do it is:

obj.foobar()
There is no systematic way to find this call.

In C++, just commend out the definition and the compiler will tell you.


In such a case I normally just grep for "foobar". I did so (and I'll do so)
in C/C++, Python, and any other language.
Any programming language allows you to do strange/stupid stuff. But none
of them encourages it. So I can't see your point in any way.

Greets,

Volker

--
Volker Grabsch
---<<(())>>---
\frac{\left|\vartheta_0\times\{\ell,\kappa\in\Re\} \right|}{\sqrt
[G]{-\Gamma(\alpha)\cdot\mathcal{B}^{\left[\oint\!c_\hbar\right]}}}
Jan 29 '06 #22

P: n/a
Quoth al***@mail.comcast.net (Alex Martelli):
| Jens Theisen <jt***@arcor.de> wrote:
....
|> What do you do when you want to no if a certain method or function is
|> actually used from somewhere, say "foobar", it a language which allows
|> (and even encourages) that it could be called by:
|>
|> getattr(obj, "foo" + "bar")()
|>
|> ?
|
| "Encourages"? What a silly assertion. Python makes introspection
| easier than Java's Reflection, C#'s similar capabilities, and C/C++'s
| primitive dlopen/dlsym, but the existence of similar dynamic name
| resolution abilities in each of these languages reflects similar
| underlying real needs. The functionality is there for those cases in
| which it's needed, but it's silly to use it when not needed.

Silly indeed, and why would such a thing ever be needed? Yet it
does in fact occur in widely used Python software, in an application
where it of course wasn't really needed, rather was sort of convenient.
This is like the C enthusiast who tells you that any self-respecting
programmer won't mind accounting for storage, or the Perl enthusiast
who tells you that there's nothing about the language that encourages
hard-to-read code. Give people a feature like this, and they will
find a need for it, to the detriment of comprehensibility.

I'm not saying that we should therefore use C++ !, but let's be
realistic about the costs of Python's benefits.

Donn Cave, do**@drizzle.com
Jan 30 '06 #23

P: n/a
Volker Grabsch wrote:
Any programming language allows you to do strange/stupid stuff. But none
of them encourages it.


One word: Intercal.

:-)

--
Steven.

Jan 30 '06 #24

P: n/a
Alex Martelli wrote:
The "but without declaration it can't be self-documenting" issue is a
red herring. Reading, e.g.:

int zappolop(int frep) { ...

gives me no _useful_ "self-documenting" information about the role and
meaning of frep, or zappolop's result. The code's author must obviously
add a little comment here to clarify -- and in that little comment,
adding the information about type, if at all relevant, is an obvious
task.


Yes, one can use such simple types that the types do not tell you that
much. They do tell you something though. The arg and return types are
not list structures for example. They aren't floats either.

However, C/C++ at least provide a way to make types tell you far more.
For example, one could declare enum types:

typedef enum MyArgType
{
// a bunch of enum const names here
} MyArgType;
typedef enum MyResultType
// another bunch of enum const names
} MyResultType;

Then your example above becomes

MyResultType zappolop(MyArgType frep) { ...

and that's a lot more insightful.

I return objects in Python and in C++. In C++ I can see what their
types are right on the m method signature. In Python I've got to write
a comment on the line above it. If I change what type I return and
forget to change the comment then the code isn't correctly documented
anymore. I've done recently and found out with a runtime error while
testing the Python. In C++ if I'd changed the return type the compiler
would have told me if I didn't use it that way somewhere else.

There are a lot of stages at which to reduce the chance of bugs. While
coding an editor can give you more help with code completion if you
have more static typing. At compile time the compiler can tell you
about errors if it knows the types you are using.

I use PyChecker and PyLint and while they are incredibly helpful (and
I'm grateful to their authors just as I am to Python's developers) they
do not tell me as much as Borland's C++ compiler does. I get more
runtime errors with my Python code than with my C++ code.

Still, I find Python useful and better than C++ in some situations.
But I wish it provided better options for allowing me to indicate types
so that more errors could get caught sooner and so that editor code
completion could be smarter.

Jan 31 '06 #25

P: n/a
Randall Parker wrote:
I return objects in Python and in C++. In C++ I can see what their
types are right on the m method signature. In Python I've got to write
a comment on the line above it.


Ouch! Don't do that! As you've noticed, it's not very maintainable.

First of all, if you want to use Python well, embrace it's dynamic
nature, don't try to restrain it! It takes some time to let go of
the static thinking if one is used to it, but try. Just as lots of
programming guidelines (e.g. Parna's Principle and The Law of
Demeter) tells us that we should try to know and depend as little
as possible on the details in other pieces of code, the duck typing
behaviour in Python extends this one step further, to types.

Without proper tests, this might cause more problems than it solves,
but there is no excuse for not having proper automated tests for
software you develop in the 21st century!!!

You *don't* write an unmaintainable comment about what return
type to expect, you write unit tests that shows you how to use
each API that you implement. You run these tests often, fix them
as soon as they break, and you encourage their use as
documentation which describes through examples how to use you
APIs. (Sorry about the imperative tone. It's your life after
all, but don't blame Python for not fitting your style of
development.)

You should do that for statically typed languages as well. Knowing
that you got the correct type back gives you no assurance that
you got the right value!
Feb 1 '06 #26

This discussion thread is closed

Replies have been disabled for this discussion.