Python vs C for a mail server

A

abhinav

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?
 
S

Steven D'Aprano

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? :)
 
R

Ravi Teja

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.
 
A

al pacino

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.
 
J

Jim Segrave

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_.
 
A

al pacino

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)
 
A

abhinav

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.
 
N

Nicolas Lehuen

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
 
J

Jens Theisen

Nicolas said:
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
 
S

Sybren Stuvel

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
 
A

Alex Martelli

Jens Theisen said:
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
 
N

Nicolas Lehuen

Jens said:
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
 
D

Dennis Lee Bieber

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? :)

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.
--
 
G

Grant Edwards

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.
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.
 
D

Dan Lowe

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
 
S

Sybren Stuvel

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
 
J

Jens Theisen

Nicolas said:
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
 
J

Jens Theisen

Alex said:
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
 
P

Peter Hansen

Jens said:
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
 
A

Alex Martelli

Jens Theisen said:
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;-).

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.

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
474,283
Messages
2,571,405
Members
48,098
Latest member
inno vation

Latest Threads

Top