An Optimized R5RS Macro Expander
Total Page:16
File Type:pdf, Size:1020Kb
Brigham Young University BYU ScholarsArchive Theses and Dissertations 2013-02-05 An Optimized R5RS Macro Expander Sean P. Reque Brigham Young University - Provo Follow this and additional works at: https://scholarsarchive.byu.edu/etd Part of the Computer Sciences Commons BYU ScholarsArchive Citation Reque, Sean P., "An Optimized R5RS Macro Expander" (2013). Theses and Dissertations. 3509. https://scholarsarchive.byu.edu/etd/3509 This Thesis is brought to you for free and open access by BYU ScholarsArchive. It has been accepted for inclusion in Theses and Dissertations by an authorized administrator of BYU ScholarsArchive. For more information, please contact [email protected], [email protected]. An Optimized R5RS Macro Expander Sean Reque A thesis submitted to the faculty of Brigham Young University in partial fulfillment of the requirements for the degree of Master of Science Jay McCarthy, Chair Eric Mercer Quinn Snell Department of Computer Science Brigham Young University February 2013 Copyright c 2013 Sean Reque All Rights Reserved ABSTRACT An Optimized R5RS Macro Expander Sean Reque Department of Computer Science, BYU Master of Science Macro systems allow programmers abstractions over the syntax of a programming language. This gives the programmer some of the same power posessed by a programming language designer, namely, the ability to extend the programming language to fit the needs of the programmer. The value of such systems has been demonstrated by their continued adoption in more languages and platforms. However, several barriers to widespread adoption of macro systems still exist. The language Racket [6] defines a small core of primitive language constructs, including a powerful macro system, upon which all other features are built. Because of this design, many features of other programming languages can be implemented through libraries, keeping the core language simple without sacrificing power or flexibility. However, slow macro expansion remains a lingering problem in the language's primary implementation, and in fact macro expansion currently dominates compile times for Racket modules and programs. Besides the typical problems associated with slow compile times, such as slower testing feedback, increased mental disruption during the programming process, and unscalable build times for large projects, slow macro expansion carries its own unique problems, such as poorer performance for IDEs and other software analysis tools. In order to improve macro expansion times for Racket, we implement an existing expansion algorithm for R5RS Scheme macros, which comprise a subset of Racket's macro system, and use that implementation to explore optimization opportunities. Our resulting expander appears to be the fastest implementation of a R5RS macro expander in a high-level language and performs several times faster than the existing C-based Racket implementation. Keywords: Macros, R5RS, Optimizations, Expander ACKNOWLEDGMENTS Without the support and guidance provided by Dr. McCarthy, this work would not have been possible. I am also indebted to BYU for providing an excellent learning environment and culture. I last of all thank my family for being the teachers in the most important school of my life. Table of Contents List of Figures viii List of Tables ix 1 Introduction 1 1.1 Thesis Statement . .1 1.2 Scheme Macros . .1 1.3 R5RS Scheme . .3 1.4 Problems with Conventional Macro Systems . .6 1.5 Related Work . 11 1.5.1 Gensym . 11 1.5.2 Timestamp Expander . 12 1.5.3 Syntactic Closures . 13 1.5.4 Explicit Renaming . 13 1.5.5 Mark/Antimark . 14 1.5.6 Fast Imperative Expander . 15 1.5.7 MetaML and MacroML . 15 1.5.8 Template Haskell . 16 1.5.9 Nemerle . 17 1.6 Optimization Approach . 17 1.7 Summary . 18 2 Explicit Renaming Algorithm 19 iv 2.1 Algorithm Overview . 19 2.2 R5RS syntax-rules ................................ 21 2.2.1 syntax-rules Grammar . 21 2.2.2 Interpreting syntax-rules Definitions . 23 2.2.3 Implementation Concerns . 25 2.3 Example Macro Expansion . 26 2.4 Summary . 29 3 Correctness and Performance Verification 30 3.1 Correctness and Performance Tests . 30 3.2 Testing Hardware . 30 3.3 Performance Goals . 31 3.4 Test Programs . 32 3.4.1 CK . 32 3.4.2 Dirty R5RS . 32 3.4.3 Macro Lambda . 33 3.4.4 Prime Numbers and the Sieve of Eratosthenes . 33 3.4.5 Fibonacci . 33 3.4.6 Schelog . 34 3.4.7 Monads . 34 3.5 Benchmarked Implementations . 35 3.5.1 Gambit . 35 3.5.2 Chicken . 35 3.5.3 Ikarus . 35 3.5.4 Chez . 36 3.5.5 Racket . 36 3.5.6 Fast Imperative Expander . 36 3.5.7 Other expanders . 36 v 3.6 Initial Benchmark Results . 36 3.7 Summary . 40 4 Optimizations 42 4.1 Data Structure Optimizations . 43 4.1.1 Pattern Matching Environment . 43 4.1.2 Template Regular Identifier Environments . 43 4.1.3 Removing the Quote Environment . 44 4.2 Lazy Computation Optimizations . 44 4.2.1 Lazy List Matching . 44 4.2.2 No Match Failure Diagnostics . 47 4.3 Redundant Computation Optimizations . 47 4.3.1 Unsafe Operations . 47 4.3.2 Optimizing body expansion . 49 4.3.3 Template List Rewriting . 50 4.4 Static Analysis Optimizations . 52 4.4.1 Constant Wrapping . 52 4.4.2 Template Pre-expansion . 52 4.4.3 Identifier Analysis . 54 4.5 Other Racket-Specific Optimizations . 56 4.5.1 Racket Keyword Arguments . 56 4.5.2 Hasheq vs Hash . 56 4.6 Optimization Results . 56 4.6.1 Lazy List Matching . 56 4.6.2 Unsafe Operations . 57 4.6.3 No Error Diagnosis . 58 4.6.4 Optimized Body Expansion . 58 4.6.5 Pattern Environment Vectors and Regular Identifier Vectors . 59 vi 4.6.6 Quote Environment Removal . 59 4.6.7 Optimized Template List Rewriting . 59 4.6.8 Hasheq and Keyword Arguments . 60 4.6.9 Template Pre-expansion . 60 4.6.10 Binding Inference . 60 4.6.11 Final Results . 61 4.7 Summary . 66 5 Conclusions 67 5.1 Current Issues . 68 5.2 Future Work . 68 5.3 Final Thoughts . 69 References 71 vii List of Figures 1.1 An example showing the use of the "and" macro with its subsequent expansion. 6 2.1 Explicit Renaming Example . 20 2.2 Simplified let definition and example use . 26 3.1 Initial \Heavyweight" Benchmarks . 38 3.2 Initial \Lightweight" Benchmarks . 39 4.1 R5RS letrec Definition . 46 4.2 Recursive rule of letrec . 46 4.3 Base case of letrec . 46 4.4 Optimized letrec pseudocode . 49 4.5 Specialized Definitions of map and foldr . 51 4.6 An example of template pre-expansion using the assert-eq macro . 53 4.7 Definition of glambda from the \dirtier macros" benchmark . 55 4.8 Impact of Optimizations on `Heavyweight' Benchmarks . 62 4.9 Impact of Optimizations on `Lightweight' Benchmarks . 63 4.10 Final \Heavyweight" Benchmarks . 64 4.11 Final \Lightweight" Benchmarks . 65 viii List of Tables 2.1 Simplified R5RS syntax-rules Grammar . 22 2.2 The Top-level Sub-Patterns, Matched Syntax, and Output Environments . 27 2.3 Sub-Templates of lambda Template and Their Output Syntax . 28 3.1 Benchmark Programs . 37 4.1 Mean and Median Performance Deltas Per Optimization . 57 ix Chapter 1 Introduction 1.1 Thesis Statement R5RS macro expansion can be optimized to enable the expansion of Scheme programs in a fraction of the time required by.