20 hours of Computer Science lectures focusing on teaching you how to think like a programmer and solve problems using computation. One of the best introductions to programming I’ve seen.
Extract from Fred Brooks’ book, The Mythical Man-Month. One of the best explanations why programming is so interesting.
Most Recent Articles
Stack Overflow has a good post on which languages (or rather Stack Overflow tags) are used mostly during business hours, and which are used at night.
tsql, SharePoint, Java, etc. are used during the day, and Haskell is the clear favorite among night owls.
Haskell often catches flak for “being a hard language to hire programmers for.” This data suggests that, while there clearly aren’t as many Haskell programmers, many of them use it recreationally out of interest, not because it has the potential for a high salary. Such people would likely jump at an opportunity to do similar things during the day.
Would you hire such a person?
I just… I don’t even. Tom Wildenhain demonstrates how PowerPoint can be used to do general-purpose computation, leaving people pondering the question, “Will it be the next cool language after Go and Rust?”
There is even a paper.
If you want to get a job as a software witch, you’re going to have to pass a whiteboard interview. We all do them, as engineers–often as a part of our morning ritual, along with arranging a beautiful grid of xterms across the astral plane, and compulsively running ls in every nearby directory–just in case things have shifted during the night–the incorporeal equivalent of rummaging through that drawer in the back of the kitchen where we stash odd flanges, screwdrivers, and the strangely specific plastic bits: the accessories, those long-estranged black sheep of the families of our household appliances, their original purpose now forgotten, perhaps never known, but which we are bound to care for nonetheless. I’d like to walk you through a common interview question: reversing a linked list.
First, we need a linked list. Clear your workspace of unwanted xterms, sprinkle salt into the protective form of two parentheses, and recurse. Summon a list from the void.
Such begins the first of a series of witty posts on the black magic of technical job interviews written by Kyle Kingsbury:
Excellent point by Lucas Di Cioccio that social media makes Haskell seem much harder to learn than it really is:
It’s perfectly possible to be productive in Haskell without understanding anything about monads!
It’s true. If you have to think about the types of your values when you are writing your program, it will take longer to write, especially in languages where type inferencing is weak or non-existent, forcing you to constantly redeclare the types of values the compiler should already know about. Typing those characters takes time, even if you’re using keyboard shortcuts and code generation tools!
So what’s so special about type inferencing anyway? Let’s take a look at some Haskell to illustrate:
respond :: String -> String respond s = "(╯°□°）╯︵ " ++ reverse s
Here, the first line is a type signature indicating that
respond is a function from
String (the input) to
String (the output.) The function body reverses the input and appends (
++) it to somebody with anger management issues. When run, it works as expected:
> putStrLn (respond "sounds like somebody has a case of the mondays") (╯°□°）╯︵ syadnom eht fo esac a sah ydobemos ekil sdnuos
In Haskell, type signatures are generally optional because the compiler can infer the relevant types without help from the author. That means this version of
respond is the same as the above:
respond s = "(╯°□°）╯︵ " ++ reverse s
In Python, this can be written as:
def respond(s): return "(╯°□°）╯︵ " + s[::-1]
which works the same:
>>> print(respond("sounds like somebody has a case of the mondays")) (╯°□°）╯︵ syadnom eht fo esac a sah ydobemos ekil sdnuos
So Haskell and Python are the same, right? Yes.
Wait. No. There’s a difference.
In Python, if we start speaking in numbers, weird things happen:
>>> respond(6174) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in respond TypeError: 'int' object has no attribute '__getitem__'
When we call the
respond function with a number, we get an error. Python has realized that it’s trying to treat a number like a list in order to reverse it, and shuts everything down until it can figure out what the hell is going on.
“Hey! You just said Python and Haskell aren’t the same, but Python has inferred that it’s an int! Also your memes are making me very upset.”
Python didn’t so much infer the type as trip over itself. It’s true that Python figured out that it was trying do something invalid on an int, but it did so at the very last moment, at which point it can only throw an exception in response.
BEHOLD THE ARCANE MAGIC OF HASKELL, SAVIOR OF MANKIND
-- respond.hs respond s = "(╯°□°）╯︵ " ++ reverse s main = putStrLn (respond (6174 :: Int))
Let’s compile it:
% ghc -o respond respond.hs [1 of 1] Compiling Main ( flip.hs, flip.o ) flip.hs:5:27: error: • Couldn't match type ‘Int’ with ‘[Char]’ Expected type: String Actual type: Int • In the first argument of ‘respond’, namely ‘(6174 :: Int)’ In the first argument of ‘putStrLn’, namely ‘(respond (6174 :: Int))’ In the expression: putStrLn (respond (6174 :: Int))
“This is not useful at all, you are just demonstrating the basics of static vs. dynamic typing. In statically typed languages, type errors are caught at compile time, and in dynamic languages at runtime. Everyone knows this.” — Michael Scott
Ehrm. Excuse me.
It’s true that the Haskell compiler simply knows the program’s types at compile-time and can output an error, but notice that we never said we expected a string in this program. That was all inferred from the first argument to
(We did state that
6174 was an
Int. Nobody knows why we had to do this. Archeologists believe the answer was lost with a clan of highly intelligent synapsids that went extinct at the end of the Triassic period.)
Because Haskell has a powerful inferencing system, we can write whole programs, without any type annotations, that are statically checked at compile time:
-- program.hs respond s = "(╯°□°）╯︵ " ++ reverse s addTwo n = n + 2 snipSnip xs = tail xs main = do putStrLn (respond "salmonatus quichen!") print (addTwo 8) print (snipSnip "<o>") -- you're gonna lose that arm!
% ghc -o program program.hs % ./program (╯°□°）╯︵ !nehciuq sutanomlas 10 "o>"
Mom, where are the types?
This program will compile and run just fine, but supply
addTwo a string or
respond a number and you’ll be in big trouble. Big.
Now imagine you have over 9,000 functions that are all statically verified like this, and you put them into a tube. That means you’d end up with a very long tube. Also, no part of the tube would be broken—now or after making modifications.
Anyway, yeah, so the point or whatever is that while dynamic languages require very little thinking about types, they make no effort to try to validate that your program is actually correct. It is faster to develop applications with them because you don’t constantly have to declare (or even know) what types you are working with. However, much frustration with static types comes from the verbosity of the implementation of various programming languages, not from static typing itself. It is possible to get the benefits of static typing (programs compile until they are no longer correct, rather than run until they try to do something horribly wrong) without having to actively think about or annotate types.
(In fact, many users of statically typed languages like Haskell choose to type out type signatures, but as a sanity check on themselves, not the compiler, and as documentation. They don’t have to.)
When the negative mental overhead usually associated with static types is avoided, they can greatly reduce the number of error conditions your program can encounter, reduce the number of tests you have to write (because even though there can be logic errors, there are simply a large number of things your compiled program can’t do incorrectly, so why test for them?), and even make you enjoy thinking about them (creep.)
Interestingly, learning Haskell gives you ideas that can be applied to other programming languages in order to address issues like lack of typechecking. Even if you don’t use Haskell, learning it helps you write programs that are safer, more maintainable, and faster, not slower, to develop.