Haskell discounts the very useful choice of reasoning about your code after it runs, favoring, instead, all-upfront reasoning, often at the expense of facilitating the former. There are some domains where figuring everything up front is very important. Others, where trial and error is far more productive.
Trying unfamiliar things is very good advice, but not for an important project you want done relatively quickly, and which you'd have to maintain for years to come.
Huh, I have never thought about it like that. Thanks.
For server-side rendering of fat web clients, I don't see any way around node.js and my resentment of javascript without doing some impressive design of the client to be able to reinitialize itself from a JSON that pops out of the client state in the host language. It's possible, but I'm too busy with Kivy to mess with web development atm.
I used to be a bench chemist in a pharmaceutical company and the tools we used to develop new drug candidates and the tools we used to put them into mass production were radically different. I don't see why software should be any different. Let Haskell be the proving ground for new ideas and we can cherry pick the best ones for simpler languages later.
This is a very interesting observation. I would hazard a guess that Phil Wadler developed (or at least significantly contributed to proving type-theoretic soundness of) Java Generics and Collections after they sort of proved their worth in Haskell world.
Same with Lambda which made its way to Java 8. STM is perhaps next.
I would say that adopting a language for the next 10 years that doesn't have purely functional data structures at its core is a fool's errand.
Persistent data structures, i.e. efficiently storing every version of your data structure, is the natural reflection of the new reality in computing where:
* storage is cheap
* random reads are cheap
* random writes are expensive
* serial writes are cheap
Whether you adopt this through Haskell, Clojure, scala or even Bloom e.a. is fairly inconsequential.What will matter is that persistent data structures will inevitable become commonplace over the next decade and that techniques for leveraging it (such as functional reactive programming) will be adopted in one form or another.
@jacquesm: I live in Amsterdam so I can try to explain it to you in person once; virtually everyone still underestimates the impact this will have and (or perhaps because) it's very difficult to get that across in writing.
Besides your listed reasons mutable state is becoming a bigger and bigger bottle neck as the number of cores goes up and that's why functional programming is becoming more and more important. It also makes programs much harder to write in a bug-free manner and it makes testing much more difficult (if not impossible).
It's one of the core reasons why I felt so bad about dropping Erlang from the list because I feel that it gives me that plus a battle tested environment to work with.
Still tempted to put it back in. Your reasons add weight to an already very difficult decision, whether or not to pursue this opportunity as a way to get more into functional programming or to stay in my 'comfort zone'.
I've been toying around with FP on and off for the last couple of years and it is one of the most important revivals the computing world has seen to date (imo of course).
Finally, I must say that while Scala does indeed have a first-class web framework in Play, web frameworks are first-class objects in Clojure. Joke. Sort of. I personally do not want to have a monolithic pre-packaged web framework to bow down to; the Clojure community is a community of hackers, we like to make things out of other things, and to take things apart. Clojure and the work of its community allows me to compose my own web framework as needed very very quickly–and to drastically change it just as fast. I'm not saying you should stop doing what you like to do, but if you gave Clojure a chance...dude: it's addictive.
The code I write now is nothing like Java, but it's a question of how you get from there to here. When I started Scala I wrote what I'd write in Java. In the first week I removed the semicolons. In the second week I started to use function literals. Then I started using match/case. Later I found out about for/yield with futures. And so on. I learnt the language at my job, and I was delivering real, user-facing features in it from day 1. I don't think I could've done the same with Clojure.
(Reasonable people can disagree on syntax; I find that Scala's lets you get very close to the language of the domain (e.g. see the Spray "routing DSL") and that's worth the cost it imposes on the macro system)
Also, sometimes you want your updates to a data structure to be seen via an alias (happens often actually), then we are back at square one again.
Systems people are much more pragmatic about this: they see the trends in hardware before we PL people do, and their solution has never been functional programming. Ok, well...maybe once with MapReduce (but Jeff and Sanjay are both systems PL people).
Adopting it successfully does require separating essential from accidental state which naturally leads to some variant of FRP being adopted to manage (re-)derivation of accidental state; which is usually the hard to explain part.
I am wondering what you do see systems people doing by the way? I'm always interested in broadening my perspective on this.
The systems people I work with do a lot of key value stores (sharded NoSQL-style databases), there is a lot of pipelining for data parallel processing (MapReduce, Pig), and there is still a lot of classic locking going on, throughput is important. Oh, and lots of Paxos, logging, state replication, etc... The normal stuff you could find at Google (note I don't work for Google).
On the HPC side, the people that really care about performance, there is some map reduce via MPI, but most of the big gains are to be had in CUDA, which is an extremely imperative programming model with very synchronized core executions and memory accesses.
I've learned that whenever the FP people talk about high performance, they usually mean something else (like concurrency that isn't so slow), rather than the real high performance stuff that the big kids (systems and HPC communities) are doing.
The reality though is that well over 99% of the market works with data sets for which, with current hardware, the performance costs of these persistent data structures are very much irrelevant.
When you add FRP on top of that so that you can keep your managed state minimal you can actually often achieve quite dramatic performance improvements over the traditional hand-written data-to-UI synchronisation.
For persistent data structures to come into their own for big data quite a few more things are needed of course; but if you look at Nathan Marz's Lambda Architecture for example it's little more than a handwritten system for making large scale persistent data structures manageable with today's systems already.
I'm fairly sure that tooling for that will only improve over time until the very thought of manually managing derivation pipelines becomes as quaint as manual memory management.
As for HPC; yes... I would not be surprised at all if at that level mutable state no longer is a premature optimization. Even there I could imagine many of the more high-level control structures benefitting from persistent data structures though.
About the FRP part; which competing paradigm are you working on? I wouldn't be able to name a 'competitor' so I'm quite curious.
Yes; the managed time approach in Glitch is very interesting and indeed a competitor towards addressing the same problem I originally raised.
The core of my original statement/problem definition was that real mutable state, i.e. throwing away history by default, was no longer the smart thing to do given current hardware.
From what I can tell you would also agree with that...
Why is it hard to get across in writing?
a) it requires putting together a fairly large number of concepts of moderate complexity (and you never know which ones your readers already understand.)
b) many of the concepts sound trivial and people usually don't grasp their power until you've listed X amounts of things it would enable.
And to be clear; it's hard for me to put in writing for now ;)
Look at Python: The only reason people started to use it is because of the syntax. Now it's slowly eating Matlab and R in science - two specialized languages beaten in their own domain by a general purpose one because the general purpose one has nicer syntax.
How great wouldn't it have been to have a Haskell-like language with a Python-like syntax? But no, Haskell needs a "first-class syntax", as if keystrokes are the limiting factor in development.
I've seen this criticism before, and I don't understand it. The syntax of Haskell is not that big. There are some things a bit funky about it, especially the indent rules, but I don't see what there is to be mystified about.
On the other hand, it does introduce a lot of mind-bending concepts if your background includes imperative programming and no category theory, and that's typically what people find hard to grok. You don't find a pile of "Haskell syntax cheatsheets", you find a bunch of monad tutorials instead.
http://stackoverflow.com/questions/7746894/are-there-pronoun...
http://www.haskell.org/haskellwiki/Pronunciation
plus any more potentially introduced by any libs, or whatever else. When I see any Haskell code, I feel that I trip on those every time. And among them, especially confusion between: -> => <- -< >>= >>
Neither is APL's syntax.
Too much operator overloading is just a bad idea.
But one thing where Haskell errs, in my opinion, is in allowing arbitrary infix operators with random ASCII characters, which library maintainers take as an encouragement to each create their own DSLs which totally makes sense to them and nobody else, but that's not the same thing as saying that Haskell-the-language has a huge syntax. Maybe that's what you mean.
Another quick way to measure this - compare that beautiful pseudo quick sort to real quick sort (e.g. using Array.ST)...
(And if you're going to use Play, Scala is very much the best way to do so)
In most languages I have learned I've generally reached a point fairly quickly (without hours) where I've thought "wow - this is cool!" and this is generally because of enabling me to do something more easily than in other languages - I've never got to that point with Haskell.
Note - this is just my own observation, not a criticism of Haskell or any of the resources I have used to try and learn it!
In any case, I'm definitely not smart enough to use it. The issue isn't functional programming, though, which is why Elixir looks very interesting.
Given I have been working with web development in Ruby and PHP for years, I would love to find a nice "getting started" guide for a good/well established Haskell framework.
It also comes along with a free online book: http://www.yesodweb.com/book
Other popular alternative is Snap framework.
Haskell is not only for surpassingly intelligent people, or even optimized for them. If anything, it's the opposite: one of its core tenants is that we're not smart enough to reason about our programs in most languages. Much of the design work focuses on unloading complexity into the language, tools and abstractions.
Haskell goes out of its way to prevent common errors and help you design your program. In a very real sense, it trims the "search space" of possible programs, helping you zero in on a reasonable solution. To an extent, I use Haskell because I'm not smart enough to use C.
Haskell is unfamiliar. And people mistake that for some sort of innate difficulty. But the two are not the same.
I would argue that overcoming unfamiliarity is one of the most important ways to grow as both a programmer and, more generally, a person. That's why I think the article focuses too much on choosing a language that's familiar, codifying it as "just about all the good advice". This mindset is far, far too exaggerated in most programmers, and its what really slows down progress, especially for popular programming languages.
The blub paradox is also a bit misrepresented. Being a "blub" programmer is not a matter of being more or less intelligent—it's a matter of not knowing what you're missing. "Beating the Averages" is not "we used Lisp because we were smarter than you"; it's more like "we used Lisp because it offers some incredibly powerful tools that non-Lisp programmers have never used and so do not really appreciate". It's a matter of habits and experience, not intelligence.
My advice? Do try something unfamiliar. Especially if it seems to be higher in the great partial order of programming language power :).