A Modular Fully-Lazy Lambda Lifter in Haskell 1 Introduction

A Modular Fully-Lazy Lambda Lifter in Haskell 1 Introduction

A mo dular fullylazy lambda lifter in Haskell Simon L Peyton Jones Department of Computing Science University of Glasgow G QQ David Lester Department of Computer Science University of Manchester M PL June Abstract An imp ortant step in many compilers for functional languages is lambda lifting In his thesis Hughes showed that by doing lambda lifting in a particular way a useful prop erty called ful l laziness can b e preserved Hughes Full laziness has b een seen as intertwined with lambda lifting ever since We show that on the contrary full laziness can b e regarded as a completely separate pro cess to lambda lifting thus making it easy to use dierent lambda lifters following a fulllaziness transformation or to use the fulllaziness transformation in compilers which do not require lambda lifting On the way we present the complete co de for our mo dular fullylazy lambda lifter written in the Haskell functional programming language This paper appears in Software Practice and Experience May Introduction Lambda lifting and full laziness are part of the folk lore of functional programming yet the few published descriptions of fullylazy lambda lifting have b een either informal or hard to understand with the notable exception of Bird Bird Our treatment diers from earlier work in the following ways The main technical contribution is to show how full laziness can b e separated from lambda lifting so that the two transformations can b e carried out indep endently This makes each transformation easier to understand and improves the mo dularity of the compiler Our treatment deals with a language including let and letrecexpressions Not only is this essential for ecient compilation in the later stages of most compilers but we also show that eliminating letrec expressions by translating them into lambda abstrac tions loses full laziness To our knowledge this has not previously b een realised We show how to decomp ose each of the transformations further into a comp osition of simple steps each of which is very easy to program thus further improving mo dularity We have developed an elegant use of parameterised data types which allows the type system to help express the purp ose of each pass We present the complete source co de for our solution and we do cument some of the exp e rience we gained in developing it indeed the pap er can b e read as an exercise in functional programming The co de is presented in the functional programming language Haskell and the source text for the pap er is an executable literate Haskell program Lines of co de are distinguished by a leading sign the rest of the text b eing commentary We introduce all the notation and background that is required to understand the pap er The rst three sections introduce the language to b e compiled the Haskell language and the main data types to b e used Following these preliminaries we develop a nonfullylazy lambda lifter and then rene it into a fully lazy one The pap er concludes with some optimisations to the fullylazy lambda lifter The language We b egin by dening a small language L on which our compiler will op erate The abstract syntax of the language is given by the following pro ductions expression name j constant Literals and builtin functions j expression expression Application j let defns in expression Nonrecursive denitions j letrec defns in expression Recursive denitions j name expression Lambda abstraction defns def ::: def n > n def name expression The concrete syntax is conventional parentheses are used to disambiguate application as so ciates to the left and binds more tightly than any other op erator the b o dy of a lambda abstraction extends as far to the right as p ossible the usual inx op erators are p ermitted and denitions are delimited using layout Notice that the bindings in letrec expressions are all simple that is the left hand side of the binding is always just a variable Functions are dened by binding variables to lambda abstractions Here is an example to illustrate these p oints letrec fac n if n n factorial n in fac An imp ortant feature of this language is that any pure highlevel functional programming language can b e translated into it without loss of expressiveness or eciency This pro cess is describ ed in some detail by Peyton Jones Peyton Jones Notice that letrecexpressions are retained despite the fact that they are resp onsible for many of the subtleties in the rest of the pap er They can certainly b e transformed into applications of lambda abstractions and the Y combinator but doing so straightforwardly may result in a serious loss of eciency Peyton Jones Chapter For example eliminating a letexpression introduces a new lambda abstraction which will under the com pilation scheme describ ed in this pap er b e lambdalifted and thereby decomp ose execution into smaller steps Similarly a naive treatment of mutual lo cal recursion using Y involves much packing and unpacking of tuples which can easily b e avoided if the letrecexpression is handled explicitly Finally later on we show that laziness can b e lost if letexpressions are not handled sp ecially Haskell Haskell is a recentlydesigned common nonstrict pure functional language Hudak et al For the purp oses of this pap er it is fairly similar to SML or Miranda except in its treatment of abstract data types and mo dules We make little use of Haskells ma jor technical innovation namely systematic overloading using type classes Haskell mo dules b egin with a declaration naming the mo dule and imp orting any mo dules it requires module LambdaLift where import Utilities Here the mo dule we will b e dening is called LambdaLift and it imp orts an auxiliary mo dule called Utilities whose interface is given in the App endix A data type for compilation Every compiler has a data type which represents the abstract syntax tree of the program b eing compiled The denition of this data type has a substantial impact on the clarity and eciency of the compiler so it merits careful thought First failed attempt As a rst attempt the language describ ed in the previous section can translated directly into the following Haskell algebraic data type declaration 1 Miranda is a trade mark of Research Software Ltd 2 Notice that data constructors such as EVar and ELam and type constructors such as Expresssion and Name must b oth b egin with capital letter in Haskell data Expression EConst Constant EVar Name EAp Expression Expression ELam Name Expression ELet IsRec Definition Expression We choose to represent names simply by their character string using a type synonym decla ration type Name Char Constants may b e numbers b o oleans the names of global functions and so on data Constant CNum Integer CBool Bool CFun Name The denition of the Constant type can b e changed without aecting any of the rest of this pap er As an example of the Expression type the Lexpression a would b e represented by the Haskell expression EAp EAp EConst CFun EVar a EConst CNum Letexpressions can usually b e treated in the same manner as letrecexpressions so the two are given a common constructor and distinguished by a ag of type IsRec It is convenient to use a b o olean for this ag type IsRec Bool recursive True nonRecursive False Each denition in the denition list of an ELet construction is just a pair type Definition Name Expression Second failed attempt It do es not take long to discover that this is an insuciently exible data type Many compiler passes add information to the abstract syntax tree and we need a systematic way to represent this information Examples of analyses which generate this sort of information are freevariable analysis binding level analysis type inference strictness analysis and sharing analysis The most obvious way to add such information is to add a new constructor for annotations to the Expr data type thus data Expression EVar Name EAnnot Annotation Expression together with an auxiliary data type for annotations which can b e extended as required 3 The type Set a is a standard abstract data type for sets whose interface is given in the App endix but data Annotation FreeVars Set Name Level Integer This allows annotations to app ear freely throughout the syntax tree which app ears admirably exible In practice it suers from two ma jor disadvantages It is easy enough to add annotation information in the form just describ ed but writing a compiler pass which uses information placed there by a previous pass is downright awkward Supp ose for example that a pass wishes to use the freevariable information left at every no de of the tree by a previous pass Presumably this information is attached immediately ab ove every no de but the data type would p ermit several annotation no des to app ear ab ove each no de and worse still none or more than one might have a free variable annotation Even if the programmer is prepared to certify that there is exactly one annotation no de ab ove every tree no de and that it is a freevariable annotation the implementation will still p erform patternmatching to check these assertions when extracting the annotation Both of these problems namely the requirement for uncheckable programmer assertions and some implementation overhead are directly attributable to the fact that every annotated tree has the rather uninformative type Expression which says nothing ab out which annotations are present The second ma jor problem is that further exp erimentation reveals that two distinct forms of annotation are required

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    28 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us