On Mon, Nov 12, 2007 at 04:41:35PM -0500, Chris Fant wrote:
> I would like some language recommendations. Requirements:
> Runs in Linux
> Has garbage collection
> Fast
> Well supported
> Can interface with MPI (can make C calls)
Yes, wouldn't want a language question to start a war.:-|
Among the languages I know something about (which excludes D and C#,
for example)...
...for some values of "well supported":
* OCaml
* Common Lisp
People complain about the relative scarcity of libraries for both of
them, not without justification. If you're coming from a more popular
language like C and C++, you may miss libraries implementing
algorithms and data structures. If you're coming from a popular
language like Perl or Python where people do less work in algorithms
and data structures, still you may miss libraries for GUIs and WWW
operations and databases and whatnot. Such libraries aren't
nonexistent for OCaml and Common Lisp, but they're not as plentiful as
they are for more popular languages.
...for some values of "well supported" and "fast":
* Scheme
I've read people complaining that the implementations which are
pleasant to work with (helpful debugger and nice foreign function
interface and so forth) are not fast, and the fast implementations are
unpleasant to work with, though I can't confirm this from firsthand
experience.
...for some values of "fast":
* Java
I haven't used Java for many years, apparently some implementations
have gotten pretty fast since then, but I don't know how easy it is
for a lone programmer to get such an implementation for his Linux box.
(And even if I could have a fast implementation, I like things like
higher order functions enough that writing in Java felt clunky to me,
so I'd choose to avoid it.)
technically perhaps allowed by your feature list, but in my judgment a
poor fit for Go (because, e.g., strict purely functional data
structures make it hard to efficiently modify a single square among
361):
* Haskell
also technically allowed but an even worse fit for any reasonably
normal Go program:
* Prolog
Also Prolog may be in a higher obscurity class than the others: unlike
even the most obscure languages listed above, I don't know any serious
applications which are maintained in Prolog today.
I have written a lot of Go code in C++ and Common Lisp, and I like
Common Lisp. OCaml might be my second choice. Or, if I were writing a
program with a very conservative design, without weird data
structures, perhaps I'd write it in C++. And my current CL code
shouldn't be incredibly hard to translate to C++ if I ever need to,
just very very tedious, a little like translating a program containing
a lot of C++ OO constructs into a program in plain C.
Various people advised you to remove GC from your feature list. E.g.,
Christoph:
>> Forget 'garbage collection' and use 'C'.
Nick:
>> If you like to have your garbage collected for you then use
>> one of the management strategies present in C++. If you like
>> delayed freeing, overload new or use a library that does this.
[...]
>> If you can't avoid memory leaks, fine, don't use C++ or C, but
>> don't blame the language. You could use garbage collection if
>> you need it; don't make us all stoop to your level of competency
>> and don't try and claim that your language is just as fast when
>> it isn't.
(You probably don't need to be convinced of this, but) I think they
are mistaken. People who use sufficiently complicated data structures,
or just lots of higher order functions, often have good reasons to use
GC. Ask anyone who has worked on a reasonably modern optimizing
compiler, for example, whether garbage collection is worth having in
the language used to represent the compiler's own algorithms and data
structures. In my experience, most of them will say "yes" --- and
recruiting those who say "no" is not an effective way to recruit the
good programmers.:-|
Or, closer to Go, find a copy of Wolfe's Gamesman's Toolkit code and
do some work with the combinatorial game theory calculations there. Is
there anyone here who is reasonably fluent in a language like Lisp or
ML and wants to argue it couldn't be clearer in such a language? I
ended up rewriting the logic that I needed in CL. It sure seemed to me
that it naturally became much cleaner in the process, in part because
of GC. (It'd similarly have become cleaner in other languages
mentioned here, like languages in the ML family.) It's not because I
don't know how to do smart pointers and reference counting in C++,
either.
It is true that some kinds of calculations don't benefit from garbage
collection. But that doesn't mean GC is useless, it just means "horses
for courses." Some kinds of calculations don't benefit from recursion
or object orientation or convenient string manipulation either. I
spent several years in graduate school writing numerical Monte Carlo
simulations of quantum mechanics in Fortran77, and it worked pretty
well: in that problem domain, I didn't miss the greater expressiveness
of C very much. But I think trying to write a visual editor or a web
server in Fortran 77 would be quite aggravating.
It is also true that GC can cause a noticeable performance penalty.
This arises in some direct ways (like of the cost of running the
actual garbage collection algorithm) and in some indirect ways (like
the way that in practice garbage collectors often impose constraints
on compiler register allocation, and often forbid objects being
physically embedded in each other and instead require indirection
through an extra pointer). It is not unheard of for the advantage to
be negligible or even run the other way, but in practice for a program
which does a lot of heap allocation, I expect the performance cost to
be 20-50% compared to ordinary well-written C or C++ code, or
significantly higher if the heap allocation has a trivial pattern of
some sort (like pure LIFO order) and in the low-level code one can
take advantage of the pattern to bypass the general malloc()-ish
library algorithm in favor of some simple fast special-purpose
allocation algorithm. I'm usually happy to accept such GC overhead in
order to get significantly simpler code, even when I'm working with
data structures less interesting than optimizing compiler internal
representations or cyclic combinatorial games. But I think that
when/if a project gets to the point where it is limited not by
developer time but by CPU cycles, it can be quite reasonable to change
to a lower-level language. Or, sometimes you can get what you want by
calling out to a library in a lower-level language: e.g., I have over
the years noticed that projects written at the Lisp/ML abstraction
level tend to delegate their BDD calculations to external C/C++
libraries.
Nick Apperson: You write as though garbage collection is "reference
counting and copy on write." You are in good company, lots of very
smart people have arrived at that conclusion over the years, enough of
them that even decades ago it was a cliche that people joked about
(see "Moon instructs a student" at
<http://catb.org/jargon/html/koans.html#id3141202>). And despite that
cliche, the idea got built into the "garbage collection" in languages
like Perl. Alas, it is basically incorrect: at least, you need to
beware of important cases where it breaks down. In particular, it is
easy to cause memory leaks in a reference counting scheme by setting
up cyclic references. And alas, not all problem domains make it
natural to avoid cyclic references. You seem to be used to problem
domains which feature a clear notion of which object owns which
object, and that lets you avoid cyclic references by setting up a
directed acyclic graph of ownership relationships. But not all
problems are like that. In Go, consider a graph representing the cycle
of three or more board positions which make up a ko fight. If there
are records representing representing those board positions and
referring to each other, which record owns which? Or for another
problem domain, see
<http://www.perl.com/pub/a/2002/08/07/proxyobject.html>. For simple
cases like that, special-purpose hacks suffice to work around the
problem. But as data structures get more complicated, special-purpose
hacks scale poorly, while true GC continues to Just Work.
somebody who wrote optimistically about how GCed code is in practice
just as fast as C++-level code: That does happen sometimes. To me,
though, it seems to be really common that when a manageably simple
codebase stabilizes and people decide they're willing to double their
coding effort in order to double the speed, they switch to C or C++ in
the process and (as long as the codebase remains very stable, anyway)
are basically satisfied with the switch. I don't remember how many
times I've run across this, but I do remember the most recent time: I
chased the computer Go bibliography into the U. Alberta games group
work on Sokoban, and noticed that the POWER PLAN program calls out to
the TLPlan planner, and TLPlan was originally developed in Lisp but
was eventually translated to a lower level language for performance.
--
William Harold Newman <[EMAIL PROTECTED]>
PGP key fingerprint 85 CE 1C BA 79 8D 51 8C B9 25 FB EE E0 C3 E5 7C
Ubi saeva indignatio ulterius cor lacerare nequit. -- Jonathan Swift's epitaph
_______________________________________________
computer-go mailing list
[email protected]
http://www.computer-go.org/mailman/listinfo/computer-go/