www.it-ebooks.info www.it-ebooks.info Yaron Minsky, Anil Madhavapeddy, and Jason Hickey Real World OCaml www.it-ebooks.info Real World OCaml by Yaron Minsky, Anil Madhavapeddy, and Jason Hickey Copyright © 2014 Yaron Minsky, Anil Madhavapeddy, Jason Hickey. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://my.safaribooksonline.com). For more information, contact our corporate/ institutional sales department: 800-998-9938 or corporate@oreilly.com. Editors: Mike Loukides and Andy Oram Production Editor: Christopher Hearse Copyeditor: Amanda Kersey Proofreader: Becca Freed Indexer: Judith McConville Cover Designer: Randy Comer Interior Designer: David Futato Illustrator: Rebecca Demarest November 2013: First Edition Revision History for the First Edition: 2013-10-31: First release See http://oreilly.com/catalog/errata.csp?isbn=9781449323912 for release details. Nutshell Handbook, the Nutshell Handbook logo, and the O’Reilly logo are registered trademarks of O’Reilly Media, Inc. Real World OCaml, the image of a Bactrian camel, and related trade dress are trademarks of O’Reilly Media, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O’Reilly Media, Inc., was aware of a trade‐ mark claim, the designations have been printed in caps or initial caps. While every precaution has been taken in the preparation of this book, the publisher and authors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein. ISBN: 978-1-449-32391-2 [LSI] www.it-ebooks.info For Lisa, a believer in the power of words, who helps me find mine. —Yaron For Mum and Dad, who took me to the library and unlocked my imagination. —Anil For Nobu, who takes me on a new journey every day. —Jason www.it-ebooks.info www.it-ebooks.info Table of Contents Prologue. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv Part I. Language Concepts 1. A Guided Tour. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 OCaml as a Calculator 3 Functions and Type Inference 5 Type Inference 7 Inferring Generic Types 8 Tuples, Lists, Options, and Pattern Matching 10 Tuples 10 Lists 11 Options 16 Records and Variants 18 Imperative Programming 20 Arrays 20 Mutable Record Fields 21 Refs 22 For and While Loops 23 A Complete Program 25 Compiling and Running 26 Where to Go from Here 26 2. Variables and Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Variables 27 Pattern Matching and let 30 Functions 31 Anonymous Functions 31 Multiargument functions 33 v www.it-ebooks.info Recursive Functions 34 Prefix and Infix Operators 35 Declaring Functions with Function 39 Labeled Arguments 40 Optional Arguments 43 3. Lists and Patterns. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 List Basics 49 Using Patterns to Extract Data from a List 50 Limitations (and Blessings) of Pattern Matching 52 Performance 52 Detecting Errors 54 Using the List Module Effectively 55 More Useful List Functions 58 Tail Recursion 61 Terser and Faster Patterns 63 4. Files, Modules, and Programs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Single-File Programs 67 Multifile Programs and Modules 70 Signatures and Abstract Types 71 Concrete Types in Signatures 74 Nested Modules 75 Opening Modules 77 Including Modules 79 Common Errors with Modules 81 Type Mismatches 81 Missing Definitions 81 Type Definition Mismatches 81 Cyclic Dependencies 82 Designing with Modules 83 Expose Concrete Types Rarely 83 Design for the Call Site 84 Create Uniform Interfaces 84 Interfaces before implementations 85 5. Records. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 Patterns and Exhaustiveness 88 Field Punning 91 Reusing Field Names 92 Functional Updates 96 Mutable Fields 97 vi | Table of Contents www.it-ebooks.info First-Class Fields 98 6. Variants. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Catch-All Cases and Refactoring 105 Combining Records and Variants 107 Variants and Recursive Data Structures 111 Polymorphic Variants 114 Example: Terminal Colors Redux 116 When to Use Polymorphic Variants 121 7. Error Handling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Error-Aware Return Types 123 Encoding Errors with Result 125 Error and Or_error 125 bind and Other Error Handling Idioms 127 Exceptions 128 Helper Functions for Throwing Exceptions 131 Exception Handlers 132 Cleaning Up in the Presence of Exceptions 132 Catching Specific Exceptions 133 Backtraces 135 From Exceptions to Error-Aware Types and Back Again 137 Choosing an Error-Handling Strategy 138 8. Imperative Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Example: Imperative Dictionaries 139 Primitive Mutable Data 143 Array-Like Data 143 Mutable Record and Object Fields and Ref Cells 145 Foreign Functions 146 for and while Loops 146 Example: Doubly Linked Lists 147 Modifying the List 149 Iteration Functions 150 Laziness and Other Benign Effects 151 Memoization and Dynamic Programming 153 Input and Output 159 Terminal I/O 160 Formatted Output with printf 161 File I/O 163 Order of Evaluation 165 Side Effects and Weak Polymorphism 167 Table of Contents | vii www.it-ebooks.info The Value Restriction 168 Partial Application and the Value Restriction 170 Relaxing the Value Restriction 170 Summary 173 9. Functors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 A Trivial Example 176 A Bigger Example: Computing with Intervals 177 Making the Functor Abstract 181 Sharing Constraints 182 Destructive Substitution 184 Using Multiple Interfaces 185 Extending Modules 189 10. First-Class Modules. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 Working with First-Class Modules 193 Example: A Query-Handling Framework 199 Implementing a Query Handler 200 Dispatching to Multiple Query Handlers 202 Loading and Unloading Query Handlers 205 Living Without First-Class Modules 208 11. Objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 OCaml Objects 212 Object Polymorphism 213 Immutable Objects 215 When to Use Objects 216 Subtyping 217 Width Subtyping 217 Depth Subtyping 218 Variance 219 Narrowing 222 Subtyping Versus Row Polymorphism 224 12. Classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 OCaml Classes 227 Class Parameters and Polymorphism 228 Object Types as Interfaces 230 Functional Iterators 232 Inheritance 233 Class Types 234 Open Recursion 235 viii | Table of Contents www.it-ebooks.info [...]... sophisticated applications in OCaml Code that uses only the traditional compiler standard library will always exist, but there are other online resources for learning how that works Real World OCaml focuses on the techniques the authors have used in their personal experience to construct scalable, robust software systems xviii | Prologue www.it-ebooks.info What to Expect Real World OCaml is split into three... easier-to-use version of OCaml s standard toplevel (which you can start by typing ocaml at the command line) These instructions will assume you’re using utop specifically Before getting started, make sure you have a working OCaml installation so you can try out the examples as you read through the chapter OCaml as a Calculator The first thing you need to do when using Core is to open Core.Std: OCaml utop $ utop... This Book Real World OCaml is aimed at programmers who have some experience with conven‐ tional programming languages, but not specifically with statically typed functional pro‐ gramming Depending on your background, many of the concepts we cover will be new, including traditional functional-programming techniques like higher-order functions and immutable data types, as well as aspects of OCaml s powerful... Automatically Mapping JSON to OCaml Types ATD Basics ATD Annotations Compiling ATD Specifications to OCaml Example: Querying GitHub Organization Information 293 294 296 300 302 303 304 305 305 307 16 Parsing with OCamllex and Menhir 311 Lexing and Parsing Defining a Parser Describing the Grammar Parsing Sequences Defining a Lexer OCaml Prelude Regular Expressions... discusses OCaml s runtime system and compiler toolchain It is remarkably simple when compared to some other language implementations (such as Java’s or NET’s CLR) Reading this part will enable you to build very-high-performance systems, or to interface with C libraries This is also where we talk about profiling and debugging techniques using tools such as GNU gdb Installation Instructions Real World OCaml. .. of these resulted in improvements to the OCaml compiler, which means that you will need to ensure that you have an up-to-date development environment (using the 4.01 version of the compiler) The installation process is largely automated through the OPAM package manager Instructions on how to it set up and what packages to install can be found at this Real World OCaml page As of publication time, the... providing a clear guide to what you need to know to use OCaml effectively in the real world What makes OCaml special is that it occupies a sweet spot in the space of programming language designs It provides a combination of efficiency, expressiveness and practicality that is matched by no other language That is in large part because OCaml is an elegant combination of a few key language features that have been... different types, lists let you hold any number of items of the same type Consider the following example: OCaml utop (part 20) # let languages = [ "OCaml" ;"Perl";"C"];; val languages : string list = [ "OCaml" ; "Perl"; "C"] Note that you can’t mix elements of different types in the same list, unlike tuples: OCaml utop (part 21) # let numbers = [3;"four";5];; Characters 17-23: Error: This expression has type... "French" :: "Spanish" :: languages;; - : string list = ["French"; "Spanish"; "OCaml" ; "Perl"; "C"] Here, we’re creating a new and extended list, not changing the list we started with, as you can see below: OCaml utop (part 26) # languages;; - : string list = [ "OCaml" ; "Perl"; "C"] Semicolons Versus Commas Unlike many other languages, OCaml uses semicolons to separate list elements in lists rather than commas... quite what you might expect: OCaml utop (part 27) # [ "OCaml" , "Perl", "C"];; - : (string * string * string) list = [( "OCaml" , "Perl", "C")] In particular, rather than a list of three strings, what we have is a singleton list containing a three-tuple of strings This example uncovers the fact that commas create a tuple, even if there are no surrounding parens So, we can write: OCaml utop (part 28) # 1,2,3;; . www.it-ebooks.info www.it-ebooks.info Yaron Minsky, Anil Madhavapeddy, and Jason Hickey Real World OCaml www.it-ebooks.info Real World OCaml by Yaron Minsky, Anil Madhavapeddy, and Jason Hickey Copyright © 2014. wider audience, by providing a clear guide to what you need to know to use OCaml effectively in the real world. What makes OCaml special is that it occupies a sweet spot in the space of programming language. applications in OCaml. Code that uses only the traditional compiler standard library will always exist, but there are other online resources for learning how that works. Real World OCaml focuses