Open Pattern Matching for C++

Total Page:16

File Type:pdf, Size:1020Kb

Open Pattern Matching for C++ Open Pattern Matching for C++ Yuriy Solodkyy Gabriel Dos Reis Bjarne Stroustrup Texas A&M University College Station, Texas, USA fyuriys,gdr,[email protected] Abstract 1.1 Summary Pattern matching is an abstraction mechanism that can greatly sim- We present functional-style pattern matching for C++ built as an plify source code. We present functional-style pattern matching for ISO C++11 library. Our solution: C++ implemented as a library, called Mach71. All the patterns are • is open to the introduction of new patterns into the library, while user-definable, can be stored in variables, passed among functions, not making any assumptions about existing ones. and allow the use of class hierarchies. As an example, we imple- • is type safe: inappropriate applications of patterns to subjects ment common patterns used in functional languages. are compile-time errors. Our approach to pattern matching is based on compile-time • Makes patterns first-class citizens in the language (§3.1). composition of pattern objects through concepts. This is superior • is non-intrusive, so that it can be retroactively applied to exist- (in terms of performance and expressiveness) to approaches based ing types (§3.2). on run-time composition of polymorphic pattern objects. In partic- • provides a unified syntax for various encodings of extensible ular, our solution allows mapping functional code based on pattern hierarchical datatypes in C++. matching directly into C++ and produces code that is only a few • provides an alternative interpretation of the controversial n+k percent slower than hand-optimized C++ code. patterns (in line with that of constructor patterns), leaving the The library uses an efficient type switch construct, further ex- choice of exact semantics to the user (§3.3). tending it to multiple scrutinees and general patterns. We compare • supports a limited form of views (§3.4). the performance of pattern matching to that of double dispatch and • generalizes open type switch to multiple scrutinees and enables open multi-methods in C++. patterns in case clauses (§3.5). • demonstrates that compile-time composition of patterns through Categories and Subject Descriptors D.1.5 [Programming tech- concepts is superior to run-time composition of patterns through niques]: Object-oriented Programming; D.3.3 [Programming Lan- polymorphic interfaces in terms of performance, expressive- guages]: Language Constructs and Features ness, and static type checking (§4.1). General Terms Languages, Design Our library sets a standard for the performance, extensibility, brevity, clarity, and usefulness of any language solution for pat- Keywords Pattern Matching, C++ tern matching. It provides full functionality, so we can experiment with the use of pattern matching in C++ and compare it to existing 1. Introduction alternatives. Our solution requires only current support of C++11 Pattern matching is an abstraction mechanism popularized by without any additional tool support. the functional programming community, most notably ML [12], OCaml [21], and Haskell [15], and recently adopted by several 2. Pattern Matching in C++ multi-paradigm and object-oriented programming languages such The object analyzed through pattern matching is commonly called as Scala [30], F# [7], and dialects of C++[22, 29]. The expressive the scrutinee or subject, while its static type is commonly called power of pattern matching has been cited as the number one reason the subject type. Consider for example the following definition of for choosing a functional language for a task [6, 25, 28]. factorial in Mach7: This paper presents functional-style pattern matching for C++. To allow experimentation and to be able to use production-quality int factorial(int n) f toolchains (in particular, compilers and optimizers), we imple- unsigned short m; mented our matching facilities as a C++ library. Match(n) f Case(0) return 1; 1 The library is available at http://parasol.tamu.edu/mach7/ Case(m) return m∗factorial(m−1); Case( ) throw std::invalid argument(”factorial”); g EndMatch Permission to make digital or hard copies of all or part of this work for personal or g classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation The subject n is passed as an argument to the Match statement on the first page. Copyrights for components of this work owned by others than ACM and is then analyzed through Case clauses that list various pat- must be honored. Abstracting with credit is permitted. To copy otherwise, or republish, terns. In the first-fit strategy typically adopted by functional lan- to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. Request permissions from [email protected]. guages, the matching proceeds in sequential order while the pat- GPCE ’13, October 27–28, 2013, Indianapolis, Indiana, USA. terns guarding their respective clauses are rejected. Eventually, the Copyright © 2013 ACM 978-1-4503-2373-4/13/10. $15.00. statement guarded by the first accepted pattern is executed or the http://dx.doi.org/10.1145/2517208.2517222 control reaches the end of the Match statement. The value 0 in the first case clause is an example of a value pat- This == is an example of a binary method: an operation that re- tern. It will match only when the subject n is 0. The variable m in quires both arguments to have the same type [3]. In each of the the second case clause is an example of a variable pattern. It will case clauses, we check that both subjects are of the same dynamic bind to any value that can be represented by its type. The name in type using a constructor pattern. We then decompose both subjects the last case clause refers to the common instance of the wildcard into components and compare them for equality with the help of a pattern. Value, variable, and wildcard patterns are typically referred variable pattern and an equivalence combinator (‘+’) applied to it. to as primitive patterns. The list of primitive patterns is often ex- The use of an equivalence combinator turns a binding use of a vari- tended with a predicate pattern (e.g. as seen in Scheme [49]), which able pattern into a non-binding use of that variable’s current value allows the use of any unary predicate or nullary member-predicate as a value pattern. We chose to overload unary + because in C++ it as a pattern: e.g. Case(even) ::: (assuming bool even(int);) or turns an l-value into an r-value, which has a similar semantics here. Case([](int m) f return m^m−1; g) ::: for λ-expressions. In general, a pattern combinator is an operation on patterns The predicate pattern is a use of a predicate as a pattern and to produce a new pattern. Other typical pattern combinators, sup- should not be confused with a guard, which is a predicate attached ported by many languages, are conjunction, disjunction and nega- to a pattern that may make use of the variables bound in it. The tion combinators, which all have an intuitive Boolean interpreta- result of the guard’s evaluation will determine whether the case tion. We add a few non-standard combinators to Mach7 that reflect clause and the body associated with it will be accepted or rejected. the specifics of C++, e.g. the presence of pointers and references. Guards gives rise to guard patterns, which in Mach7 are expres- The equality operator on λ-terms demonstrates both nesting of sions of the form P j=E, where P is a pattern and E is its guard. patterns and relational matching. The variable pattern was nested Pattern matching is closely related to algebraic data types. within an equivalence pattern, which in turn was nested inside In ML and Haskell, an Algebraic Data Type is a data type each a constructor pattern. The matching was also relational because of whose values are picked from a disjoint sum of data types, we could relate the state of two subjects. Both aspects are even called variants. Each variant is a product type marked with a better demonstrated in the following well-known functional so- unique symbolic constant called a constructor. Each construc- lution to balancing red-black trees with pattern matching due to tor provides a convenient way of creating a value of its vari- Chris Okasaki [32, §3.3] implemented in Mach7: ant type as well as discriminating among variants through pat- class Tfenum colorfblack,redg col; T∗ left; K key; T∗ right;g; tern matching. In particular, given an algebraic data type D = C1(T11; :::; T1m )S⋯SCk(Tk1; :::; Tkm ) an expression of the form T∗ balance(T::color clr, T∗ left, const K& key, T∗ right) f 1 k const T::color B = T::black, R = T::red; Ci(x1; :::; xmi ) in a non-pattern-matching context is called a value constructor and refers to a value of type D created via the construc- var⟨T∗⟩ a, b, c, d; var⟨K&⟩ x, y, z; T::color col; Match(clr, left, key, right) f tor Ci and its arguments x1; :::; xmi . The same expression in the pattern-matching context is called a constructor pattern and is used Case(B, C⟨T⟩(R, C⟨T⟩(R, a, x, b), y, c), z, d) ::: to check whether the subject is of type D and was created with the Case(B, C⟨T⟩(R, a, x,C⟨T⟩(R, b, y, c)), z, d) ::: constructor Ci. If so, it matches the actual values it was constructed Case(B, a, x,C⟨T⟩(R, C⟨T⟩(R, b, y, c), z, d)) ::: with against the nested patterns xj .
Recommended publications
  • Programming the Capabilities of the PC Have Changed Greatly Since the Introduction of Electronic Computers
    1 www.onlineeducation.bharatsevaksamaj.net www.bssskillmission.in INTRODUCTION TO PROGRAMMING LANGUAGE Topic Objective: At the end of this topic the student will be able to understand: History of Computer Programming C++ Definition/Overview: Overview: A personal computer (PC) is any general-purpose computer whose original sales price, size, and capabilities make it useful for individuals, and which is intended to be operated directly by an end user, with no intervening computer operator. Today a PC may be a desktop computer, a laptop computer or a tablet computer. The most common operating systems are Microsoft Windows, Mac OS X and Linux, while the most common microprocessors are x86-compatible CPUs, ARM architecture CPUs and PowerPC CPUs. Software applications for personal computers include word processing, spreadsheets, databases, games, and myriad of personal productivity and special-purpose software. Modern personal computers often have high-speed or dial-up connections to the Internet, allowing access to the World Wide Web and a wide range of other resources. Key Points: 1. History of ComputeWWW.BSSVE.INr Programming The capabilities of the PC have changed greatly since the introduction of electronic computers. By the early 1970s, people in academic or research institutions had the opportunity for single-person use of a computer system in interactive mode for extended durations, although these systems would still have been too expensive to be owned by a single person. The introduction of the microprocessor, a single chip with all the circuitry that formerly occupied large cabinets, led to the proliferation of personal computers after about 1975. Early personal computers - generally called microcomputers - were sold often in Electronic kit form and in limited volumes, and were of interest mostly to hobbyists and technicians.
    [Show full text]
  • Certification of a Tool Chain for Deductive Program Verification Paolo Herms
    Certification of a Tool Chain for Deductive Program Verification Paolo Herms To cite this version: Paolo Herms. Certification of a Tool Chain for Deductive Program Verification. Other [cs.OH]. Université Paris Sud - Paris XI, 2013. English. NNT : 2013PA112006. tel-00789543 HAL Id: tel-00789543 https://tel.archives-ouvertes.fr/tel-00789543 Submitted on 18 Feb 2013 HAL is a multi-disciplinary open access L’archive ouverte pluridisciplinaire HAL, est archive for the deposit and dissemination of sci- destinée au dépôt et à la diffusion de documents entific research documents, whether they are pub- scientifiques de niveau recherche, publiés ou non, lished or not. The documents may come from émanant des établissements d’enseignement et de teaching and research institutions in France or recherche français ou étrangers, des laboratoires abroad, or from public or private research centers. publics ou privés. UNIVERSITÉ DE PARIS-SUD École doctorale d’Informatique THÈSE présentée pour obtenir le Grade de Docteur en Sciences de l’Université Paris-Sud Discipline : Informatique PAR Paolo HERMS −! − SUJET : Certification of a Tool Chain for Deductive Program Verification soutenue le 14 janvier 2013 devant la commission d’examen MM. Roberto Di Cosmo Président du Jury Xavier Leroy Rapporteur Gilles Barthe Rapporteur Emmanuel Ledinot Examinateur Burkhart Wolff Examinateur Claude Marché Directeur de Thèse Benjamin Monate Co-directeur de Thèse Jean-François Monin Invité Résumé Cette thèse s’inscrit dans le domaine de la vérification du logiciel. Le but de la vérification du logiciel est d’assurer qu’une implémentation, un programme, répond aux exigences, satis- fait sa spécification. Cela est particulièrement important pour le logiciel critique, tel que des systèmes de contrôle d’avions, trains ou centrales électriques, où un mauvais fonctionnement pendant l’opération aurait des conséquences catastrophiques.
    [Show full text]
  • Presentation on Ocaml Internals
    OCaml Internals Implementation of an ML descendant Theophile Ranquet Ecole Pour l’Informatique et les Techniques Avancées SRS 2014 [email protected] November 14, 2013 2 of 113 Table of Contents Variants and subtyping System F Variants Type oddities worth noting Polymorphic variants Cyclic types Subtyping Weak types Implementation details α ! β Compilers Functional programming Values Why functional programming ? Allocation and garbage Combinatory logic : SKI collection The Curry-Howard Compiling correspondence Type inference OCaml and recursion 3 of 113 Variants A tagged union (also called variant, disjoint union, sum type, or algebraic data type) holds a value which may be one of several types, but only one at a time. This is very similar to the logical disjunction, in intuitionistic logic (by the Curry-Howard correspondance). 4 of 113 Variants are very convenient to represent data structures, and implement algorithms on these : 1 d a t a t y p e tree= Leaf 2 | Node of(int ∗ t r e e ∗ t r e e) 3 4 Node(5, Node(1,Leaf,Leaf), Node(3, Leaf, Node(4, Leaf, Leaf))) 5 1 3 4 1 fun countNodes(Leaf)=0 2 | countNodes(Node(int,left,right)) = 3 1 + countNodes(left)+ countNodes(right) 5 of 113 1 t y p e basic_color= 2 | Black| Red| Green| Yellow 3 | Blue| Magenta| Cyan| White 4 t y p e weight= Regular| Bold 5 t y p e color= 6 | Basic of basic_color ∗ w e i g h t 7 | RGB of int ∗ i n t ∗ i n t 8 | Gray of int 9 1 l e t color_to_int= function 2 | Basic(basic_color,weight) −> 3 l e t base= match weight with Bold −> 8 | Regular −> 0 in 4 base+ basic_color_to_int basic_color 5 | RGB(r,g,b) −> 16 +b+g ∗ 6 +r ∗ 36 6 | Grayi −> 232 +i 7 6 of 113 The limit of variants Say we want to handle a color representation with an alpha channel, but just for color_to_int (this implies we do not want to redefine our color type, this would be a hassle elsewhere).
    [Show full text]
  • An Efficient Implementation of Guard-Based Synchronization for an Object-Oriented Programming Language an Efficient Implementation of Guard-Based
    AN EFFICIENT IMPLEMENTATION OF GUARD-BASED SYNCHRONIZATION FOR AN OBJECT-ORIENTED PROGRAMMING LANGUAGE AN EFFICIENT IMPLEMENTATION OF GUARD-BASED SYNCHRONIZATION FOR AN OBJECT-ORIENTED PROGRAMMING LANGUAGE By SHUCAI YAO, M.Sc., B.Sc. A Thesis Submitted to the Department of Computing and Software and the School of Graduate Studies of McMaster University in Partial Fulfilment of the Requirements for the Degree of Doctor of Philosophy McMaster University c Copyright by Shucai Yao, July 2020 Doctor of Philosophy (2020) McMaster University (Computing and Software) Hamilton, Ontario, Canada TITLE: An Efficient Implementation of Guard-Based Synchro- nization for an Object-Oriented Programming Language AUTHOR: Shucai Yao M.Sc., (Computer Science) University of Science and Technology Beijing B.Sc., (Computer Science) University of Science and Technology Beijing SUPERVISOR: Dr. Emil Sekerinski, Dr. William M. Farmer NUMBER OF PAGES: xvii,167 ii To my beloved family Abstract Object-oriented programming has had a significant impact on software development because it provides programmers with a clear structure of a large system. It encap- sulates data and operations into objects, groups objects into classes and dynamically binds operations to program code. With the emergence of multi-core processors, application developers have to explore concurrent programming to take full advan- tage of multi-core technology. However, when it comes to concurrent programming, object-oriented programming remains elusive as a useful programming tool. Most object-oriented programming languages do have some extensions for con- currency, but concurrency is implemented independently of objects: for example, concurrency in Java is managed separately with the Thread object. We employ a programming model called Lime that combines action systems tightly with object- oriented programming and implements concurrency by extending classes with actions and guarded methods.
    [Show full text]
  • Comparative Studies of Programming Languages; Course Lecture Notes
    Comparative Studies of Programming Languages, COMP6411 Lecture Notes, Revision 1.9 Joey Paquet Serguei A. Mokhov (Eds.) August 5, 2010 arXiv:1007.2123v6 [cs.PL] 4 Aug 2010 2 Preface Lecture notes for the Comparative Studies of Programming Languages course, COMP6411, taught at the Department of Computer Science and Software Engineering, Faculty of Engineering and Computer Science, Concordia University, Montreal, QC, Canada. These notes include a compiled book of primarily related articles from the Wikipedia, the Free Encyclopedia [24], as well as Comparative Programming Languages book [7] and other resources, including our own. The original notes were compiled by Dr. Paquet [14] 3 4 Contents 1 Brief History and Genealogy of Programming Languages 7 1.1 Introduction . 7 1.1.1 Subreferences . 7 1.2 History . 7 1.2.1 Pre-computer era . 7 1.2.2 Subreferences . 8 1.2.3 Early computer era . 8 1.2.4 Subreferences . 8 1.2.5 Modern/Structured programming languages . 9 1.3 References . 19 2 Programming Paradigms 21 2.1 Introduction . 21 2.2 History . 21 2.2.1 Low-level: binary, assembly . 21 2.2.2 Procedural programming . 22 2.2.3 Object-oriented programming . 23 2.2.4 Declarative programming . 27 3 Program Evaluation 33 3.1 Program analysis and translation phases . 33 3.1.1 Front end . 33 3.1.2 Back end . 34 3.2 Compilation vs. interpretation . 34 3.2.1 Compilation . 34 3.2.2 Interpretation . 36 3.2.3 Subreferences . 37 3.3 Type System . 38 3.3.1 Type checking . 38 3.4 Memory management .
    [Show full text]
  • An Overview of the Scala Programming Language
    An Overview of the Scala Programming Language Second Edition Martin Odersky, Philippe Altherr, Vincent Cremet, Iulian Dragos Gilles Dubochet, Burak Emir, Sean McDirmid, Stéphane Micheloud, Nikolay Mihaylov, Michel Schinz, Erik Stenman, Lex Spoon, Matthias Zenger École Polytechnique Fédérale de Lausanne (EPFL) 1015 Lausanne, Switzerland Technical Report LAMP-REPORT-2006-001 Abstract guage for component software needs to be scalable in the sense that the same concepts can describe small as well as Scala fuses object-oriented and functional programming in large parts. Therefore, we concentrate on mechanisms for a statically typed programming language. It is aimed at the abstraction, composition, and decomposition rather than construction of components and component systems. This adding a large set of primitives which might be useful for paper gives an overview of the Scala language for readers components at some level of scale, but not at other lev- who are familar with programming methods and program- els. Second, we postulate that scalable support for compo- ming language design. nents can be provided by a programming language which unies and generalizes object-oriented and functional pro- gramming. For statically typed languages, of which Scala 1 Introduction is an instance, these two paradigms were up to now largely separate. True component systems have been an elusive goal of the To validate our hypotheses, Scala needs to be applied software industry. Ideally, software should be assembled in the design of components and component systems. Only from libraries of pre-written components, just as hardware is serious application by a user community can tell whether the assembled from pre-fabricated chips.
    [Show full text]
  • “Scrap Your Boilerplate” Reloaded
    “Scrap Your Boilerplate” Reloaded Ralf Hinze1, Andres L¨oh1, and Bruno C. d. S. Oliveira2 1 Institut f¨urInformatik III, Universit¨atBonn R¨omerstraße164, 53117 Bonn, Germany {ralf,loeh}@informatik.uni-bonn.de 2 Oxford University Computing Laboratory Wolfson Building, Parks Road, Oxford OX1 3QD, UK [email protected] Abstract. The paper “Scrap your boilerplate” (SYB) introduces a com- binator library for generic programming that offers generic traversals and queries. Classically, support for generic programming consists of two es- sential ingredients: a way to write (type-)overloaded functions, and in- dependently, a way to access the structure of data types. SYB seems to lack the second. As a consequence, it is difficult to compare with other approaches such as PolyP or Generic Haskell. In this paper we reveal the structural view that SYB builds upon. This allows us to define the combinators as generic functions in the classical sense. We explain the SYB approach in this changed setting from ground up, and use the un- derstanding gained to relate it to other generic programming approaches. Furthermore, we show that the SYB view is applicable to a very large class of data types, including generalized algebraic data types. 1 Introduction The paper “Scrap your boilerplate” (SYB) [1] introduces a combinator library for generic programming that offers generic traversals and queries. Classically, support for generic programming consists of two essential ingredients: a way to write (type-)overloaded functions, and independently, a way to access the structure of data types. SYB seems to lacks the second, because it is entirely based on combinators.
    [Show full text]
  • Notes on Functional Programming with Haskell
    Notes on Functional Programming with Haskell H. Conrad Cunningham [email protected] Multiparadigm Software Architecture Group Department of Computer and Information Science University of Mississippi 201 Weir Hall University, Mississippi 38677 USA Fall Semester 2014 Copyright c 1994, 1995, 1997, 2003, 2007, 2010, 2014 by H. Conrad Cunningham Permission to copy and use this document for educational or research purposes of a non-commercial nature is hereby granted provided that this copyright notice is retained on all copies. All other rights are reserved by the author. H. Conrad Cunningham, D.Sc. Professor and Chair Department of Computer and Information Science University of Mississippi 201 Weir Hall University, Mississippi 38677 USA [email protected] PREFACE TO 1995 EDITION I wrote this set of lecture notes for use in the course Functional Programming (CSCI 555) that I teach in the Department of Computer and Information Science at the Uni- versity of Mississippi. The course is open to advanced undergraduates and beginning graduate students. The first version of these notes were written as a part of my preparation for the fall semester 1993 offering of the course. This version reflects some restructuring and revision done for the fall 1994 offering of the course|or after completion of the class. For these classes, I used the following resources: Textbook { Richard Bird and Philip Wadler. Introduction to Functional Program- ming, Prentice Hall International, 1988 [2]. These notes more or less cover the material from chapters 1 through 6 plus selected material from chapters 7 through 9. Software { Gofer interpreter version 2.30 (2.28 in 1993) written by Mark P.
    [Show full text]
  • Csci 555: Functional Programming Functional Programming in Scala Functional Data Structures
    CSci 555: Functional Programming Functional Programming in Scala Functional Data Structures H. Conrad Cunningham 6 March 2019 Contents 3 Functional Data Structures 2 3.1 Introduction . .2 3.2 A List algebraic data type . .2 3.2.1 Algebraic data types . .2 3.2.2 ADT confusion . .3 3.2.3 Using a Scala trait . .3 3.2.3.1 Aside on Haskell . .4 3.2.4 Polymorphism . .4 3.2.5 Variance . .5 3.2.5.1 Covariance and contravariance . .5 3.2.5.2 Function subtypes . .6 3.2.6 Defining functions in companion object . .7 3.2.7 Function to sum a list . .7 3.2.8 Function to multiply a list . .9 3.2.9 Function to remove adjacent duplicates . .9 3.2.10 Variadic function apply ................... 11 3.3 Data sharing . 11 3.3.1 Function to take tail of list . 12 3.3.2 Function to drop from beginning of list . 13 3.3.3 Function to append lists . 14 3.4 Other list functions . 15 3.4.1 Tail recursive function reverse . 15 3.4.2 Higher-order function dropWhile . 17 3.4.3 Curried function dropWhile . 17 3.5 Generalizing to Higher Order Functions . 18 3.5.1 Fold Right . 18 3.5.2 Fold Left . 22 3.5.3 Map . 23 1 3.5.4 Filter . 25 3.5.5 Flat Map . 26 3.6 Classic algorithms on lists . 27 3.6.1 Insertion sort and bounded generics . 27 3.6.2 Merge sort . 29 3.7 Lists in the Scala standard library .
    [Show full text]
  • Codata in Action
    Codata in Action Paul Downen1, Zachary Sullivan1, Zena M. Ariola1, and Simon Peyton Jones2 1 University of Oregon, Eugene, USA?? [email protected], [email protected], [email protected] 2 Microsoft Research, Cambridge, UK [email protected] Abstract. Computer scientists are well-versed in dealing with data struc- tures. The same cannot be said about their dual: codata. Even though codata is pervasive in category theory, universal algebra, and logic, the use of codata for programming has been mainly relegated to represent- ing infinite objects and processes. Our goal is to demonstrate the ben- efits of codata as a general-purpose programming abstraction indepen- dent of any specific language: eager or lazy, statically or dynamically typed, and functional or object-oriented. While codata is not featured in many programming languages today, we show how codata can be eas- ily adopted and implemented by offering simple inter-compilation tech- niques between data and codata. We believe codata is a common ground between the functional and object-oriented paradigms; ultimately, we hope to utilize the Curry-Howard isomorphism to further bridge the gap. Keywords: codata · lambda-calculi · encodings · Curry-Howard · func- tion programming · object-oriented programming 1 Introduction Functional programming enjoys a beautiful connection to logic, known as the Curry-Howard correspondence, or proofs as programs principle [22]; results and notions about a language are translated to those about proofs, and vice-versa [17]. In addition to expressing computation as proof transformations, this con- nection is also fruitful for education: everybody would understand that the as- sumption \an x is zero" does not mean \every x is zero," which in turn explains the subtle typing rules for polymorphism in programs.
    [Show full text]
  • CS 11 Haskell Track: Lecture 1 N This Week
    CS 11 Haskell track: lecture 1 n This week: n Introduction/motivation/pep talk n Basics of Haskell Prerequisite n Knowledge of basic functional programming n e.g. Scheme, Ocaml, Erlang n CS 1, CS 4 n "permission of instructor" n Without this, course will be pretty hard Quote "Any programming language that doesn't change the way you think about programming is not worth learning." -- Alan Perlis Why learn Haskell? (1) n Pound for pound, Haskell has more novel concepts than any programming language I've ever seen n and I've seen 'em all n Very powerful and innovative type system n Extremely high-level language n Will make you smarter n Fun to program in! Why learn Haskell? (2) n Very elegant and concise code: quicksort :: (Ord a) => [a] -> [a] quicksort [] = [] quicksort (x:xs) = quicksort lt ++ [x] ++ quicksort ge where lt = [y | y <- xs, y < x] ge = [y | y <- xs, y >= x] n Works for any orderable type What Haskell is good at n Any problem that can be characterized as a transformation n Compilers n DSLs (Domain-Specific Languages) n Implementing mathematical/algebraic concepts n Theorem provers What Haskell is not good at n Any problem that requires extreme speed n unless you use Haskell to generate C code n Any problem that is extremely stateful n e.g. simulations n though monads can get around this to some extent What is Haskell, anyway? n Haskell is a programming language n duh n A functional programming language n you all know what that is n A lazy functional programming language n Has strong static typing n every expression has a type n all types checked at compile time What is Haskell, anyway? n Named after Haskell Curry n pioneer in mathematical logic n developed theory of combinators n S, K, I and fun stuff like that Laziness (1) n Lazy evaluation means expressions (e.g.
    [Show full text]
  • Generalized Abstract GHC.Generics
    Generalized Abstract GHC.Generics Ryan Scott Indiana University Haskell Implementors Workshop 2018 St. Louis, MO GHC.Generics GHC’s most popular datatype-generic programming library. GHC.Generics GHC’s most popular datatype-generic programming library. data ADT a = MkADT1 a | MkADT2 a deriving Generic GHC.Generics GHC’s most popular datatype-generic programming library. data ADT a = MkADT1 a | MkADT2 a deriving Generic GHC.Generics GHC’s most popular datatype-generic programming library. data ADT a data GADT a where = MkADT1 a MkGADT1 :: GADT Int | MkADT2 a MkGADT2 :: GADT Bool deriving Generic deriving Generic GHC.Generics GHC’s most popular datatype-generic programming library. data ADT a data GADT a where = MkADT1 a MkGADT1 :: GADT Int | MkADT2 a MkGADT2 :: GADT Bool deriving Generic deriving Generic GHC.Generics GHC’s most popular datatype-generic programming library. class Generic a where -- Can be derived type Rep a from :: a -> Rep a to :: Rep a -> a GHC.Generics GHC’s most popular datatype-generic programming library. class NFData a where rnf :: a -> () instance NFData a => NFData [a] where rnf [] = () rnf (x:xs) = rnf x `seq` rnf xs We’ll continue to use NFData as a running example. What can GHC.Generics do? Generically represent any (simple) algebraic data type as a composition of representation types. data U1 = U1 -- No fields newtype K1 c = K1 c -- One field data a :*: b = a :*: b -- Products data a :+: b = L1 a | R1 b -- Sums What can GHC.Generics do? Generically represent any (simple) algebraic data type as a composition of representation types. -- Example instance instance Generic [a] where type Rep [a] = U1 -- [] constructor :+: (K1 a :*: K1 [a]) -- (:) constructor from [] = L1 U1 from (x:xs) = R1 (K1 x :*: K1 xs) to (L1 U1) = [] to (R1 (K1 x :*: K1 xs)) = x:xs What can GHC.Generics do? Generically represent any (simple) algebraic data type as a composition of representation types.
    [Show full text]