Advanced Functional Programming (9) Domain Specific Embedded Languages



Similar documents
POLYTYPIC PROGRAMMING OR: Programming Language Theory is Helpful

Chapter 7: Functional Programming Languages

Syntax Check of Embedded SQL in C++ with Proto

Functional Programming. Functional Programming Languages. Chapter 14. Introduction

Object-Oriented Software Specification in Programming Language Design and Implementation

KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

Embedded Software Development with MPS

Functional Programming

Comparing Dynamic and Static Language Approaches to Web Frameworks

Variable Base Interface

Towards a Tight Integration of a Functional Web Client Language into Scala

Thomas Jefferson High School for Science and Technology Program of Studies Foundations of Computer Science. Unit of Study / Textbook Correlation

YouTrack MPS case study

The Clean programming language. Group 25, Jingui Li, Daren Tuzi

The countdown problem

Cedalion A Language Oriented Programming Language (Extended Abstract)

Functional Programming in C++11

[Refer Slide Time: 05:10]

Compiler I: Syntax Analysis Human Thought

Semantic Analysis: Types and Type Checking

Chapter 1. Dr. Chris Irwin Davis Phone: (972) Office: ECSS CS-4337 Organization of Programming Languages

Moving from CS 61A Scheme to CS 61B Java

Lecture 9. Semantic Analysis Scoping and Symbol Table

03 - Lexical Analysis

Programming Languages in Artificial Intelligence

Structure of Presentation. The Role of Programming in Informatics Curricula. Concepts of Informatics 2. Concepts of Informatics 1

INTRODUCTION TO OBJECTIVE-C CSCI 4448/5448: OBJECT-ORIENTED ANALYSIS & DESIGN LECTURE 12 09/29/2011

Lecture 1: Introduction

SDT: A Programming Language for Debugging (Working Paper)

Programming Languages

Timber: A Programming Language for Real-Time Embedded Systems

Sources: On the Web: Slides will be available on:

Deterministic Discrete Modeling

Anatomy of Programming Languages. William R. Cook

How To Write A Programmg With A State Monad And An Imperative Dsl

1/20/2016 INTRODUCTION

White Paper: 5GL RAD Development

Scanning and parsing. Topics. Announcements Pick a partner by Monday Makeup lecture will be on Monday August 29th at 3pm

Parsing Technology and its role in Legacy Modernization. A Metaware White Paper

C++ Programming Language

The Mjølner BETA system

ADVANCED SCHOOL OF SYSTEMS AND DATA STUDIES (ASSDAS) PROGRAM: CTech in Computer Science

Introduction. Compiler Design CSE 504. Overview. Programming problems are easier to solve in high-level languages

Chapter One Introduction to Programming

PROBLEM SOLVING SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON

Jos Warmer, Independent

Haskell Programming With Tests, and Some Alloy

How to make the computer understand? Lecture 15: Putting it all together. Example (Output assembly code) Example (input program) Anatomy of a Computer

Informatica e Sistemi in Tempo Reale

Division of Mathematical Sciences

Adding GADTs to OCaml the direct approach

Testing and Tracing Lazy Functional Programs using QuickCheck and Hat

NLUI Server User s Guide

Domains and Competencies

SQL INJECTION ATTACKS By Zelinski Radu, Technical University of Moldova

Compilers. Introduction to Compilers. Lecture 1. Spring term. Mick O Donnell: michael.odonnell@uam.es Alfonso Ortega: alfonso.ortega@uam.

Project Group Applied Functional Programming

C++ INTERVIEW QUESTIONS

A Scala DSL for Rete-based Runtime Verification

Scoping (Readings 7.1,7.4,7.6) Parameter passing methods (7.5) Building symbol tables (7.6)

Chapter 15 Functional Programming Languages

TECHNOLOGY Computer Programming II Grade: 9-12 Standard 2: Technology and Society Interaction

