This brief history of Haskell is a nice introduction to how Haskell has developed. Jones tells a nice story punctuated by seminal publications that contributed to the ideas. He is a living example of how well the Cambridge accent was designed for giving lectures.
Some programs work but are not well-typed. That is, they are the programs that you want to write but the compiler rejects them. So this is the "Region of Abysmal Pain". Because that's where you think: "Ugh! The type system is getting in my way! I know! I'll use an untyped language."
It is very refreshing to hear someone straight from the top of the static typing pantheon acknowledge the pain of working with current, statically-typed languages.
Now, of course there's always going to be a small Region of Abysmal Pain. There's rather a sort of sterile debate that happens between the static and the dynamic crowd. But I just want to remark that there's something not just self-indulgent but I think is actually quite important about the process of trying to find ways of making types more expressive so that they maintain the good property of being somewhat comprehensible and while moving closer to writing programs that you really want to write.
Alright, so here's our plan for world domination: make the type system sufficiently expressive to the point where everybody will forget dynamic languages and write statically typed ones. I don't expect that will happen to me in my lifetime. But I regard Haskell as a kind of thought experiment that's trying to go in that direction.
In the end, I think Simon Peyton Jones is the perfect mix of humility and hubris to lead the Haskell movement. He seems to have the patience to work with (and be excited about) an incomplete language (as Haskell was in the early days and still is in a lot of ways) without being dogmatic about the virtue of the current limitations.
Thanks for this curation of Google Web Fonts. Despite Google Web Fonts' excellent UI, I still have trouble finding the gems.
This is the best video I've ever seen defining monadic parser combinators from the ground up. Nate Young explains his translation of Parsec into Clojure. I'm surprised he could show the code and explain it well in less than forty-five minutes.
As you may know, I have my own PEG parser combinator library called squarepeg. I began developing it as monadic, but decided that I didn't like having to write my own version of Haskell's do notation (let->> in his version), which felt awkward in Clojure. Instead, squarepeg lets you bind variables and refer to them later within each parser itself (instead of in the code that builds the parser). There were a few other differences, but in general, I think the two libraries are more similar than different.
One thing I think I will borrow from his library is counting the character position of the current parser to help report parsing errors. It's going on my TODO list.
I have more plans for squarepeg when I get a chance. They include limiting the laziness of the parser and being able to report better error messages.
Update The kindly Sergey Pariev clued me into the github repo of The Parsatron.
Simply amazing.
I tried to build a small project using ClojureScript and gave up, reverting back to Javascript. The workflow was awkward and information about the language was lacking. ClojureScript One aims to exemplify the power latent in ClojureScript by giving us a productive workflow from the very start. You clone the repo and use it as a starting point for your own project.
I haven't explored this new project, but it is already impressive. It sets a high bar for new projects. It includes a well-designed home page, getting started videos, and nice documentation. But, more importantly, it hints at a new age in web development in much the same way as the Blog in 15 Minutes Ruby on Rails video ushered in the rise of Ruby on the web. Watch the ClojureScript One Getting Started video to have your mind blown.
I also recommend a podcast about the goals of ClojureScript One.
If you are reading this, you are probably a programmer. Let me ask you, for just a moment, to step out of your programmer shoes and answer these questions:
- Is this apple equal to that orange?
- Is that cloud equal to this house?
- Is my backpack equal to my television?
The obvious answer is "no" to all of these. And so (please step back into your programmer shoes) we see in many languages I can ask a similar question:
In Java:
apple.equals(orange)
Or in Clojure:
(= apple orange)
The answer to both questions is unsurprisingly false.
And in Haskell?
apple == orange
Type error! The compiler is saying I cannot even ask the question.
What model of reality is Haskell asserting?
Is it telling me that I need to convert the apple and orange into values of the same type?
Fruit {name = "apple"} == Fruit {name = "orange"}
Is this question really different from apple == orange?
Which model (Haskell's or Clojure's) more closely models reality?
Is this behavior intentionally designed into Haskell or is it incidental behavior due to the choice of type system?
Does this behavior make Haskell better or worse than a hypothetical Haskell that allowed the question to be asked?
Deep questions.
Paul Chiusano:
In the functional programming world, there is insane amounts of code reuse happening, but along with this comes a fair bit of plumbing.
The plumbing Chiusano is referring to is incidental complexity imposed by current static type systems without a good set of "universal" types. Dynamically typed languages often do not have the same plumbing problem because of the extra information available at runtime to do dynamic dispatching and the use of overloading. This incidental complexity is a huge hurdle to languages like Haskell, where half of the code is about converting from one type to another.
This could be the fault of the codebase/libraries I am working with. In my practical Haskell experience, I have failed to find the zen of type/domain fit that static-typing enthusiasts talk about. Chiusano, however, hints that this problem is universal.
It makes it clear that types are effective not just at preventing many software errors, but also in guiding development.
I would love to see the adoption of standard type classes recognized by the Haskell compiler that could automatically handle the most common coercions safely. For instance, the compiler could "upgrade" function application to Functor application when the types match. It is beyond me whether this can be done "safely". I suspect that it cannot.
The second is to have more normalized types and type systems so that there is no incidental structure for code to broker between in the first place. To support this we'll see things like row types, unordered tuples, type sets, and so on, and any related type system machinery needed to make all this feasible and convenient.
If modules were programmed to a small, standard set of types (and type classes), they would be more universally applicable. The compiler could "overload" functions automatically. The trick is to keep it safe. At the very least, the "universal" types would help programmers do it manually. We may already be seeing such a convergence.
Not coincidentally, the built in Clojure data structures are usually all I need. Others appear to think the same. The Clojure ecosystem thrives from the consensus on a small, universal set. There is a lot of reuse and little boilerplate.
See Ring as an example of a universal datatype facilitating a flourishing community. It allows the problem domain (web programming) to be broken up into subproblems with little-to-no coordination between the groups. Clojure has a number of web frameworks and libraries that are all inter-compatible. I think this is unique among languages.
The editor will search for a program to make the types align, show me the program for confirmation if I request it, and then not show this subexpression in the main editor view . . .
Please give me this editor. It is technically feasible. Hoogle can already do a pretty decent search based on the types of functions. All you need is a planner to find a path from one type to another.
You could even help the search by defining a type class Convertible like this:
class Convertible a b where
convert :: a -> b
All of the instances of Convertible would form graphs which could be searched for all paths between any two types. The editor could show a list of those paths and let you choose one.
A great Alan Kay-esque speech (by none other than Alan Kay himself).
Alan Kay is a great thinker and I always enjoy his talks, but he needs someone to refine his presentations--particularly his verbal explanations. There are lots of great ideas and perspectives, but mostly he is just saying that "we're doing it wrong". Much better would be to show us his analysis of a problem.
In general, I finish his presentations feeling like everyone is doing everything wrong but with no concrete steps to take to correct it. We are thinking wrong (we need better perspectives), we are programming wrong, we are engineering wrong, we are learning the wrong things, we are doing computer science wrong, etc.
I also finish thinking that a new and better way is possible, but again, with no idea of that better way except a vague notion of less and better code in less time.
And then here I am, trapped in a world of crappy computers and crappy thinking, with a feeling of unease. I wish he would come down to Earth a little and apply that big brain with its great perspectives to a problem on-camera. It would be concrete and I could learn to emulate his thinking.
An insightful talk from Internet activist Cory Doctorow about the future of the freedom of computation.
David Nolen speaking at Strange Loop:
How much of Computer Science is sitting around when I'm sitting and working on a problem?
David draws on some of the giants of Computer Science in recent years. Alan Kay, Gregor Kiczales, Peter Norvig, and more. I love to see the products of great minds folded into Clojure and ready at my fingertips.
core.match and core.logic are now on my reading list.
Kris Jordan:
Inspired by Clojure's multimethods, multimethod.js provides a functional alternative to classical, prototype based polymorphism.
multimethod.js builds functions which dispatch on arbitrary predicates in Javascript using a fluent style.
Multimethod iterates through each 'method' registered with when and performs an equality test on the dispatchValue and each method's match value.
I wonder whether a linear search for the dispatch value will scale. I prefer to see some kind of hash-map based solution. Is it possible to serialize the object to JSON and use the resulting String as a key?
Still, I enjoy seeing inter-language cross-pollination. It is also a nice translation from a functional language to a prototype language. The fluent interface does the job extremely well.
Kris Jordan deserves a follow on GitHub.