views:

672

answers:

15

I'm a scientist working mostly with C++, but I would like to find a better language. I'm looking for suggestions, I'm not even sure my "dream language" exist (yet), but here's my wishlist;

IMPORTANT FEATURES (in order of importance)

1.1: Performance: For science, performance is very important. I perfectly understand the importance of productivity, not just execution speed, but when your program has to run for hours, you just can't afford to write it in Python or Ruby. It doesn't need to be as fast as C++, but it has to be reasonably close (e.g.: Fortran, Java, C#, OCaml...).

1.2: High-level and elegant: I would like to be able to concentrate as most as possible on the science and get a clear code. I also dislike verbose languages like Java.

1.3: Primarely functional: I like functional programming, and I think it suits both my style and scientific programming very well. I don't care if the language supports imperative programming, it might be a plus, but it has to focus and encourage functional programming.

1.4: Portability: Should work well on Linux (especially Linux!), Mac and Windows. And no, I do not think F# works well on Linux with mono, and I'm not sure OCaml works well on windows ;)

1.5: Object-oriented, preferably under the "everything is an object" philosophy: I realized how much I liked object-oriented programming when I had to deal pure C not so long ago. I like languages with a strong commitment to object-oriented programming, not just timid support.

NOT REALLY IMPORTANT, BUT THINGS THAT WOULD BE NICE

2.1: "Not-too-strong" typing: I find Haskell's strong typing system to be annoying, I like to be able to do some implicit casting.

2.2: Tools: Good tools is always a plus, but I guess it really depends on the languages. I played with Haskell using Geany, a lightweight editor, and I never felt handicapped. On the other hand I wouldn't have done the same with Java or even Scala (Scala, in particular, seems to be lacking good tools, which is really a shame). Java is really the #1 language here, with NetBeans and Javadoc, programming with Java is easy and fun.

2.3: Garbage collected, but translated or compiled without a virtual machine. I have nothing against virtual machines, but the two giants in the domain have their problems. On paper the .net framework seems much better, and especially suited for functional programming, but in practice it's still very windows-centric and the support for Linux/MacOS is terrible not as good as it should be, so it's not really worth considering. Java is now a mature VM, but it annoys me on some levels: I dislike the ways it deals with executables, generics, and it writes terrible GUIs (although these things aren't so bad).

+4  A: 

Your requirements seem to me to describe ocaml quite well, except for the "not-too-strong" typing. As for tools, I use and like tuareg mode for emacs. Ocaml should run on windows (I haven't used it myself though), and is pretty similar to F#, FWIW.

I'd consider the ecosystem around the language as well. In my opinion Ocaml's major drawback is that it doesn't have a huge community, and consequently lacks the large library of third-party modules that are part of what makes python so convenient. Having to write your own code or modify someone else's one-shot prototype module you found on the internet can eat up some of the time you save by writing in a nice functional language.

brendan
IMO, the library support / 3rd-party module availability is the one real trump card of F#.
Marc Gravell
+4  A: 

You can use F# on mono; perhaps worth a look? I know that mono isn't 100% perfect (nothing ever is), but it is very far from "terrible"; most of the gaps are in things like WCF/WPF, which I doubt you'd want to use from FP. This would seem to offer much of what you want (except obviously it runs in a VM - but you gain a huge set of available libraries in the bargain (i.e. most of .NET) - much more easily than OCaml which it is based on).

Marc Gravell
I don't get his point about F# not working well in mono. F# should "work [as] well" as any .NET language in mono, since it, like every other .net language, is compiled to IL. The question should be, "does IL work well in mono?"
Will
Agreed - and if he disagrees he is welcome to downvote me ;-p
Marc Gravell
F# performance in Mono is bad right now.
wrang-wrang
Really? You honestly surprise me. I admit I've only used it on mono for validation; not in "anger"...
Marc Gravell
F# is about 4 times slower than Scala according to the "Computer Language Benchmarks Game", which is starting to be too slow for me. Beside, while I had a reasonably good experience with C# on Mono, I cannot say the same for F#.Mono is still far behind Microsoft's .Net, this is a huge issue since many scientists in my field use Linux/MacOS (including me). Otherwise I would probably adopt F#, as it does seem to fit all my needs (it has some great librairies such as dnAnalytics and I like Cairo/Gtk#).Terrible was probably too strong a word ;-)Thanks for the answer.
Shinka
I guess it's improved lately, but it still seems that Mono has put more work into running C# well than F#. Even with the Mono speedbump, F# is faster when using unboxed floats than Ocaml in some cases, so it might not be a bad choice overall. http://abdullin.com/journal/2009/1/6/f-has-better-performance-than-c-in-math.htmlhttp://lists.ximian.com/pipermail/mono-list/2009-January/041088.htmlhttp://groups.google.com/group/comp.lang.functional/msg/1cbd9c411b93ed3fhttp://flyingfrogblog.blogspot.com/2009/01/mono-22.html
wrang-wrang
+4  A: 

I would still go for Python but using NumPy or some other external module for the number crunching or alternatively do the logic in Python and the hotspots in C / assembler.

You are always giving up cycles for comfort, the more comfort the more cycles. Thus you requirements are mutual exclusive.

Martin P. Hellwig
I strongly disgree with the notion that my requirements are mutually exclusive, at least not anymore. Many high-level languages, such as Haskell, OCaml, and Scala, produce very fast programs. They're not dynamic, of course, but I don't care about that.
Shinka
The requirements you given explicitly stated performance, any syntax sugar will cost clock cycles, whatever you do. Some may be faster than others but it always will be slower than the algorithm directly implemented in the assembly language for that platform.When you come up with the notion that for example Java is fast enough, I can guarantee you that using Python with the hotspot written in C or using a specialized numeric module will outperform any of the other implementation in whatever language except C/Assembler. However the same thing can be done with any FFI supporting language.
Martin P. Hellwig
+6  A: 

Try Scala. It's an object-oriented functional language that runs in the JVM, so you can access everything that was ever written in Java. It has all your important features, and one of the nice to have features. (Obviously not #2.2 :) but that will probably get better quickly.) It does have very strong typing, but with type inference it doesn't really get in your way.

jqno
Scala fits all of your requirements except 2.2. It has the right sort of strong typing, in that it's used to support the programmer in writing cleaner, simpler code rather than forcing them to jump through hoops. It's much less verbose than Java, for approximately the same performance. It supports and encourages functional style while still permitting a non-functional.
Marcus Downing
+1  A: 

Short Version: The D Programming Language

Yum Yum Yum, that is a big set of requirements.

As you probably know, object orientation, high-level semantics, performance, portability and all the rest of your requirements don't tend to fit together from a technical point of view. Let's split this into a different view:

Syntax Requirements

  1. Object Orientated presentation
  2. Low memory management complexity
  3. Allows function style
  4. Isn't Haskell (damn)

Backend Requirements

  1. Fast for science
  2. Garbage Collected

On this basis I would recommend The D programming language it is a successor to C trying to be all things to all people.

This article on D is about it's functional programming aspects. It is object-orientated, garbage collected and compiles to machine code so is fast!

Good Luck

Aiden Bell
A: 

Are you sure that you really need a functional language? I did most of my programming in lisp, which is obviously a functional language, but I have found that functional programming is more of a mind-set than a language feature. I'm using VB right now, which I think is an excellent language (speed, support, IDE) and I basically use the same programming style that I did in lisp - functions call other functions that call other functions - and functions are usually 1-5 lines long.

I do know that Lisp has good performance, run on all platforms, but it is somewhat outdated in terms of how up to date support for features such as graphics, multi-threading etc. are.

i've taken a look at clojure but if you don't like java you probably won't like clojure. It's a functional-lisp-style language implemented on top of java - but you'll probably find yourself using java libraries all the time which adds the verbosoity of java. I like lisp but I didn't like clojure despite the hype.

Are you also sure about your performanc requirements? Matlab is an excellent language for a lot of scientific computation, but it is kind of slow and I hate reading it. You might find t useful though especially in conjunction with other languages, for prototypes/scenarios/subunits.

Larry Watanabe
I'd say it's more than a mindset. I think a functional language should support closures, for instance, and should make it easy to use functions as _arguments_ to other functions. Lack of tail recursion also discourages a functional style.
brendan
The mindset is definitely an important component. Since learning Scala (itself only an impure functional language, in that it has the features of a functional language while letting you write in a non-functional style if you prefer), my code in other languages has become more functional in style. Even in PHP, one of the least functional languages around!
Marcus Downing
What do you mean by lack of tail recursion? Tail recursion is just where the function call occurs. The issue is whether the compiler is smart enough to eliminate recursive calls for tail recursion or not -- it's a simple compiler optimization and I'm sure the CLR has it.In any event, it is a compiler optimization issue, not a language issue.
Larry Watanabe
If a language doesn't guarantee tail recursion, then you can't really use recursion as a looping construct, because it is too expensive. The natural alternative is an imperative style with mutable data. Some languages require certain forms of recursion to be implmented as tail calls, and some don't. For instance, I believe gcc can find some tail calls, but because C doesn't mandate it you would still be very careful about your use of recursion.
brendan
I prefer C/C++ to VB, actually. VB is nearly everything a good language for science should not be. While it's interesting to have a GUI, most programs in science don't have one. And it runs mosly on windows (many scientists in academia, if not most, work with Unices). MatLab is slower than C, but the performance is often reasonable, but I use Python with Numpy for the Matlab-like problems I encounter.
Shinka
+2  A: 

Clojure and/or Scala are good canditates for JVM

dfa
+1  A: 

I'm going to assume that you are familiar enough with the languages you mentioned to have ruled them out as possibilities. Given that, I don't think there is a language that fulfills all your expectations. However, there are still a few languages you could take a look at:

  1. Clojure This really is a very nice language. It's syntax is based on LISP, and it runs on the JVM.

  2. D This is like C++ done right. It has all the features you want except that it's kind of weak on the functional programming.

  3. Clean This is based very heavily on Haskell, but removes some of Haskell's problems. Downsides are that it's not very mature and doesn't have a lot of libraries.

  4. Factor Syntactically it's based on Forth, but has support for LISP-like functional programming as well as better support for classes.

Imagist
A: 

Many of your requirements are based on hearsay. One example: the idea that Mono is "terrible".

http://banshee-project.org/

That's the official media player of many Linux distributions. It's written in C#. (They don't even have a public Windows release of it!)

Your assertions about the relative performance of various languages are equally dubious. And requiring a language to not use a virtual machine is quite unrealistic and totally undesirable. Even an OS is a form of VM on which applications run, which virtualises the hardware devices of the machine.

Though you earn points for mentioning tools (although not with enough priority). As Knuth observed, the first question to ask about a language is "What's the debugger like?"

Daniel Earwicker
Yeah, I'm used to getting downvotes for supplying facts!
Daniel Earwicker
You complain about hearsay, and then supply an anecdote to counter it. You then equivocate an OS with a language-level VM, when they are very different concepts. "quite unrealistic and totally undesirable" isn't really a fact-supplying statement either.
brendan
So you're saying you haven't understood what I said at all. I'm probably going to have to live with that.
Daniel Earwicker
You might want to look up the word "equivocate". See, the free facts just keep coming, even for people who don't want them!
Daniel Earwicker
"subject to two or more interpretations and usually used to mislead or confuse", which is what you're doing to the term "virtual machine."I'd recommend you look up "fact".
brendan
Come now, it's obvious from the structure of the sentence that you meant "equate", and it's obvious from my answer that I'm drawing a comparison (which you think of as equating but mislabel as "equivocating") between the way an OS virtualises the hardware - in particular memory, the file system, the display and even the system of GUI controls - exactly as the .NET and Java VM does (and in fact there have been implementations of OSes in which those runtimes actually provide the basic OS services).
Daniel Earwicker
So it is pointless to require a language not to produce runtime code that is dependent on a rich runtime system of libraries, drivers and other 3rd party supplied capabilities. All modern languages do (where "modern" is post-1950s in the commercial computing world, and post-1980s in personal computing). And surely you must be able to see that there is a difference between the unsupported assertion that .NET is "terrible" and supplying an example of a full-featured application that runs on about eight Linux flavours and has existed for four years (or "anecdote", as you call it).
Daniel Earwicker
"Many of [my] requirements are based on hearsay"... really ? In any case, I got mostly good and instructive answers. I'll admit "terrible" was too strong, but the support for .net on Linux is still insufficient for me.
Shinka
+3  A: 

You just described Common Lisp...

Technical Bard
+4  A: 

I think that Common Lisp fits your description quite well.

1.1: Performance: Modern CL implementations are almost on par with C. There are also foreign function interfaces to interact with C libraries, and many bindings are already done (e.g. the GNU Scientific Library).

1.2: High-level and elegant: Yep.

1.3: Primarily functional: Yes, but you can also "get imperative" wherever the need arises; CL is "multi-paradigm".

1.4: Portability: There are several implementations with differing support for each platform. Some links are at CLiki and ALU Wiki.

1.5: Object-oriented, preferably under the "everything is an object" philosophy: CLOS, the Common Lisp Object System, is much closer to being "object oriented" than any of the "curly" languages, and also has features you will sorely miss elsewhere, like multimethods.

2.1: "Not-too-strong" typing: CL has dynamic, strong typing, which seems to be what you want.

2.2: Tools: Emacs + SLIME (the Superior Lisp Interaction Mode for Emacs) is a very nice free IDE. There is also a plugin for Eclipse (Cusp), and the commercial CL implementations also oftem bring an own IDE.

2.3: Garbage collected, but translated or compiled without a virtual machine. The Lisp image that you will be working on is a kind of VM, but I think that's not what you mean.

A further advantage is the incremental development: you have a REPL (read-eval-print-loop) running that provides a live interface into the running image. You can compile and recompile individual functions on the fly, and inspect the current program state on the live system. You have no forced interruptions due to compiling.

Svante
I considered Common Lisp too (see my other post) but I would say the current development tools suck. Slime is a pain to install and the user base is too small to support a lot of 3rd party software, the multi-threading is all over the place depending on what implementation you choose, etc.That's why I suggested abandoning (basically) the Linux requirement and just go for windows. If Mono isn't adequate than you can always run a VM on Linux.
Larry Watanabe
Bah. I don't know what you have been doing, but getting Slime to work is a breeze. Multithreading will require reading some manuals, but that's not unusual; there is also a lot of development going on there. There is also a nice community that you can find at Planet Lisp, the Lisp Forum, or the IRC, among others.
Svante
+4  A: 

If you like using lists for most things, and care about performance, use Haskell or Ocaml. Although Ocaml suffers significantly in that Floats on the heap need to be boxed due to the VM design (but arrays of floats and purely-float records aren't individually boxed, which is good).

If you're willing to use arrays more than lists, or plan on programming using mutable state, use Scala rather than Haskell. If you're looking to write threaded multi-core code, use Scala or Haskell (Ocaml requires you to fork).

Scala's list is polymorphic, so a list of ints is really a list of boxed Int objects. Of course you could write your own list of ints in Scala that would be as fast, but I assume you'd rather use the standard libraries. Scala does have as much tail recursion as is possible on JVM.

Ocaml fails on Vista 64 for me, I think because they just changed the linker in the latest version (3.11.1?), but earlier versions worked fine.

Scala tool support is buggy at the moment if you're using nightly builds, but should be good soon. There are eclipse and netbeans plugins. I'm using emacs instead. I've used both the eclipse and netbeans debugger GUI successfully in the past.

None of Scala, Ocaml, or Haskell, have truly great standard libraries, but at least you can easily use Java libs in Scala. If you use mapreduce, Scala wins on integration. Haskell and Ocaml have a reasonable amount of 3rd party libs. It annoys me that there are differently named combinators for 2-3 types of monad in Haskell.

http://metamatix.org/~ocaml/price-of-abstraction.html might convince you to stay with C++. It's possible to write Scala that's almost identical in performance to Java/C++, but not necessarily in a high level functional or OO style.

http://gcc.gnu.org/projects/cxx0x.html seems to suggest that auto x = ... (type inference for expressions) and lambdas are usable. C++0x with boost, if you can stomach it, seems pretty functional. The downside to C++ high performance template abusing libraries is, of course, compile time.

wrang-wrang
What about Clojure?
Robert Harvey
+14  A: 
Norman Ramsey
I do like Haskell quite a lot, and I agree with your points. I wish it were more reasonable in Haskell to intern input strings to unique symbols or ids, and then perform some pure computation on the parsed input, using the strings later in a read-only fashion. You now have a monad threaded through your whole program. Yuck.Scala can be significantly faster than Ocaml or Haskell, depending on the implementation technique. But I agree that high level, purely functional Scala tends to be slightly slower than Ocaml or Haskell.
wrang-wrang
Thanks for the answer. I might indeed take another look at Haskell's type system.
Shinka
@wrang-wrang: Gensym is always a pain in Haskell, but I think if you couple your parsed input with a mapping from UIds to strings, you can actually contain the monad within quite narrow bounds, e.g., write a pure function of type String -> (ParseTree, Data.Map Unique String) which uses a state monad internally.
Norman Ramsey
P.S. Haskell questions on SO are good :-)
Norman Ramsey
"Scala is out on the grounds that it compiles to JVM codes and is therefore unlikely to be fast enough when programs must run for days." Is this based on experience with a 1.6 JVM or based on how it used to be back in the dark ages?
Peter Recore
For example, Wrang-Wrang's first link shows scala outperforming Ocaml on the cpu bound test.
Peter Recore
@Peter: Partly on dark ages and partly because the JVM doesn't support proper tail calls, so functional programs (which do a lot of tail recursion) tend not to perform so well. See http://stackoverflow.com/questions/105834/does-the-jvm-prevent-tail-call-optimizations. My understanding is that to get peak performance from Scala you have to give up tail calls.
Norman Ramsey
A: 

Looking over your requirements, I would recommend VB on either Mono, or a virtual machine running windows. As a previous poster said, the first thing to ask about a language is "What is the debugger like" and VB/C# have the best debugger. Just a result of all those Microsoft employees hammering on the debugger, and having the teams nearby to bug (no pun intended) into fixing it.

The best thing about VB and C# is the large set of developer tools, community, google help, code exapmles, libraries, softwaer that interfaces with it, etc. I've used a wide variety of software development environments over the past 27 years, and the only thing that comes close is the Xerox Lisp machine environmnets (better) and the Symbolics Lisp machines (worse).

Larry Watanabe
+1  A: 

Take a peek at Erlang. Originally, Erlang was intended for building fault-tolerant, highly parallel systems. It is a functional language, embracing immutability and first-class functions. It has an official Windows binary release, and the source can be compiled for many *NIX platforms (there is a MacPorts build, for example).

In terms of high-level features, Erlang support list comprehensions, pattern matching, guard clauses, structured data, and other things you would expect. It's relatively slow in sequential computation, but pretty amazing if you're doing parallel computation. Erlang does run on a VM, but it runs on its own VM, which is part of the distribution.

Erlang, while not strictly object-oriented, does benefit from an OO mindset. Erlang uses a thing called a process as its unit of concurrency. An Erlang process is actually a lot like a native thread, except with much less overhead. Each process has a mailbox, will be sent messages, and will process those messages. It's easy enough to treat processes as if they were objects.

I don't know if it has much in the way of scientific libraries. It might not be a good fit for your needs, but it's a cool language that few people seem to know about.

Daniel Yankowsky