Fun with Phantom Types

Simplifying the Development of Rules Using Domain Specific Languages in DROOLS

CSE 373: Data Structure & Algorithms Lecture 25: Programming Languages. Nicki Dell Spring 2014

A Multi-layered Domain-specific Language for Stencil Computations

F# Web Tools: Rich client/server web applications in F#

The programming language C. sws1 1

Fundamentals of Java Programming

1 External Model Access

Java Application Developer Certificate Program Competencies

Visualization of C++ Template Metaprograms

The C Programming Language course syllabus associate level

Compiling Recursion to Reconfigurable Hardware using CLaSH

A Framework for Extensible Languages

Algorithm & Flowchart & Pseudo code. Staff Incharge: S.Sasirekha

El Dorado Union High School District Educational Services

Asymptotic Improvement of Computations over Free Monads

Categorical Monads and Computer Programming

Guile Present. version 0.3.0, updated 21 September Andy Wingo

Language Evaluation Criteria. Evaluation Criteria: Readability. Evaluation Criteria: Writability. ICOM 4036 Programming Languages

Programming Languages

Chapter 13: Program Development and Programming Languages

Towards a Framework for Generating Tests to Satisfy Complex Code Coverage in Java Pathfinder

Teaching Non-majors Computer Programming Using Games as Context and Flash ActionScript 3.0 as the Development Tools

The previous chapter provided a definition of the semantics of a programming

CSE 307: Principles of Programming Languages

C Compiler Targeting the Java Virtual Machine

Introducing Formal Methods. Software Engineering and Formal Methods

An Eclipse Plug-In for Visualizing Java Code Dependencies on Relational Databases

The Import & Export of Data from a Database

CSCI 3136 Principles of Programming Languages

Characteristics of Java (Optional) Y. Daniel Liang Supplement for Introduction to Java Programming

The Habit Programming Language: The Revised Preliminary Report

Transcription:

Advanced Functional Programming (9) Domain Specific Embedded Languages Advanced Functional Programming (9) Domain Specific Embedded Languages, Universiteit Utrecht http://www.cs.uu.nl/groups/st/ February 28, 2007

Domain Specific Embedded Languages Overview 1 Domain Specific Languages 2 Domain Specific Embedded Languages 3 Growing a language 4 Template Haskell 5 Agenda

Domain Specific Embedded Languages > Domain Specific Languages Domain Specific Languages General purpose language: a programming language for creating various kinds of programs. Domain specific language (DSL): a programming language for one particular problem domain. DSLs offer appropriate notation and abstractions for one domain. Often limited to the domain. Examples: PostScript for page rendering Structured Query Language for accessing a database make macro language for declaring file dependencies L A T E X and bibtex for document preparation

Domain Specific Embedded Languages > Domain Specific Languages Why use a DSL? Because the language is tailored for one problem domain, a DSL is even at a higher level than a high-level language. Ideally, a domain engineer should be able to use a DSL Programs in a DSL are generally easier to write, modify, and reason about. Argument in favor of using DSLs: the initial cost to start using a DSL may be high, but over time it should yield significant savings.

Domain Specific Embedded Languages > Domain Specific Embedded Languages Problems of DSL Don t build a DSL from scratch, but inherit the infrastructure of some other language! This yields a domain specific embedded language A pure embedding: no pre-processor, macro-expander, or generator.

Domain Specific Embedded Languages > Domain Specific Embedded Languages Problems of DSL Don t build a DSL from scratch, but inherit the infrastructure of some other language! This yields a domain specific embedded language A pure embedding: no pre-processor, macro-expander, or generator. What makes Haskell a good host for a DSEL? Higher-order functions Laziness Polymorphism Type classes

