OCaml For the Masses
CowboyRobot writes "Yaron Minsky of Jane Street argues that the time has come for statically-typed functional languages like OCaml and Haskell. He cites many reasons and illustrates what he says is the most important, concision: 'The importance of concision is clear: other things being equal, shorter code is easier to read, easier to write, and easier to maintain.'"
haskell for "the masses" is possible as soon as "the masses" has a degree in mathematics. java and php are copy-and-paste languages, functional languages simply take more thinking to compile at all, and i think many programmers are not prepared to do that to the required degree, although i'd love to be proved wrong.
A pac-man clone-game should be written in this language and it should be called, "Nom Nom Nom Chomsky"!
All other things are not equal though, are they? Procedural programming is easier for humans to understand: most of us do no not think in a way that maps easily to functional programming.
I remember using it during my uni times and finding it very cool.
However it is less useful than Iteratative or OOP languages unless you NEED to use mathematics and recursion all the time, in which case its easier.
I disagree, it'll always be a niche language which isn't for 'the masses'.
Both Ocaml and Haskell can compile directly to native machine code and aren't tied to decrepit virtual machines. In particular, Haskell's compiler is written in Haskell for optimal bootstrappy fun.
Ita erat quando hic adveni.
OK, somebody posted their resume.
Python is similarly terse, and isn't statically typed. So this isn't about static typing. It's another functional programming fan.
Functional programming is a good fit to a certain class of algorithms. For the 65 programmers of a trading house, it makes sense.
Functional programming has its downsides. It tends to result in heavily nested code. It's hard to fan out results, so programs tend to be trees with a single result. Persistent state and I/O don't fit well with the functional model.
OCaml has some features that ought to be in more languages, like Djykstra's "guards" for choosing multiple alternatives.
You mean like right now? Haskell's pretty mature, and it's been able to compile to native code for years. It's pretty straight forward to talk to C (the universal ABI) with Haskell (well, as straight forward as anything is in Haskell).
OCaml has been mature for nearly a decade, by the way. Without the success it's had, languages such as Haskell and F# wouldn't be around. It also can compile to native code, and has been able to since inception.
PS, the .NET VM isn't really decrepit, it's much more performant than the JVM is. Sadly, mono isn't nearly as mature as the actual .NET virtual machine.
Request granted (at least for calling C). SML has an even nicer FFI and most certainly builds native executables.
Adhering to the platform ABI makes little sense -- the "platform" ABI on e.g. UNIX is meant for C programs and is not expressive enough for other languages (keep in mind the only types in C are bytes, half-words, words, double words, ...).
HAL 7000, fewer features than the HAL 9000, but just as homicidal!
They compile to native machine code, FYI.
Take a look at Scala collections.
Scala lists look and feel immutable, but under the covers they are really mutable to remain more performant.
Perl also has shorter code, and it's not easier to read.
Pandoc is written in Haskell, but you can download a 3MB Windows installer for it.
I have the perfect hammer.
Everything should be a nail.
Welcome to the Panopticon. Used to be a prison, now it's your home.
Huh? No it isn't. The API may most often be expressed in C, but the ABI is language agnostic.
Huh? The C standard doesn't define anything in terms of "bytes", "half-words" or "double words". In fact those terms are largely meaningless in the context of C: the standard offers very few guarantees about the width and endianess of it's native types. C didn't even gain portable fixed-width types until C99.
Syllable : It's an Operating System
TFA gives a wonderful example where the type system detects that the list function is missing one case. This is huge. This is huger can you can imagine if you don't understand what it's all about.
The problem is that we've got "programmers" that have no formation whatsoever in computer science and that play cry-babies as soon as something looking a tiny bit like some kind of mathematical notation appears. It's really, really, very sad. The list example in TFA is spot on and is simply wonderful.
This is why I think Scala will succeed.
Scala has all the advantages that the article mentions AND you can integrate and reuse your old Java or .NET code and libraries.
It's there. The tooling doesn't suck half bad anymore. The world just needs to find out.
I personally think that Scala will win over the 10% best Java programmers as soon as the tooling is comparable to Javas.
And that might happen within the next 1-2 years.
'The importance of concision is clear: other things being equal, shorter code is easier to read, easier to write, and easier to maintain.'
But there's the rub. Other things are not equal. Functional languages require the developer to approach problems with an entirely different mindset. There is a steep learning curve to really understand how they work. And I'm not talking about just the syntax. Functional languages are fundamentally different than procedural languages. Truly understanding how they work requires a lot more brainpower than procedural languages.
While it's admirable to espouse what you see to be a more elegant and "better" solution, you need to be pragmatic. Getting the millions of software developers in the world to put the effort to completely change their way of thinking just isn't going to happen. The cost/benefit ratio is questionable at best, given that a lot of people could train for a long time and still have difficulty with the basic concepts of functional languages.
Procedural languages are the norm because they're a lot simpler. Procedural languages (including "C with classes" and the like that masquerade for OOP/OOD) are useful to many more people simply because there is less to understand about how they work. It's easier for people to approach problem solution in a procedural way than it is for them to think about it functionally. And that's why functional languages, no matter how elegant or "great" they may be, will never really break into the mainstream.
"Also, the reason why, you, ... is because you don't understand ...."
So, if I find a programmer making more money than TFA author, his language of choice is perforce better than OCaml and Haskell?
Glascow Haskell Compiler:
GHC compiles Haskell code either directly to native code or using LLVM as a back-end. GHC can also generate C code as an intermediate target for porting to new platforms. The interactive environment compiles Haskell to bytecode, and supports execution of mixed bytecode/compiled programs.
Place your bets.
Deleted
APL is very concise and is famously easy to read and maintain. Oh, wait...
Quidnam Latine loqui modo coepi?
F# is essentially OCaml for .Net, so you get the full access to the .Net library. Also the best thing about F#, in my opinion, is since it is a .Net language, you can mix and match it with C#. So you can use functional approach for most part of your program, yet drop to C# when you require.
(wait, no, even better: at editing time, because you're IDE/Emacs/whatever *should* be able to compile even an impartial AST and tell you immediately that you got your types wrong).
I would like to agree with this (long ago I even work with an 'Interactive Incremental Compiler' for FORTRAN that did the syntax checking on a line by line basis as you typed). But there is a major problem - the editor basically has to include a complete, correct copy of the language compiler/interpreter in its own logic. Since most languages these days are built based on various token-tools, perhaps it would be possible to base the checking on the input definitions to those tools (sorry I can't remember what they are called.) That would be an interesting exercise, and might make it possible to build a multilanguage editor that had that capability.
Many editors (Vim, e.g.) have pretty good syntax coloring which is a good half-step in this direction. And the APL environment worked that way, and there have been others. I think languages that have adopted C-like syntax will be the last because C syntax is so ... baroque.
It's easier to be a result of the past, but more fun to be a cause of the future! http://www.spacefinancegroup.com/
F# is an OCaml variant built to run in .NET. While not 100% compatible with OCaml, many programs can be cross-compiled.
F# includes features such as units of measure (numeric parameters) and computation expressions. It has many more, those are just the ones I like most.
All my liberal friends think I'm a conservative, all my conservative friends think I'm a liberal.
We have found the problem with the software business.
Bad news: It's you and your 100,000,000 ignorant & unwilling to learn clones.
you had me at #!
Ah, and I forgot, F# 3 will have type providers, which gives you a hook into the compiler to provide types however you please. It is mostly used to create statically-typed elements from a dynamic resource such as a cloud database.
All my liberal friends think I'm a conservative, all my conservative friends think I'm a liberal.
Not sure what you mean by "native code". Haskell and Ocaml can both be compiled down to native code. What exactly do you want and is lacking in these two?
I'm no developer, and only a novice with programming and databases, so this may be a naive question.
I remember reading about Object-relational impedance mismatch. I thought, if object oriented programming is a poor fit, conceptually, with the relational database model, perhaps functional programming would be a better fit: the code leaves the management of state to the database, which is its specialty.
Does that make any sense?
My only problem with non-determinism and Prolog was that it was really hard to find where unnecessary choicepoints are. (e.g. you get the same results multiple times) Prolog could definitely use better debugging tools.
That post was a statement, not a question. The subject line was inherited. You'll need to look further up the thread to find the post to which yours is admittedly a completely valid reply.
The ABI defines how data is represented at the machine level, how functions are called, etc. The C ABI is insufficient for representing languages like Common Lisp, OCaml, Haskell, ... for a number of reasons. One is that the calling convention is not powerful enough for them, another is that it is difficult to express types from these languages in terms of the C ABI. It could probably be done, but then you'd need a lot of run time support and it would be really difficult for a human to actually call things from C. Then you have things like the stack -- SML/NJ at least doesn't even use the C control stack (opting instead to keep a list of activation frames on the heap -- this makes call/cc O(1) instead of O(N) proportional to the length of the activation chain).
As long as they provide a main entry point does it really matter?
HAL 7000, fewer features than the HAL 9000, but just as homicidal!
"Procedural languages are the norm because they're a lot simpler"
Maybe you haven't seen Scheme.
Procedural programming isn't simpler. Its popularity and mindshare (like that of say, Windows) is accidental, and needs to end for the industry to move forward. Minsky's not the first or last to point this out.
you had me at #!
The real question is, can NON-FP systems effectively leverage multicore? Functional programming has extremely powerful tools to exploit new hardware. Pthreads and explicit locking do not. Have you heard of Erlang?
you had me at #!
The Unison file synchronizer is written in OCaml.
All the fear and uncertainty coming from those who've never tried functional languages here sound just like the mobs in 1965 insisting 'compiled languages will never catch on'.
Smell the coffee. Learn something. The industry needs to change.
you had me at #!
LLVM supports the GHC calling conventions now, so it's also relatively easy to call into Haskell from other languages.
I am TheRaven on Soylent News
Are there any studies to back up the "smaller code is better" thesis? My own experience and that of many others leads us to diasgree; but our anecdote and/or sentiment is no better than theirs.
1. Quantify terseness.
2. Assign terseness value to language.
3. Quantify qualities of interest (maintainability, etc.).
4. ???
5. Science!
For all intensive purposes, "whom" is no longer a word. That begs the question, "who cares"?
Well, if a thousand unbelievably crappy, unstable, and resource-inefficient erlang programs hit the streets in a couple of years, I'll know it wasn't actually the Java language that was the problem after all, it was the Java programmers. Which is what I suspect, frankly.
Eventually, all languages become individual CPU instructions. That's the level that the machine ABI deals with.
Yes, very very much. Even defining enough of an ABI to even get to the executables entry point is a pretty big task!
Syllable : It's an Operating System
Sorry, indeed realised after posting. I'm still surprised about the original parent's statement though (.net and JVM in relation to OCaml and Haskell??)
Are you aware that there is a State object in the Haskell library just to represent mutable objects? There's nothing in functional languages preventing you to handle state, not even in the purest ones, at least since the application of monads to programming.
With monads you can create sequences of pseudo-imperative actions ("do blocks") that behave like a language with mutable states, but where the only possible side-effects are the ones you have previously embedded in the monad declaration; every other side effect is logically impossible.
Basically a monad is an implementation for an imperative micro-machine that handles one particular type of state changes. What this buys you is simplifying the number of cases you have to take care of (you avoid race conditions, exceptions thrown by rare cases in the input data...)
The cost for it is that you must know what you're doing - you have to know how to create a miniature programming language, so it's not a job for the typical java copy-paste-debug programmer.
Singularity: a belief in the "God" idea with the "demiurge" relation inverted.
Functional languages are good for inplementing algorithms and imperative languages are good for handling data. It happens that in most real-life situations we need the latter.
I have no experience in functional programming languages, so I'm curious to hear from those who have developed real applications. How does functional programming do when having to create UIs? Or reading/writing to a database and dealing with transactions? Or creating a web-service? Or enforcing business logic?
Functional programming seems ideal for writing algorithms, but does it have any drawbacks?
The common ABI of all platforms in wide use today were designed only with C in mind (extended slightly, in an incompatible manner, to support C++). If even C++ cannot link directly with C, why would Ocaml et al have to? These things have their own internal binary interfaces and so I don't see what the problem is. The lack of a shared library format?
HAL 7000, fewer features than the HAL 9000, but just as homicidal!
The guy started his career writing in VBA and moved to OCaml via Java. Is it any wonder he finds OCaml so great?
Now you're talking about language ABIs, which is a different matter entirely. How Haskell or OCaml or C++ handle one function calling another function within the same process is entirely up to the language designer. That isn't anything to do with the platform ABI.
Externally however, you have to conform to the platform ABI because you have to run on the platform. The platform ABI is language agnostic. There is absolutely nothing C specific about the x86-64 ELF ABI, for example.
Syllable : It's an Operating System
Sooo...shorter code that is identical to longer code, except for length, is better? I don't think it is possible to change length and hold everything else constant. Even if you could hold everything else constant, separating code into sections that are actually longer than a more compact form can be more readable. Longer code can be easier or harder to read, easier or harder to maintain, and easier or harder to write. The only conclusion that can be made is: It depends.
Take a look at any functional programming language implementation for the last 30 years. The same is true. Something Scala and Ruby have in common: they both claim decades old ideas are new and exciting.
I am TheRaven on Soylent News
Our main application (LexiFi Apropos) is almost entirely written in OCaml. Some years ago we had kernel algorithms implemented in OCaml and some GUI + business logic in C#, and we decided to switch everything to OCaml. We are very happy about this choice.
In my opinion, the most important language features that exist in OCaml (and Haskell, etc) and which are still missing from mainstream languages are sum types (tagged union with parameters) and pattern-matching. Honestly, I don't understand why such powerful and simple constructs are still reserved to functional languages... Probably the bad heritage of C-like languages where you can easily multiply types (structures = product types) but not add them (sum types). Addition is as basic as multiplication!
Then I could cite various means that OCaml offers to factorize and share the code: structural objects, functors, first-class modules. These are great and really allowed us to reduce the size of our code base and increase its maintainability a lot.
For the UI, we use CSML which is a kind of high-level FFI between OCaml and .Net. We use directly the Windows Forms API from our OCaml code as we would do from C#. On top of that, we have developed higher-level layers to facilitate GUI development. In particular, we have some libraries to generate automatically entry screens from OCaml type definitions (see http://www.lexifi.com/product/technology/automatic-generation-of-user-interfaces).
Same for databases: we use exactly the same low-level programming model as we would do it we were programming in an imperative or OO language (OCaml is imperative and OO, btw). On top of that, we have an ORM again based on OCaml type definitions. Nothing really specific to functional programming here.
As a mathematician, TFA's argument appeals to me. Types made up of disjoint unions and Cartesian products, type inference (which, incidentally, mathematicians often do implicitly: eg. let f(x) = 1/x; it's implied that x is real and non-zero), pattern matching--these are all things I'm used to and even enjoy. That doesn't sound promising for widespread adoption, though. For all its power, most people hate math, and something this math-y has a serious hill to climb. That the author simply assumed his readers would have any idea what a disjoint union is (see the set theory definition for his usage) is a great example of the article's lack of realistic consideration of who "the masses" are.
If you want a programming language to gain widespread adoption, you really only have one option: allow the programmer to think less than they have had to in the past. Migrations from C to C++ to Java to scripting languages like Python all progressively took care of more and more details for the programmer--organizing objects, hiding pointers, doing automatic garbage collection, and getting rid of static types, to name a few. Does using OCaml allow you to think less than using another modern language? Almost certainly not. Therefore, the language will not gain widespread adoption "for the masses".
That said, some higher-end coders could probably benefit from using functional languages more often. They're certainly beautiful and powerful in the right hands (while in the wrong hands they're just confusing). Perhaps that's all the author really meant to advocate--that competent people check to see if a functional language they might otherwise ignore is a good fit for their problem.
If you got em -- smoke em.
Truth is stranger than fiction, but it is because Fiction is obliged to stick to possibilities; Truth isn't. Mark Twain.
An OCaml example from The Fine Article: (both of these do the same thing)
let map f (x,y,z) = (f x, f y, f z)
Here, map is defined as a function with two arguments: a function f and a triple (x,y,z). Note that f x is the syntax for applying the function f to x.
Now consider what this would look like in C# 4.0. The C# code, while functionally equivalent, looks cluttered, with the real structure obscured by syntactic noise.
Tuple<U,U,U> Map<T,U>(Func <T,U> f, Tuple<T,T,T> t)
{
return new Tuple<U,U,U>(f(t.item1), f(t.item2), f(t.item3));
}
And this isn't just to harsh on C#, the next example shows 15 lines of OCaml sized up against 50 lines Java
(or, if you strip whitespace, 258 chars of OCaml vs. 1,124 chars in java).
Somehow TL;DR doesn't apply to code? Maybe our species is irreparably stupid.
Prove it's better with objective metrics and real-world scenarios FIRST. Being "elegant" or "cool" or "clever" doesn't necessarily result in "better". We're just asking for the scientific process: test, measure, repeat, and document. Programming hasn't made science obsolete, has it? (I've heard some interesting arguments that it has, but that's further along the flame-war curve :-)
Table-ized A.I.
Should be fixed now!
This c# code is stupid. 3 elements of the same type would be in an array not a tuple and would then read fine
Ok, we were actually having an argument about different things ;)
ELF is a separate concern — I do agree that it would be nice if binaries from other languages were encapsulated in ELF more (Guile Scheme has made motions toward this). You can already do things like dump Common Lisp binaries that include a minimal C bootstrap runtime. Getting more than a main entry point so that they can be run as programs, however, is one of those really difficult things — the C language ABI is basically mandated.
HAL 7000, fewer features than the HAL 9000, but just as homicidal!
Unfortunately for those who like cross-platform languages, OCaml is well behind F# in a couple of areas:
1. Toolchain - getting a simple OCaml program to compile is horribly complex involving various separate tools such as omake, ocamlbuild, ocamlfind, etc - there is no one way to do things and it's really hard even for someone used to building open source packages in many languages (I've built KDE in the past which uses CMake but did work OK)
2. Integration with other languages - see this tutorial for the various issues to be covered: http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php - and this for the build sequence: http://stackoverflow.com/questions/2807021/compiling-c-lib-and-ocaml-exe-using-it-all-using-ocamlfind/2809086#2809086
I think OCaml is a very impressive implementation and language, and is one of the few languages which can compile to real machine code with performance competitive with C, yet at the same time provide the productivity of a much higher level language such as Python, Ruby, etc. For heavy computation on limited hardware where the right third party libraries exist, it can really work well. But the OCaml community needs to make it easier to get started....
There are already quite a few projects making use of Scala, Clojure, Erlang, F#. Ocaml and Haskell tend to not be so used as the former three.
One small thing that might disklike Microsoft bashers is that F# is developed by Microsoft and Ocaml and Haskell communities do have quite a few developers employed by Microsoft Research.
I use Haskell for personal projects and use C at work. The reasons I use Haskell when I have a choice is that a) I like the typechecker to catch my mistakes, b) the language is performant enough for what I want to do, c) I can get a lot done with not very much code, d) the language is aesthetically appealing and e) using Haskell is fun. If "d" and "e" were the only reasons, I wouldn't use Haskell. I'm lazy, and if I just want to get something done, I'll usually do it the easiest way I know how. For many problems, Haskell is the easiest way I know.
I don't expect people who haven't used Haskell to understand this. I didn't, until I had used the language for awhile and found to my surprise (writing my first large Haskell program) that restricting file access to the IO monad not only didn't restrict me in any significant way, it actually made the design of the program cleaner than what I would have come up with had that restriction not been in place. "Clean design" may sound like an aesthetic issue, but for some reason cleanly designed programs seem to consistently work better than programs that aren't cleanly designed. (I'm not claiming that writing in Haskell is the only way to achieve clean design, just that the language seems to encourage it.)
Some programs I've written in Haskell are the glome raytracer (available on hackage), a web-app, and an environmental simulator. I would consider these, if not "real world" programs, then at least representative of real world programs. I could have written them in other languages... but I didn't. Glome is the most complicated piece of software I've ever written by far (meaning that it does a lot, not that is internally complex), and I don't think it's a coincidence that it was written in the most powerful language I know.
This c# code is stupid. [...]
Exactly!
I'm surprised the article talks about C# but not F#, which is an Ocaml-like strict functional language running on the .NET runtime. The F# compiler was made free software a year or so ago, I believe.
-- Ed Avis ed@membled.com
I call gotcha reporting!
'Just saying, these are very useful tools - but lack some of the elegance that makes OOP work (misuse of multiple inheritance aside). Some of the design principles that make OOP so great just aren't as readily applicable in functional languages, so while I think they're cool - I'd just assume something more robust mature out of them over time before I adopt them full time.
I remember learning it in university in the 90s, I didn't really understand it :)
"Science will win because it works." - Stephen Hawking
Functional languages, particularly LISP and Haskell, have one advantage that I like: I can design programs that do ONLY what I want them to do. On my last couple projects my main problem was covering all wanted program behaviors, because if I left it out the program simply died elegantly and told me it couldn't do what I asked. (These are control programs, not learning programs.)
Of course, this has resulted in my finding a myriad of bugs shipped with manufacturer's devices. I have had to replace PROMS and drivers that were not well designed. The accumulated error count from one component to the next is truly scary! It is no wonder that control software (Utilities, SCADA, sensors, etc.) is such a good target for destructive hacking.
"The mind works quicker than you think!"
No. It is just OCaml by Microsoft ...
But this article states: "Make no mistake: Java/C/C++/C#/Perl are much worse than OCaml! " And contains many mistakes. It has been written especially to feed trolls ... Without any convincing argument.
It easy to take some very special issues and conclude that something sucks ...
You can do this for everything.
Well ... This article precisely tells that OCaml is used by companies ...
And they never want to go back to other languages ...