Hello, hello, hello. Welcome to part four of this adventure where we're making a database by hand. In part three we did some joins, and today we're doing to do some limiting. If you'd like to look at the code, it's right here . No no, no no no no, no no no no, no no, there's no limits Limit is very straightforward, it's used to control the amount of data we get back…
Well, well, well, if it isn't part 3. Last time we tidied up a bit so that we're ready to tackle joins. As ever, all the code lives right here . What is a join then? Say we have a table of Albums that looks something like: { " albumId ": 1 , " title ": " Best of the Beatles ", " artistId ": 1 }, { " albumId ": 2 , " title ": " Horses ", " artistId ": 2 } ...and another table full of…
Hello, hello, hello. Welcome to part two of this adventure where we're making a database by hand. In part one we stole a SQL parser, did some table scans, filtered some results, and projected the ones we're interested in. I promised we'd look at joins today, but first we need to do a bit of housekeeping. If you'd like to look at the code, it's right here . Storing our rows…
So, confession, I love playing on the computer, but I'm terrible at SQL. I know that it's Good or whatever and there's this whole very sensible looking Relational Algebra behind it all, but like when I have to interact with it, I get the job done and then immediately wipe whatever I learned from my brain. Enough is enough. It's time to learn it properly. And what better way…
So last year I started writing a series on compiling a functional language to LLVM, and I have to confess, I came utterly unstuck . Until recent versions, LLVM tried to be helpful by making you specify types for all pointers you pass around. This is really helpful in simple cases as you get basic typechecking at compile time. However, once you start implementing things like sum types (ie, reserve…
Welcome to part 3 of this series in compiling functional languages to LLVM. In part 2 we added basic control flow to our langauge with an if / then / else construct. Today we're going to get one important step towards a functional programming language by adding functions and variables. By the end of today we'll be able to make small modules such as: function add ( a: integer,…
Welcome to part 2 of this series in compiling functional languages to LLVM. In part 1 we created a very simple calculator that let us add, subtract and multiply integers like 1 + 1 or 6 * (5 - 2) . Today we're going to spice things up a touch by adding some basic control flow. By the end of today we're going to be writing sweet syntax such as: 2 + 2 == 5 if 6 == 6 then False else True…
Recently I thought it would be good to start compiling the small functional language mimsa I've been messing around with for the last few years to LLVM. There's a few really helpful resources - Joseph Morag's Micro-C series, and Mapping High Level Concepts to LLVM IR in particular, but neither go into converting functional programming paradigms such as pattern matching, lambdas and…
So I've been getting really interested in typechecking, and well, the best way to learn is to try and explain it in words, so here we go. There are many kinds of typechecking, but today I want to explain a variation on Hindley Milner (I've also seen it called Damas Milner, please feel free to ping with the actual truth, fact fans). This kind of type system is the kind you'll find…
Over the last year and a half I haven't really written much stuff, because I have been working on a small content-addressed programming language called mimsa . I'm not really sure why I am doing this, other than that I watched a neat tutorial about how typecheckers worked , and then got somewhat carried away. I has sat down to write about my recent implementation of property testing in…
So in the last post I quickly introduced the project I've been working on for a while called mimsa . The reason I did this was so that I could write this post about recently adding property tests to the language, and what was good/bad about that, so without further ado here are many words: Tests in mimsa So, for context, unit tests work as follows in mimsa : We create a (broken) add…
So previously we've spoken about the idea of a newtype in Haskell. A newtype is a wrapper you can put around a value to distinguish it from other items. It's common to give value that has it's own domain meaning it's own newtype , for instance: newtype Firstname = Firstname { getFirstname :: String } deriving ( Eq , Ord , Show ) newtype Surname = Surname { getSurname :: String…
Hello. In our last article we described how to generate test cases for contract testing in Haskell. This time, we are going to look at generating the front end portion of these in Typescript . This will probably be a lot briefer because I am a very lazy person at heart. First, some rambling The main differences with the type system of Haskell or Purescript compared to that of Typescript is that…
Hello. I hope you are well. Over the last few months I have been trying out a method for generating Contract Tests between services using Arbitrary instances from Quickcheck which I thought it might be good to share. It's not particularly clever, which is partially what I like about it, and as a result I may not have been the first to come up with it. If I have therefore somewhat stolen your…
Note: I have taken a break from whatever it is that I usually crap on about to do some opinions . Beware. Whimsical Story When I was much younger I was what you might call "quite a trying child". Apparently, a thing I liked was to ask lots of questions. One that I remember very clearly was this: "Where do washing machines come from?" (A reasonable, if somewhat tangental question I suppose. I…
When I first started working at a Serious Software Place , I remember being very excited about the idea of testing things and dependency injection and purity and all such things. One day, I was spouting about this (presuming, I suppose, that everybody else was also so new to and thus enamoured with the topic), as well as these Functors I had been reading about, and one of the more senior engineers…
A few weeks ago I gave a talk at London Haskell that was basically an advert for a data migrating library I haven't even finished yet. However, I managed on the whole to hide this fact and some people even came up afterwards and asked me how the library was performing in production to which of course I said "very well indeed, because of course i am very good at computers" and quickly changed…
About a month ago I gave a talk about Refined types at a React meetup. Needless to say, it was a resounding success so I thought I would share an adapted version of the slides so that you can all learn to be as learned as me when it comes to such a topic. Let's start by listing some things that we as programmers generally agree we don't particularly like: Runtime errors caused by…
Good morning and/or evening. I found myself defaulting to starting with an apology for the amount of time since my last post, then I caught myself and reminded myself that It's My Blog And I Can Post Whenever I Feel Like It Actually . So with that in mind, let's continue to today's main course, at exactly the rambling pace of my choosing. As I may have mentioned, my current…
The Monad is one of the most infamous things around Haskell, and indeed functional programming, and so writing tutorials around them has become something of a cliche. Let me be clear - I really did try and avoid writing one, but it's gotten to the point that it's difficult to talk about the other more interesting stuff without at least mentioning it. To try and avoid falling into the…
It's one thing to understand typeclasses individually, but another to see them in context. This is the second in a series looking at some common datatypes and see how their instances of the main typeclasses act. We started with one of the simplest, Maybe , and now we move onto it's slightly more powerful cousin Either . One thing or the other thing Here is the data definition for Either…
Hello. Let's make a box for putting functions in... newtype FuncBox b c = FuncBox { runFuncBox :: b -> c } ...and a function... length :: String -> Int length s = foldl' (\c _ -> c+ 1 ) 0 s ...and then let's put a function in this box: length' :: FuncBox String Int length' = FuncBox length Great. A function in a box. You may be concerned that something interesting is going on here, so…
It's one thing to understand typeclasses individually, but another to see them in context. This is the first in a series where we'll look at some common datatypes and see how their instances of the main typeclasses act. We're starting with one of the simplest, Maybe , and I hope this will help you get a feel for the way it acts. The plan is to move onto Either , List and then Reader…
Hello! I hope you are well. It has been a little while between posts as I keep starting things and then not finishing them. My most recent distraction has been remaking a game that I wrote a year or two back called It Is The Egg , which is an HTML canvas game where eggs roll around and generally have a nice time. I wanted to add more levels and features but I have no strong desire to write…
Let's say we have a function that uses the IO monad that we want to test. Now you may be aware that IO is the place in which all the bad things happen that aren't supposed to happen in Haskell. Things like Database Connections , and Mutable Global Variables and (worst of all) Actual User Interactions . It doesn't bear thinking about to be honest. However, mock dramatics aside, IO is…
Let's talk about type signatures. hello :: String -> Int -> String Pretty clear what is going on, right? Seems fine. What about this lad? wtflol :: ( Show a , Num b ) => a -> [ a ] -> b -> ( a , b ) That's pretty unhelpful to be honest. What are these letters doing in our types when we wanted, well, types? Let's work up from a simple one to a stupid one and maybe learn something…
Let's talk about things that could be one thing, or indeed could be another thing altogether. data Things a b = This a | That b This could be a This with an a inside, like a String . thisEgg :: Things String Int thisEgg = This " Egg " Or indeed a That with a b inside, like an Int . thatNumber :: Things String Int thatNumber = That 68 Now hopefully you are now thinking - "Oh please, I do hope…
Let's think about things that may or may not happen (again, I know, I'm sorry). data Perhaps a = Yeah a | Nope deriving ( Eq ) A classic datatype, that we can use for expressing either Some Sort Of Value or The Entire Concept Of Failure . We can use it when getting the first item of a list, which may or may not actually exist. first :: [ a ] -> Perhaps a first (a:_) = Yeah a first _ =…
So recently I have become one of those jerks that has sailed through Read A Couple Of Chapters Of A Book About Haskell , by way of Snuck Maybe Types Into My Work Project to arrive at full-blown Good Morning Sir/Madam, Have You Got A Spare Moment To Talk About Monads™? . That is to say, by selfishly forcing these concepts upon my colleagues I have ended up spending a lot of my working life…
In an exciting previous episode, we talked about the Semigroup type class that is used for smashing two things together. Today we're going to talk about the Monoid typeclass, which is a way of generalising a collection of things that can be combined together. Seems very similar, but the important difference between combining two things, and combining any number of things, is that that number…
Let's think about things that can be put together. Here's two lists, combined into one big list. list :: [ Int ] list = [ 1 , 2 , 3 ] ++ [ 4 , 5 , 6 ] -- list == [1,2,3,4,5,6] Great! What about two strings combined into one large excellent string? string :: String string = " Great " ++ " Stuff " -- string == "Great Stuff" Sure! Seems great. String is actually a List of Char so really…
I have not always found it clear how to get started with Haskell, and I have a small library I want to make as an experiment so I figured I'd document the process as a sort of Getting Started. The tiny library I wish to make is for reading environment variables, which can be used for database connections or similar. I use MacOS but will try not to make anything too platform specific, and link…
Let's think about Trees. data MyTree a = Leaf a | Branch ( MyTree a) ( MyTree a) A tree can be either a Leaf with contains some of value, or a Branch that has two slots for either another Branch or perhaps a Leaf . We can build up a tree like this: sampleTree :: MyTree Int sampleTree = Branch ( Branch ( Leaf 2 ) ( Leaf 3 )) ( Branch ( Leaf 5 ) ( Leaf 2 )) So if you remember way back when when…
Good question. What are newtypes ? You see them in Haskell a lot. Here's one. newtype Dog a = Dog { getDog :: a } We can make a Dog as a container for a thing (in this case, a String ) frank :: Dog String frank = Dog " Frank " -- frank == Dog "Frank" Or we can unwrap it again and lose nothing along the way (this means the types String and Dog String are isomorphic in maths terms) name ::…
So last time we looked at lens and saw had to jump into record-shaped structures and change things around like big hacker professionals. However we didn't try to change anything with a sum type in it, like Either or Maybe or something. What can we use for that? Only a bloody Prism , apparently. Here's an example sum type that can either contain a dog's name or it's age, and is…
Let's think about sets of things that we want to make into one thing. A classic example might be a list of numbers that we want to add up. In Javascript we might do something like this: const added = [ 1 , 2 , 3 , 4 ]. reduce (( total , item ) => { return total + item ; }, 0 ); // added == 10 Or perhaps we could get the maximum of the same list. const maxNo = [ 1 , 2 , 3 , 4 ].…
In my learning of Haskell and all the associated mathematical stuff attached to it, one of the tougher conceptual cookies to crack has been the Applicative Functor. Coming from a background of fairly functional Javascript, functor is a very easy sell - it's array.map . Easy. If there's a thing in the box, do something to the thing, if there's nothing in the box, don't freak out…
Let's think about Predicates. newtype Preddy a = Preddy { getPreddy :: a -> Bool } What the hell is this? OK. So it's a newtype . What is basically does is let's us take some sort of value (here, any function from a -> Bool ) and make a new type out of it so we can give it typeclasses and do magic shit to it. So let's say we have a basic function that takes a number and…
Let's think about things that might or might not happen. data Perhaps a = Yeah a | Nah Perhaps is a datatype that we can also use as a container for other data (by holding it inside a nice Yeah ), or to show that we have no data with Nah . Let's put things in it. john :: Perhaps String john = Yeah " John " Great job. John is having a nice time there. How might we express an absence of…
Let's think about things. data Thing = Thing1 | Thing2 Seems great so far. Let's try and look at one in ghci . Prelude > show Thing1 Oh shit! • No instance for ( Show Thing ) arising from a use of ‘ show ’ • In the expression: show Thing1 In an equation for ‘it’: it = show Thing1 Totally bogus! So what's the problem? So for something to be shown in the console, we need to know how…
Let's think about horses. There are three kinds of Horse: data Horse = SmallHorse | LargeHorse | OtherHorse Let's make a function to check whether two Horses are in fact equivalently sized. isSameHorse :: Horse -> Horse -> Bool isSameHorse first second = first == second Looks like a classic. Let's run it! isSameHorse SmallHorse LargeHorse Shit! • No instance for ( Eq Horse ) arising…
Let's think about moods. Psychologists all agree there are only 5 real emotional states. data Mood = Awful | QuiteBad | OK | Good | Great Which one is better? Is Great better than Awful ? broken :: Bool broken = Awful < Great Shit! • No instance for ( Ord Mood ) arising from a use of ‘<’ • In the expression: Awful < Great In an equation for ‘broken’: broken = Awful < Great These cannot be…
Do notation is a strange thing. You first see it in examples of IO () with something like: main :: IO () main = do firstName <- getLine surname <- getLine print (" Hello " ++ firstName ++ " " ++ surname) And all seems well! This functional programming seems fine! But what's going on here? Actually what's really going on here is main2 :: IO () main2 = getLine >>= (\firstName -> getLine…
Lenses are a thing that Haskell people talk about a lot. They bloody love a lens. Everywhere you go, lens, lens, lens. What is lens? Should we, mere mortals, care? Let's try and find out what the big deal is. So. Immutability is great, but it does mean that updating a value that lives deep within a big data structure can become an utter pain in the arse. Let's define a data structure:…
I recently read a piece of useful advice on Twitter about total functions which I enjoyed. The advice (which I will definitely accurately source at some point in the future, lol) goes something like this: "You start making your functions total by adding Maybe, but then you move onto removing Maybe." Like all my favourite advice this sounds like it doesn't make any sense, so I figured I'd…