Domain Specific Embedded Languages > Domain Specific Embedded Languages Syntax and semantics Slogan: semantics is more important than syntax however, syntax does matter (although it probably isn t the designer s biggest worry) Many semantic details do not matter much (numbers, scoping rules, looping constructs) Idea: borrow design decisions made for host language, and reuse ideas. Advantages: Access to more programming features. (Common evolutionary path a for DSL is to grow to a complex general purpose language hard to find the foundations) Share a common base language (and its tools). Large applications may have more than one DSEL.

Domain Specific Embedded Languages > Domain Specific Embedded Languages Example: geometric region analysis type Region = Point Bool inregion :: Point Region Bool p inregion r = r p circle :: Radius Region outside :: Region Region -- logical negation ( ) :: Region Region Region -- intersection ( ) :: Region Region Region -- union (r1 r2) p = p inregion r1 p inregion r2

Domain Specific Embedded Languages > Domain Specific Embedded Languages Example: geometric region analysis type Region = Point Bool inregion :: Point Region Bool p inregion r = r p circle :: Radius Region outside :: Region Region -- logical negation ( ) :: Region Region Region -- intersection ( ) :: Region Region Region -- union (r1 r2) p = p inregion r1 p inregion r2 Disbelief that this code is executable! Simple to prove associativity of intersection: use equational reasoning (referential transparency), or QuickCheck. (r1 r2) r3 r1 (r2 r3)

Domain Specific Embedded Languages > Domain Specific Embedded Languages Modular algebraic semantics It is important to recognize layers of abstraction for a DSEL (this requires a good understanding of the domain). Good example: two layers in the wxhaskell library. Example: A simple graphics DSEL

Domain Specific Embedded Languages > Domain Specific Embedded Languages Layer 1: pictures -- Atomic objects: circle square bitmap "p.gif" -- a unit circle -- a unit square -- an imported bit-map -- Composite objects: scale v p -- scale picture p by vector v color c p -- color picture p with color c trans v p -- translate picture p by vector v p1 over p2 -- overlay p1 on p2 p1 above p2 -- place p1 above p2 p1 beside p2 -- place p1 beside p2 Nice properties can be proven about this algebra of pictures (e.g., distributive laws, associativity)

Domain Specific Embedded Languages > Domain Specific Embedded Languages Layer 2: animations type Behavior a = Time a type Animation = Behavior Picture (lift1 f b1) t = f (b1 t) (lift2 f b1 b2) t = f (b1 t) (b2 t) colorb = lift2 color sinb = lift1 sin time t = t -- the color may also be time varying wiggle = sinb (pi time) wigglerange lo hi = lo + (hi lo) (wiggle + 1) / 2 ball = colorb red (scaleb (wigglerange 0.5 1) circle) Generalization: we adopt a more generic viewpoint Lifting could be done with type classes (also Num)

Domain Specific Embedded Languages > Domain Specific Embedded Languages Layer 3: reactivity Basic reactive expression has the form b1 until e = b2. ( behave as b1 until event e occurs, then behave as b2 ). until and (= ) are just Haskell functions (although they appear to be primitives!) color (cycle red green blue) circle where cycle c1 c2 c3 = c1 until leftmousebutton = cycle c2 c3 c1 (cycle relies on lazy evaluation)

Domain Specific Embedded Languages > Domain Specific Embedded Languages Advanced Parsing Techniques Another example of a layered DSEL are the parser combinators: Simple combinators (used for the Grammars and Parsing course) Error-correcting parsers Fast online parser (produce output as soon as possible to avoid space-leaks) Self-analyzing parser (recent work by Arthur Baars to cope with a left recursive context-free grammar)

Domain Specific Embedded Languages > Domain Specific Embedded Languages Advanced Parsing Techniques Another example of a layered DSEL are the parser combinators: Simple combinators (used for the Grammars and Parsing course) Error-correcting parsers Fast online parser (produce output as soon as possible to avoid space-leaks) Self-analyzing parser (recent work by Arthur Baars to cope with a left recursive context-free grammar) Although the implementation of the (basic) combinators is getting more and more complicated, the interface is (almost) the same. This is essential for building a successful library.

