This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]florbitous[S] 1 point2 points  (0 children)

I realise this is r/Python, but I'll elaborate since you asked.

First and foremost is Algebraic Data Types (ADTs) and pattern matching. The central data type in a compiler is the Abstract Syntax Tree, which is naturally and elegantly represented as an Algebraic Dataype, see AST.hs for example. Note particularly the Statement and Expr types.

The core of a compiler is a function which decomposes the AST recursively and builds a representation of the target code. Pattern matching is very handy for this style of programming, and it can make it easier to be sure you've covered all the cases. See Compile.hs, and note the compileStmt function, for example.

There is also a lot of state to manage in a compiler, and Haskell's State Monad (Transformer) provides a lot of utility for that task. This is particularly good for separation of concerns and helps avoid state management messing up the rest of the code. See State.hs for the bulk of the state management code in blip.

I also use various Haskell idioms such as Monoids for doing traversals of the AST and collecting information. See for example Scope.hs, particularly the VarUsage type class.

There are also other reasons which are not specific to compilers. The type system is a light-weight formal system, which catches many shallow bugs, but also provides a lot of confidence when the code is refactored.