C9 Lectures: Erik Meijer - Functional Programming Fundamentals

C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals, Chapter 2 of 13

Download this episode

Download Video


In Chapter 2, Dr. Meijer introduces Haskell syntax and notation (via a Haskell implementation called Hugs, to be precise, which is based on Haskell 98) and we learn about the Haskell syntax that represents the fundamental construct of functional programming:
functions. It's not like you're used to in mathematics like f(x). Instead, in Haskell, a function is denoted without parentheses:
f x. So, given the almost OCD requirement by Haskell language designers to eliminate
any unnecessary clutter in the language, parentheses are replaced by space. Also, in mathematics, you're accustomed to multiplication expressed either as xy or x y. In Haskell, since space denotes a function, multiplication is denoted with a *, like

You should watch these in sequence (or skip around depending on your curent level of knowledge in this domain):

Chapter 1
Chapter 2
Chapter 3
Chapter 4
Chapter 5

Chapter 6
Chapter 7
Chapter 8
Chapter 9
Chapter 10
Chapter 11
Chapter 12
Chapter 13




Available formats for this video:

Actual format may change based on video formats available and browser capability.

    More episodes in this series

    Related episodes

    The Discussion

    • Heavens​Revenge

      One amazing add-on for GHC is a stand-in frontend sort of a replacement for GHCi (using GHC officially) is a project called WinGHCi found http://code.google.com/p/winghci/  I fully recommend its usage since I haven't been disappointed by it yet (and it prints to screen ~20x faster than the original ghci output) Tongue Out


    • tomkirbygre​en

      Really looking forward to studying my way through this! Big thanks to Erik and the C9 team again.

    • DaRage

      Very very interesting and a great lecture. 


      Where can I find the slides? I want to do homework. please help:)

    • wil2300

      Sweet! Been looking forward to this all week. Still gotta get the book - I have an older version.

    • exoteric

      Hungarian notation: An artwork from hell. On the other hand, you are right, using this naming pattern, is kind of in the spirit of Hungarian notation, so I guess the hate-level has to be toned down a little, because it really is quite pretty. I don't quite like xs as much as s anymore because if you just say xs and you have to decompose it into locals in C#, then you need to save x and what's the rest of xs? xss? So in C# at least, without pattern matching it appears to be a little better with s decomposes to x and xs as in first of s and rest of s. I forget but seem to remember that you can pattern match a list in some languages using x:xs so here the parts are already decomposed into a pattern and you don't need the s to denote the whole, as the relevant parts have been named in the pattern. A reason for xs as name is also that it means you align well with the empty list case [].


      The infix notation is not quite as nice as the prefix notation due to the quotes but in a proper editor, these could be removed from view and the infix operators could be specially formatted to reduce noise.


      Object-oriented vs Function-oriented (aka Functional): Intellisense is nice but how about looking up locals based on what fits in the slots - if you pick product, then any local that fits into this will be shown. Well...


      I love the short-code love and am reminded by sentence by Brian Beckman in a previous interview: "Shorter is almost always better." There Brian was talking about short as a more direct way to express simplicity; because shorter may be seen by some as more complex - the same is equally true for longer: imagine a short Haskell program compiled to X86 machine code, it too will be complex for many people, but as Brian says, everyone agrees on what short is.


      I wasn't aware of the pervasiveness of transparently switching to "bignum" when necessary in these languages. That is quite beautiful. It adds another layer of transparency. You don't need to concern yourself with hardware limits of machine types.


      One note on the presentation style: Erik you appear a little short of air at times, maybe thinking faster than you have air ready. (Well, and you kind of pronounce bloat as blood ;o) )


      I wonder if ≤ and ≠ are legal function names in Haskell and defined in the Prelude. It would be nice - also, in this style discussion - because visually it makes the code more homogenous and aligned (≤ and > will take up the same space). And of course in C# we have to use if (..) else if (...) which completely messes up this homogeneity.


      Excellent again! Smiley

    • Charles
    • Charles

      You're welcome! We hope you learn something that will help you grow your programming skills and prepare your minds for the future Smiley


      Study hard, my friends.


    • exoteric

      OK, exercises. Defined it in C# after the first exercise but it's non-sensical for infinite lists - this is where non-termination (⊥) comes in handy


      lastx xs = head (reverse xs)


      ... The |> looks like the solution to the problem of intellisense; when you write: [1,2,3] |> you are in a way making [1,2,3] the most important thing and |> becomes like the dot which fires off intellisense. And then ofcourse if you can use infix notation, Intellisense could help suggest functions as infixes given the first value (on the left) while the remaining values are unspecified.

    • Tirpen

      Regarding the $-operator:


      I've never heard any Haskell programmer say that the $-operator is used to save letters, because as Erik says, you only save at most one. The purpose is to avoid having expressions that end with a huge mountain of parenthesises. Compare the two following, slightly nonsensical, snippets.



      print (take 10 (sort (map (\x -> x + 17) (filter isPrime xs)))))
      print $ take 10 $ sort $ map (\x -> x + 17) $ filter isPrime xs



      Notice how the second version reads alot more similar to when you write pipes in Unix or when you chain together method calls in an OO language.


      Did you even notice that there was one end parenthesis to much in the first version?


       So the $ is not about saving characters, it's about clarity. But I agree that there is a general tendency among Haskellers to be overly clever (read: obscure) to write shorter code.


    • Bass

      I guess you can't define a function in the shell?


      Hugs> double x = x + x
      ERROR - Syntax error in input (unexpected `=')


    • contextfree

      IIRC (don't have a Haskell interpreter handy atm) "let double x = x + x" will work.

    • Bass

      Here is the answer to the homework #2.


      constTwo = a `div` length xs
                  a = 10
                  xs = [1,2,3,4,5]


      I hope it's right. Blushing

    • Bass

      Main> let dooble x = x + x
      ERROR - Syntax error in expression (unexpected end of input)



    • Bass

      Answer to #3, #4 and #5 respectively:


      (PS: I don't know if I should be posting these here?)

      three xs = head $ reverse xs
      four xs = xs !! (length xs - 1)
      five xs = take (length xs - 1) xs
    • Applicative

      The more lovely way with this sort of example is not with a ton of application ($)s, but with the composition operator (.) and one last use of the application operator ($) only, isn't it?

      Erik hasn't explained map and \x -> ... x ... , yet but anyway, in your example

      print (take 10 (sort (map (\x -> x + 17) (filter isPrime xs)))))

      what am I doing to the list called xs ? I'm applying this composite function:

      print . take 10 . sort . map (\x -> x + 17) . filter isPrime

      Whatever I'm starting with, first I filter out just the primes, then I replace each of the remaining numbers with itself + 17; then I omit all but the first 10 things on my list; then print.   

      So, to apply this composite function a list, say the first hundred numbers [1..100], you could write:

      print . take 10 . sort . map (\x -> x + 17) . filter isPrime $  [1..100] 

      Of course, since in the end you're going to print the first 10, following what Erik said about laziness and  take you'd get the same result if you applied it to the infinite list of all numbers:

      print . take 10 . sort . map (\x -> x + 17) . filter isPrime $  [1..] 


    • Tirpen

      Well, I did say it was a nonsensical example. Wink

      And you are of course correct that the pointfree version is better and is what I would write as well in actual code, but I was just trying to show the use of the $ operator specifically in that example.

    • paks8150

      Here are my solutions for #2, #3,#4,#5.



      n = a `div` length xs
               a = 10
               xs = [1 .. 5]


      last' = head . reverse


      #4 (Using recursion)

      last'' [x] = x
      last'' (x:y:xs) = last'' (y:xs)


      init' = reverse . tail . reverse


      init'' xs = take (length xs - 1) xs


      Nice lecture. I really appreciate all the effort. I think we’re on the verge of a paradigm shift. Functional programming is entering the mainstream, like OOP did in the 90’s. I think learning functional programming makes you a better developer on other languages; in particular C# where some many concepts are taken from FP. Now is the moment to make the effort and learn it.

    • tomkirbygre​en

      It is a shame that there isn't a Haskell implementation that runs inside of Visual Studio... and here's why: as I see it those attending Erik's lecture are largely a self selecting group of alpha geeks, the very people who are happy to step outside the Visual Studio IDE. Of course Erik makes numerous references to LINQ, F# and C# as he goes along - which does help, but I have enough trouble encouraging developers at the company where I work to open a build shell to use some command line tool that Visual Studio's IDE doesn't wrap - let alone spark up a completely different environment.


      I appreciate Erik said that the point is not Haskell per say but the concepts, but it is really hard to get the "20+ years on the job, deeply 'pragmatic', MFC/VB6 developer" to step away from the Visual Studio IDE. Personally I am extremely happy we're using Haskell and not F# on this lecture - but I would have a easier time selling this lecture course to a wider community if it was F#.


      Obviously Microsoft has to start somewhere when it comes to educating and preparing the wider development community, and this lecture series is a truly great start. I just wanted to point out that having pitched this lecture series around some of the immediate feedback of it not using Visual Studio has been of the fear, uncertainty and doubt variety. I hate to say it, but WinHugs etc just isn't "fluffy" enough for a lot of developers - it's something that will need to be addressed.


      * note: it's all too easy to say think that developers who are fearful to step away from the Visual Studio IDE are backwards looking and narrow minded - but they're not. Many of these folks have incredible amounts of domain knowledge in their business sector, many of them came to programming via Excel VBA rather than a formal comp.sci background. Here's the sobering thought: there are more of these folks than us 'alpha geeks' / niners. We can not leave them behind because in the wider industry they do the bulk of the programming.


      Again, I do not intend this to be a negative observation, I'm just in a position at my company where my role includes a factor of helping educate other developers and what I really need is a functional programming development experience that approaches say the VBA development experience. I mean in terms of: lack of sharp edges, lots of fluffy intellisense and most importantly, situated in the Visual Studio IDE. It's almost like we need a "Haskell Express" package to sit along side "C# Express".

    • exoteric

      Using F# would not do (full justice) as it does not have a lazy evaluation as the default evaluation strategy. Then we would need to introduce extra noise to have everything be lazy explicitly.


      In a way it would be like teaching functional programming in C# using LINQ which may be fine, but if we need the purest definition why not just go all the way, well, as far as Haskell goes anyway...


      paks8150: Beautiful definitions - and of course the composition operator should be used. I love the init' definition, it looks like rsl. Not sure why it's called init.


      Now one thing is bothering me, looking at the Haskell prelude. And this is it:


      head :: [a] -> a head (x:_) = x head [] = error "Prelude.head: empty list"


      Partial functions. Isn't there a more formal way to express that a case does not apply or is "error" the formal way? It looks like the "new null". Is it thinkable that we could formalize a new list type that is never empty? This would not always be enforcible at compile time of course, but would it not make sense? In a fictional syntax: type NEL a = [a] except [] - or something like that. I remember this very fact annoying me when encoding these types in another language (haXe).


      By encoding constraints into the types we avoid having any partial functions at all!

    • Novox

      I'm quite sure that lack of good tools is the reason why functional programming didn't take off until now (though probably not the only one). And honestly, although I appreciate the power of functional languages and as much as I'd like to leverage this power, I do not (yet) use 'em for day-to-day programming. Just as Erik said, I don't want to do without IntelliSense etc. anymore. Maybe "real programmers" don't need such things; but many people prefer living in a comfortable house instead of a cave, and so do I. I think F# is a good step in this direction (despite it's awkward ML-syntax).

    • tomkirbygre​en

      Totally, as C# is to C++, so we need a ?# for the functional world. Where '?' is != to 'F'. No disrespect to F# itself (I'd rather have it than not), but F# is just not mainstream friendly and causes most VB6 / VB.NET and even C++ developers to want to hide behind the sofa.

    • tarlano



      In response to your question "Would you appreciate if we would talk about all the tricks that Haskell people use?"


      At least for me, I think your answer lies in the text of EWD 340  "The Humble Programmer"  http://www.cs.utexas.edu/~EWD/transcriptions/EWD03xx/EWD340.html


      "The analysis of the influence that programming languages have on the thinking habits of its users, and the recognition that, by now, brainpower is by far our scarcest resource, they together give us a new collection of yardsticks for comparing the relative merits of various programming languages. The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague."


      Subcultures that use tricks don't understand the value of clarity for those that read their code.



    • ShinNoNoir

      Regarding ≤ and ≠, yes, they are legal operator names, but no, they are not defined in the Prelude. Here's how you would define ≤:

      x ≤ y = x <= y

      Or alternatively:

      (≤) :: Ord a => a -> a -> Bool
      (≤) = (<=)

    • ShinNoNoir

      You cannot define functions in Hugs using "let foo x = bar", but you can in GHCi. So if you're using Hugs, you have to define your function in a file or use a "let ... = ... in ..." expression:

      > let double x = x + x  in  double 4

    • ShinNoNoir

      You could introduce a safeHead function if you really want to be safe:

      safeHead :: [a] -> Maybe a safeHead [] = Nothing safeHead (x:xs) = x

      Otherwise you have to make sure you never use head on an empty list. Regarding non-empty lists, here's how you'd define them in Haskell:

      data Stream a = Cons a (Stream a)

    • ShinNoNoir

      Let's mention the M-word in this thread. Tongue Out

      -- from the slides: double x = x + x quadruple x = double (double x) -- Erik's pointfree version of quadruple from the whiteboard: quadruple = double . double -- The version of a Haskell programmer in love with the Reader monad: double
       = join (+) quadruple = join (.) double 

    • Bas

      I wonder if Erik says "Weet je" a lot when he's back in the motherland. Tongue Out

    • paks8150

      I think you're being too harsh on F#. F# is an excellent bridge for people that want to learn functional programming. I has all the familiar things that an imperative programmer expects like mutable variables, the “for” loop, objects, Visual Studio support. But once you let go the training wheels, you have access to all the benefits of a functional language.

    • exoteric

      F# is not mainstream friendly? Then all hope is lost for Haskell. I think F# looks pretty comprehensible without as many tricks as Haskell. H#?

    • head.in.the.​box

      Interesting that you cite Dijkstra since he was super keen on streamlining notation. The tricks I was referring to are about streamlining notation, as opposed to clever algorithmic tricks that I believe he refers to in that paper.

    • head.in.the.​box

      My real name is Diana Charité, weet je wel, weet je niet Wink


      Seriously, any feedback on improving the delivery of the lectures is super welcome.

      This is the first time for me talking in an empty studio to a lone camera, imagining all you 9-ers behind its lens.

      What you hear is my brain making background noise as it discovers new associations, insights, and relationships on the fly while I am presenting the prepared material. 

    • head.in.the.​box

      That is correct.

    • head.in.the.​box

      One note on the presentation style: Erik you appear a little short of air at times, maybe thinking faster than you have air ready. (Well, and you kind of pronounce bloat as blood ;o) )


      Since you ask ... after breaking my leg a couple of years ago, I suffered a pulmonary embolism (http://en.wikipedia.org/wiki/Pulmonary_embolism. So I am happy that I can breathe at all.

    • paks8150

      Thanks exoteric. My original solution for init' didn't use composition until I saw the lecture and Erik started talking about function composition (yes, I did the exercises from the book before the lecture Tongue Out ). I'm not sure if good at this point of the lecture to introduce pointfree style. But how am I to say Smiley

      This was my original solution:


      init’ xs = reverse (tail (reverse xs))


      Which I think people not familiar with Haskell would understand better than



      init’ = reverse . tail . reverse


      I say this, because it took me a while to understand what was going on with the second definition and why the parameter was implicit.

    • Bas

      Man, and here I was thinking Diana Charité would be too obscure a joke to make. Tongue Out


      Seriously though, it's noticable but it didn't distract me or anything. These videos are great. Now I just need to find more time to devote 100% of my attention to them.

    • exoteric

      Sorry to hear that Erik. I'm very happy you're able to do this lecture series.


      So disregard what I said, I'm just happy you're doing this Smiley

      (And it didn't affect the quality of the material anyway)

    • Charles

      I am going to be in the "audience" for the filming today, man Smiley


    • exoteric
    • head.in.the.​box

      As I will explain in lecture #4, I prefer to think of errors and partiality in Haskell as nontermination. Being able to "observe" an error is a special effect, which requires monads http://www.zvon.org/other/haskell/Outputprelude/catch_f.html

    • Balclutha

      I really enjoyed this video and I really enjoy Erik's presentation. I read Hutton's book a while ago (it's an excellent book -- and thin too) but I also appreciate the additional material Erik is covering, the first lecture was fabulous in that respect.


      Erik, thank you. Please keep in the opinion and the esoterica (including coding idioms) because it's what makes your presentation so fascinating.


      Again, thank you for doing these.

    • MonkeyGuru

      Wow, I'd love to be in the "audience" too. These lectures are absolutely wonderful!

      They should be held as "cooltalks" or in the resnet rooms or something.

      It's true that somehow Erik isn't quite being his usual super-charismatic self; talking to a camera in an empty room.

    • exoteric

      Very much looking forward to that Smiley

      It somwhat nerves me to have many ways to do something, it makes the code irregular/non-uniform.

    • PatB

      So true...  Simply put : Code is easier to write then read.


      Hence, duplicated code, error introduced in maintaining it, …


      So from my humble perspective, any effort to make code “clearer” is an effort toward the proper direction.


      And clearer does not always come from an application of shorter.


      Heck, in C# I could write a series of branching condition as a single line of ?:

    • tarlano



      Yes, I agree with you that Dijkstra liked streamlining notation.


      In his 5th argument he was talking about language notation and the limitations of the human mind. If you reread it I think you will find he was stressing modesty and a "less is more" attitude toward manageability (i.e. readability) of programming languages. 


      If you read that paragraph you will see this text.


      "Another lesson we should have learned from the recent past is that the development of "richer" or "more powerful" programming languages was a mistake in the sense that these baroque monstrosities, these conglomerations of idiosyncrasies, are really unmanageable, both mechanically and mentally. I see a great future for very systematic and very modest programming languages. " 


      Anyway, all I was saying is that using tricks and trying to save every last character even for "elegance" might lead a programmer down the wrong path if it is non-systematic and eccentric.


      Love your videos!



    • exoteric

      Actually, I prefer that to C# if's because C# if's are statements. In contrast, in functional languages they are expressions and are therefore composable which is essential for highly readable well-structured programs. Once you try composable if's you never want to go back. Then we can argue over returns which are more "powerful" than blocks that evaluate to the value of the last expression of the block - but given composable if's that is actually very nice.


      Eiffel diverges from the normal "C" path in that it has a fixed return variable which is named Result and that can just be assigned to. This means no jumps out of the function except through regular branching logic with if's aso. Eiffel also distinguishes assignment with comparison, which is quite nice; although in a functional language the distinction looks less important given single-assignment and thus the denial of assignment in expressions.


      Day to day, I work with a programming language that allows both styles but having two styles is a nuisance yet it is obvious why both styles exist - because the language is not disciplined - it does not have if-expressions, for example, which means that it becomes more of a pain to write programs in the disciplined way. As usual it's more or less grab bag of features chosen by arbitrary affinity.


      It's just that now we're realizing that this kind of grab bag of features that enable arbitrary side-effects is no longer tenable if there is to be any hope of compiler-assisted concurrency. Or that's how it looks to me; your milage may vary...

    • exoteric

      I wonder what's worse - pointer gymnastics or arrow gymnastics - or vice versa. Maybe the interactive environment could unfold/inline the definitions to make the code clearer in cases where the code appears mysterious to the reader. So the code can maintain it's shortness while what the reader sees is an expansion. Best of both "worlds" - sacrifice nothing.

    • MarioTP

      Very looking forward to next Thursday Smiley. Again a very cool lecture!!!


      @ Dr. Meijer: Your enthusiasm is so inviting and catching, that's unbelievable Smiley!

    • jlomax

      HOW do you get ANY of this to work in HUGS ?


      A prior posting said the examples were incorrect and needed to be:


      let double x = x + x in double 4


      BUT, if you do that and then try to enter:

      double 4

      you get:  ERROR - Undefined varialbe "double"


      This is supposed to be an INTRODUCTION.  Why even suggest we install HUGS when it doesn't match anything presented? 


      If Haskell programmers value terseness, why do we need a LET that wasn't shown at any point in the lecture?



    • head.in.the.​box

      That is as expected: (let double x = x+x in double 4) is an expressions whose value is 8. The function double is not in scope after that.

      You should put the declarations in a file and load them into Hugs. Or perhaps try GHCi http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci.html 



    • Charles

      Good feedback. Thank you.


      In some sense, the language doesn't really matter. Just listen to the lecture. That will expand your mind to the extent that what you learn is readily applicable in any functional language or increasingly hybrid language (like C#).


      Erik will use Haskell syntax, C# and pseudo code (including pictures) to lay down the foundational functional knowledge. You can compose the bricks as you choose, as you need.



    • Justin Bailey

      I agree regarding obscure code, or anything written in C (** duck **), but of course I don't think that is the case here.


      When I started learning Haskell a lot of the "elegant" solutions really bothered me - I couldn't understand them and they seemed obscure. They used many nested function definitions or class instances which tied my brain in knots. I slowly realized, though, that once you knew the definition of a function, you could forget it. The details didn't matter - you just needed to be reminded of its basic operation and type. I think that Haskell's purity (in the technical sense) allows this much more than languages w/ side-effects. Its very easy to extract a chunk of code and wrap it up in a small definition w/o changing the behavior of your program.


      Let me illustrate with calculus.  These two things say the same thing, but one is more suitable for a beginner while the other is obvious to anyone familiar with the notation:


        "Consider a parabola. Look at the slope between two points on the curve. Now move the points closer together. Consider how the slope changes. As the points get closer and closer together, the slope of the line between them will converge on 2 * x, no matter where  you are on the curve"




        "d (x ^ 2) / dx = 2 * x"


      I would expect the "tricks" that Erik promised to show would be along these lines - "tricks" that make our programs more flexible while at the same time "easier" to understand (once you know the basics).











    • Justin Bailey

      I would love to see more of this stuff! Please work it in wherever you can.

    • Justin Bailey

      There is Visual Haskell, but it's very out of date. It targest VS 2005, does not use the Managed Package Framework (i.e., it extends VS using C++ rather than .NET), and its married to a really old version of GHC:




      BUT the sources are available and I wish someone would update it ...





    • Justin Bailey

      Let me pimp my Haskell  Cheatsheet, a short syntax reference and minitutorial:



    • chudq

      Thank Erik for your excellent shows. I really enjoy them. One suggeststion for your show: can you move you to lower right corner as a picture-in-picture way when you read or explain a slide? This will avoid me to pause the show to read slide (especially for some codes).

    • exoteric

      I was curious about the point-free style that Erik mentions and why it's called point-free when you see examples using a point or dot as the operator symbol - it would appear a most point-ful style. Apparently though, it has to do with the absence of explicit value passing in function declarations; such as with a = b . c where the argument is never mentioned - rather the b . c expression just composes a new function.




      Now interestingly, someone actually made tooling support for this, such that functions can be transformed between point and point-free style. A plugin to an IRC bot which can evaluate Haskell expressions.


      This would be an awesome tool to have built into a Haskell IDE! Several people are asking about environments, so these two came up





      Erik, besides the LINQ, Rx, Volta, etc. And the homework to rewrite both Windows and Office in Haskell, maybe you could start a Visual Studio incubation project on Haskell as well Wink

    • chudq

      Is there RRS feed for this serials?

    • chudq

      I got it: feed://channel9.msdn.com/tags/C9+Lectures/RSS/

    • we

      Great lecture.


      Although functional programming can do multi-dispatching better, it has its own weaknesses in the expression problem.


      I like how you digress and discuss about topics not typically seen in textbooks. Regarding intellisense, I think we can limit the candidate functions to those imported.

    • tapke

      Just started the lecture series, and it's very well done. Many thanks, Erik, for all the work you're doing.

    • jpuopolo

      Excellent material!


      For those looking to learn F# at your own pace, please see The F# Survival Guide at http://www.ctocorner.com/fsharp/book




    Comments closed

    Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.