Domain Specific Embedded Languages > Domain Specific Embedded Languages Building a modular interpreter So far, a DSEL is just about notation. It should be possible to make fundamental changes in the interpreter, even long after the initial design. Describe language features along with their semantics. New features can be added without altering any previous code

Domain Specific Embedded Languages > Domain Specific Embedded Languages Building a modular interpreter So far, a DSEL is just about notation. It should be possible to make fundamental changes in the interpreter, even long after the initial design. Describe language features along with their semantics. New features can be added without altering any previous code Possible approaches: Use monads and monad transformers for constructing building blocks Use an attribute grammar (the Utrecht approach) Template Haskell may also be used to acquire some extensions

Domain Specific Embedded Languages > Growing a language Growing a language Growing a language : brilliant paper by Guy L. Steele Jr. from Sun Microsystems Laboratories (highly recommended to read it yourself) Don t try to design and build The Right Thing : users will not wait for it. Plan for growth: the language must grow as the set of users grows. Library functions should look like primitives. Make it a community-effort: cathedral versus bazaar style.

Domain Specific Embedded Languages > Growing a language Growing a language: Haskell Haskell helps developers to design libraries with a native look-and-feel. For instance, recall (:=) and the on function from wxhaskell. However, not all desired extensions can be expressed within Haskell.

Domain Specific Embedded Languages > Growing a language Growing a language: Haskell Haskell helps developers to design libraries with a native look-and-feel. For instance, recall (:=) and the on function from wxhaskell. However, not all desired extensions can be expressed within Haskell. Some examples: Add syntactic sugar to the language: for instance, list comprehension cannot be introduced within the language Change the evaluation strategy: lazy versus strict Extend the type system: for example, to support generic programming The static analyzer is not aware of DSELs: error messages are still reported in terms of the host language

Domain Specific Embedded Languages > Growing a language Syntax macros Work by Arthur Baars: supply syntax macros to the compiler for adding syntactic sugar to the language. compiler syntax macros abstract syntax (constructors+types) initial grammar (list of parsers) source file macro interpreter compiler output

Domain Specific Embedded Languages > Growing a language Type inference directives Scripting the type inference process (Heeren, Hage, and Swierstra), ICFP 2003. Directives let a compiler report domain specific type error messages. (<$>) :: (a b) Parser s a Parser s b x :: t1; y :: t2; x <$> y :: t3; t1 a1 b1 : left operand is not a function t2 Parser s1 a2 : right operand is not a parser t3 Parser s2 b2 : result type is not a parser s1 s2 : parser has an incorrect symbol type a1 a2 : function cannot be applied to result of parser b1 b2 : parser has an incorrect result type

Domain Specific Embedded Languages > Growing a language Type inference directives Scripting the type inference process (Heeren, Hage, and Swierstra), ICFP 2003. Directives let a compiler report domain specific Use error type error message messages. attributes in the specialized type error messages: (<$>) :: (a b) Parser s a Parser s b t2 Parser s1 a2 : x :: t1; y :: t2; @expr.pos @ : The right operand of <$> should be a parser expression : @expr.pp@ x <$> y :: t3; right operand : @y.pp@ t1 a1type b1 : left: operand @t2@ is not a function t2 Parser does not s1 a2 match : right : Parser operand @s1@ is not @a2@ a parser t3 Parser s2 b2 : result type is not a parser s1 s2 : parser has an incorrect symbol type a1 a2 : function cannot be applied to result of parser b1 b2 : parser has an incorrect result type

Domain Specific Embedded Languages > Growing a language Example A program with a type error: test :: Parser Char String test = map toupper <$> "hello, world!" Compiling this program results in the following type error message: (2, 21) : The right operand of <$> should be a parser expression : map toupper <$> "hello, world!" right operand : "hello, world!" type : String does not match : Parser Char String

Domain Specific Embedded Languages > Template Haskell What is Template Haskell System by Tim Sheard and Simon Peyton Jones. Extension to Haskell that supports compile-time metaprogramming (i.e., algorithmic construction of programs at compile-time). With TH, we can do: Polytypic programming Macro-like expansion User-directed optimization (for instance, inlining) Generation of supporting data structures and functions from existing data structures and functions Implemented in GHC.

Domain Specific Embedded Languages > Template Haskell What is meta-programming? Nice example: C-like printf function in Haskell. printf "Error: %s on line %d." msg line

Domain Specific Embedded Languages > Template Haskell What is meta-programming? Nice example: C-like printf function in Haskell. printf "Error: %s on line %d." msg line We can t define printf in Haskell because its type depends (in a complicated way) on its first parameter. With Template Haskell, we can guarantee type-safety for printf (types for msg and line) compile template code efficiently (for instance, interpret the control string at compile-time) make it user-definable (not a compiler extension)

Domain Specific Embedded Languages > Template Haskell Using printf in Template Haskell $( printf "Error: %s on line %d." ) msg line

Domain Specific Embedded Languages > Template Haskell Using printf in Template Haskell $( printf "Error: %s on line %d." ) msg line $(... ) is special notation ( evaluate at compile-time ). $(... ) is called a splice (not to be confused with Haskell s infix application operator). Conceptually, the splice above generates the following lambda term: (λs 0 λn 1 "Error: " + s 0 + " on line " + show n 1 ) Of course, this term can be assigned a type as any other normal function.

Domain Specific Embedded Languages > Template Haskell Defining printf in Template Haskell printf :: String Expr printf s = gen (parse s) data Format = D S L String parse :: String [Format ] gen :: [Format ] Expr gen [D ] = [ λn show n ] gen [S ] = [ λs s ] gen [L s] = lift s parse is an ordinary Haskell function Simplified implementation of gen: only one format specifier [... ] is called the quasi-quote notation lift lifts a string to a value of type Expr

Domain Specific Embedded Languages > Template Haskell Defining printf in Template Haskell printf :: String Expr printf s = gen (parse s) data Format = D S L String parse :: String [Format ] gen :: [Format ] Expr gen [D ] = [ λn show n ] gen [S ] = [ λs s ] gen [L s] = lift s Let s define gen for an arbitrary number of format specifiers. We use recursion! parse is an ordinary Haskell function Simplified implementation of gen: only one format specifier [... ] is called the quasi-quote notation lift lifts a string to a value of type Expr

Domain Specific Embedded Languages > Template Haskell Defining printf in Template Haskell (2) printf :: String Expr printf s = gen (parse s) [ "" ] data Format = D S L String parse :: String [Format ] gen :: [Format ] Expr Expr gen [ ] x = x gen (D : xs) x = [ λn $( gen xs [ $x + show n ] ) ] gen (S : xs) x = [ λs $( gen xs [ $x + s ] ) ] gen (L s : xs) x = gen xs [ $x + $( lift s ) ] gen uses an accumulating parameter Recursive calls to gen are ran at compile-time Static scoping extends across the template mechanism (task of quotation monad Q)

Domain Specific Embedded Languages > Template Haskell Why templates? High-level languages make programs shorter, easier to maintain, and easier to reason about. Why? The compiler will do the job (most of the times, in a superior way). But what if a programmer knows some particular details? Let the user teach the compiler a new trick. A compiler manipulates programs. TH lets users manipulate their own programs.

Domain Specific Embedded Languages > Template Haskell Why templates? High-level languages make programs shorter, easier to maintain, and easier to reason about. Why? The compiler will do the job (most of the times, in a superior way). But what if a programmer knows some particular details? Let the user teach the compiler a new trick. A compiler manipulates programs. TH lets users manipulate their own programs. 1 Conditional compilation (for different configurations) 2 Program reification (inspect program structure, deriving) 3 Algorithmic program construction (printf ) 4 Abstractions (zip1, zip2, zip3, etcetera) 5 Optimizations (for algebraic laws, in-lining opportunities)

Domain Specific Embedded Languages > Template Haskell Design issues The advantages and disadvantages of TH s design decisions: Compile-time and run-time functions use the same language In contrast with most systems (#if, #define) Existing libraries and programming skills can be used We need explicit annotations for specifying when to execute the code Executed at compile time Allows to do full static analysis (including type inference) May lead to non-terminating compilation

Domain Specific Embedded Languages > Template Haskell Syntax-construction functions Select the first component of a triple: case x of (a, b, c) a

Domain Specific Embedded Languages > Template Haskell Syntax-construction functions Select the first component of a triple: case x of (a, b, c) a With Template Haskell: given that sel :: Int Int Expr sel i n = [ λx case x of... ] $( sel 1 3 ) x

Domain Specific Embedded Languages > Template Haskell Syntax-construction functions Select the first component of a triple: case x of (a, b, c) a With Template Haskell: $( sel 1 3 ) x given that sel :: Int Int Expr sel i n = [ λx case x of... ] We can t write sel with quasi-quoting only

Domain Specific Embedded Languages > Template Haskell Syntax-construction functions (2) sel :: Int Int Expr sel i n = lam [pvar "x"] (casee (var "x") [alt ]) where alt :: Match alt = simplem pat rhs pat :: Patt pat = ptup (map pvar as) rhs :: Expr rhs = var (as!! (i 1)) -- the operator (!!) is zero based as :: [String ] as = ["a" + show i i [1.. n]]

Domain Specific Embedded Languages > Template Haskell Syntax-construction functions (2) sel :: Int -- Int Syntax Expr for patterns sel i n = pvar lam [pvar :: String "x"] (casee Patt (var "x") [alt-- ]) x where ptup :: [Patt ] Patt -- (x, y, z) alt :: pcon Match:: String [Patt ] Patt -- Fork x y alt = pwild simplem :: Patt pat rhs -- pat :: Patt -- Syntax for expressions pat = var ptup (map :: String pvar as) Expr -- x tup :: [Expr ] Expr -- (3, y) rhs :: Expr app :: Expr Expr Expr -- f x rhs = var (as!! (i 1)) -- the operator (!!) is zero based lam :: [Patt ] Expr Expr -- λx y 5 as :: casee [String ] :: Expr [Match] Expr -- case x of... as = simplem ["a" + show :: Patt i iexpr [1.. n]] Match -- x : xs 2

Domain Specific Embedded Languages > Template Haskell Mix the two styles sel :: Int Int Expr sel i n = [ λx $( casee (var "x") [alt ] ) ] where alt = simplem pat rhs pat = ptup (map pvar as) rhs = var (as!! (i 1)) as = ["a" + show i i [1.. n]]

Domain Specific Embedded Languages > Template Haskell Mix the two styles sel :: Int Int Expr sel i n = [ λx $( casee (var "x") [alt ] ) ] where alt = simplem pat rhs pat = ptup (map pvar as) rhs = var (as!! (i 1)) as = ["a" + show i i [1.. n]] Our next challenge: implement an n-ary zip function. $( zipn 3 ) as bs cs

Domain Specific Embedded Languages > Template Haskell zipn: investigate for n = 3 To gain some insight, we first consider what zipn should do for n = 3. zip3 :: [a] [b] [c ] [(a, b, c)] zip3 = let rec = λy1 y2 y3 case (y1, y2, y3) of (x1 : xs1, x2 : xs2, x3 : xs3) (x1, x2, x3) : rec xs1 xs2 xs3 [ ] in rec Recursive definition Quite a lot pattern/expression variables

Domain Specific Embedded Languages > Template Haskell Defining zipn zipn :: Int Expr zipn n = [ let zp = $( mkzip n [ zp ] ) in zp ] mkzip :: Int Expr Expr mkzip n name = lam pys (casee (tup eys) [m1, m2 ]) where (pxs, exs) = genpe "x" n (pys, eys) = genpe "y" n (pxss, exss) = genpe "xs" n pcons x xs = [p $x : $xs ] body = [ $( tup exs ) : $( apps (name : exss) ) ] m1 = simplem (ptup (zipwith pcons pxs pxss)) body m2 = simplem pwild (con "[]") genpe :: String Int ([Pat ], [ExpQ ]) genpe s n = let ns = [s + show i i [1.. n]] in (map pvar ns, map var ns) apps = foldl1 app

Domain Specific Embedded Languages > Template Haskell Defining zipn zipn :: Int Expr zipn n = [ let zp = $( mkzip n [ zp ] ) in zp ] mkzip :: Int Expr Expr mkzip n name = lam pys (casee (tup eys) [m1, m2 ]) where (pxs, exs) = genpe "x" n (pys, eys) = genpe "y" n (pxss, exss) = genpe "xs" n pcons x xs = [p $x : $xs ] body = [ $( tup exs ) : $( apps (name : exss) ) ] m1 = simplem (ptup (zipwith pcons pxs pxss)) body m2 = simplem pwild (con "[]") genpe :: String Int ([Pat ], [ExpQ ]) genpe s n = let ns = [s + show i i [1.. n]] in (map pvar ns, map var ns) apps = foldl1 app apps has an elegant definition

Domain Specific Embedded Languages > Template Haskell Defining zipn Expr is really ExpQ zipn :: Int Expr zipn n = [ let zp = $( mkzip n [ zp ] ) in zp ] mkzip :: Int Expr Expr mkzip n name = lam pys (casee (tup eys) [m1, m2 ]) where (pxs, exs) = genpe "x" n (pys, eys) = genpe "y" n lam should be lame (pxss, exss) = genpe "xs" n pcons x xs = [p $x : $xs ] Pattern quasi-quoting is not yet body = [ $( tup exs ) : $( apps (name supported : exss) ) ] m1 = simplem (ptup (zipwith pcons pxs pxss)) body m2 = simplem pwild (con "[]") genpe :: String Int ([Pat ], [ExpQ ]) con "[]" must be genpe s n = let ns = [s + show i i con [1.."GHC.Base:[]" n]] in (map pvar ns, map var ns) apps = foldl1 app apps has an elegant definition

Domain Specific Embedded Languages > Template Haskell Declaration slicing We can splice in template declarations at top-level. For instance, introduce zip0, zip1,..., zip10. zipdecl :: Int DecQ zipdecl n = vald name body [ ] where name = pvar ("zip" + show n) body = normalb (zipn n) $ (mapm zipdecl [0.. 10]) Question: what is the type of zip0?

Domain Specific Embedded Languages > Template Haskell Reification data Tree a = Node (Tree a) (Tree a) Leaf a reptree :: Decl reptree = reifydecl Tree lengthtype :: Type lengthtype = reifytype length percentfixity :: Q Int percentfixity = reifyfixity (%) here :: Q String here = reifylocn Reification: query the state of the compiler A language construct, not a function!

Domain Specific Embedded Languages > Template Haskell Conclusion Template Haskell provides a powerful, new way of writing programs. Because all meta-code is executed at compile-time, we can still guarantee run-time safety. GHC supports Template Haskell, but the library is not mature yet (see also Section 7.6 of the User s Guide). What will the future bring for TH?

Domain Specific Embedded Languages > Agenda Agenda 1 Read QuickCheck: A Lightweight Tool for Random Testing of Haskell Programs (Koen Claessen and John Hughes). 2 Next week: deadline Exercise 2 (wxhaskell). Next lecture: March 5 (Monday): Debugging and Tracing (and space leaks in particular)