Type Systems As Macros Comp Le * a T * Te N * Te a Is W S E * E N L L C O

Total Page:16

File Type:pdf, Size:1020Kb

Type Systems As Macros Comp Le * a T * Te N * Te a Is W S E * E N L L C O rtifact Type Systems as Macros Comp le * A t * te n * te A is W s E * e n l l C o L D C o P * * c u e m s O E u e e P n R t v e o d t * y * s E a a l d u e a Stephen Chang Alex Knauth Ben Greenman t PLT @ Northeastern University, Boston, MA, USA fstchang,alexknauth,[email protected] Abstract bles a special instance of a macro system and our approach exploits synergies resulting from this insight. We present TURNSTILE, a metalanguage for creating typed embed- ded languages. To implement the type system, programmers write With our macro-based approach, programmers may implement type checking rules resembling traditional judgment syntax. To a wide range of type rules, yet they need not create a type system implement the semantics, they incorporate elaborations into these from scratch since they may reuse components of the macro sys- tem itself for type checking. Indeed, programmers need only supply rules. TURNSTILE critically depends on the idea of linguistic reuse. It exploits a macro system in a novel way to simultaneously type their desired type rules in an intuitive mathematical form. Creating check and rewrite a surface program into a target language. Reusing type systems with macros also fosters robust linguistic abstractions, a macro system also yields modular implementations whose rules e.g., they report type errors with surface language terms. Finally, may be mixed and matched to create other languages. Combined our approach produces naturally modular type systems that dually serve as libraries of mixable and matchable type rules, enabling with typical compiler and runtime reuse, TURNSTILE produces per- formant typed embedded languages with little effort. further linguistic reuse [27]. When combined with the typical reuse of the runtime that embedded languages enjoy, our approach inher- Categories and Subject Descriptors D.3.2 [Programming Lan- its the performance of its host and thus produces practical typed guages]: Specialized application languages languages with significantly reduced effort. We use Racket [12, 15], a production-quality Lisp and Scheme Keywords macros, type systems, typed embedded DSLs descendant, as our host language since Lisps are already a popular platform for creating embedded languages [17, 20]. Racket’s macro 1. Typed Embedded Languages system in particular continues to improve on its predecessors [14] and has even influenced macro system design in modern non-Lisp As Paul Hudak asserted, “we really don’t want to build a pro- languages [6, 8, 10, 48]. Thus programmers have created Racket- gramming language from scratch ... better, let’s inherit the in- embedded languages for accomplishing a variety of tasks such as frastructure of some other language” [23]. Unsurprisingly, many book publishing [7], program synthesis [44], and writing secure modern languages support the creation of such embedded lan- shell scripts [32]. guages [3, 18, 20, 22, 24–26, 41, 43, 46]. The first part of the paper (§2-3) demonstrates a connection be- Programmers who wish to create typed embedded languages, tween type rules and macros by reusing Racket’s macro infrastruc- however, have more limited options. Such languages typically reuse ture for type checking in the creation of a typed embedded lan- their host’s type system but, as a prominent project [45] recently guage. The second part (§4) introduces TURNSTILE, a metalan- remarked, this “confines them to hthati type system.” Also, reusing guage that abstracts the insights and techniques from the first part a type system may not create proper abstractions, e.g., type errors into convenient linguistic constructs. The third part (§5-7) shows may be reported in host language terms. At the other extreme, that our approach both accommodates a variety of type systems and a programmer can implement a type system from scratch [42], scales to realistic combinations of type system features. We demon- expending considerable effort and passing up many of the reuse strate the former by implementing fifteen core languages ranging benefits that embedding a language promises in the first place. from simply-typed to F!, and the latter with the creation of a full- We present an alternative approach to implementing typed em- sized ML-like functional language that also supports basic Haskell- bedded languages. Rather than reuse a type system, we embed a style type classes. type system in a host’s macro system. In other words, type check- ing is computed as part of macro expansion. Such an embedding fits naturally since a typical type checking algorithm traverses a surface program, synthesizes information from it, and then uses this infor- 2. Creating Embedded Languages in Racket mation to rewrite the program, if it satisfies certain conditions, into This section summarizes the creation of embedded languages with a target language. This kind of algorithm exactly matches the ideal Racket. Racket is not a single language but rather an ecosystem use case for macros. From this perspective, a type checker resem- with which to create languages [12]. Racket code is organized into modules, e.g. LAM:1 #lang racket lam Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee (define-m (lm x e) (λ (x) e)) provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than ACM must be honored. (provide lm) Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, or to redistribute to lists, contact the Owner/Author(s). Request permissions from [email protected] or Publications Dept., ACM, Inc., fax +1 (212) 869-0481. POPL ’17, January 18 - 20, 2017, Paris, France 1 Code note: For clarity and conciseness, this paper stylizes code and thus Copyright © 2017 held by owner/author(s). Publication rights licensed to ACM. ACM 978-1-4503-4660-3/17/01. $15.00 its examples may not run exactly as presented. Full, runnable examples are DOI: http://dx.doi.org/10.1145/http://dx.doi.org/10.1145/3009837.3009886 available at: www.ccs.neu.edu/home/stchang/popl2017/ A #lang racket declaration allows LAM to use forms and func- τ ::= τ !τ e ::= x j λx:τ : e j e e Γ ::= x:τ; : : : (types, terms) tions from the main Racket language. LAM defines and exports one 2 macro, lm, denoting single-argument functions. A Racket macro x:τ 2 Γ Γ; x:τ1 ` e : τ2 consumes and produces syntax object data structures. The lm macro (T-VAR) (T-ABS) Γ ` x : τ Γ ` λx:τ1 : e : τ1 !τ2 specifies its usage shape with input pattern (lm x e) (in yellow Γ ` e1 : τ1 !τ2 Γ ` e2 : τ1 to help readability), which binds pattern variables x and e to sub- (T-APP) pieces of the input, the parameter and body, respectively. The out- Γ ` e1 e2 : τ2 put syntax (λ (x) e) (gray denotes syntax object construction) er(x) = x; er(λx:τ : e) = λx : er(e); er(e e0) = er(e) er(e0) (erase) references these pattern variables (λ is Racket’s λ). Implementation sketch: A module serves multiple roles in the Racket ecosystem. Run- ning LAM as a program produces no result since it consists of only #lang racket stlc a macro definition. But LAM is also a language: (define-m (checked-λ : : :) hwhen T-ABSi er( )) #lang lam lam-prog (define-m (checked-app :::) hwhen T-APPi er( )) (lm x (lm y x)); => hfunctioni ((lm x x) (lm x x)); stx error! fn application undefined Figure 2. Simply-typed λ-calculus A module declaring #lang lam may only write lm functions; using any other form results in an error. Finally, a Racket module may be used as a library, as in the following LC module: 1 (define-m (checked-app efn earg); v0 #lang racket lc 2 #:with (! τin τout) (compute-τ efn ) (require lam) 3 #:with τarg (compute-τ earg ) (provide (rename-out [lm λ] [app #%app])) 4 #:when (τ= τarg τin ) (define-m (app efn earg) (#%app efn earg)) 5 #:with efn (erase-τ efn ) LC imports lm from LAM and also defines app, which corresponds 6 #:with earg (erase-τ earg ) to single-argument function application. LC exports lm and app with new names, λ and #%app, respectively. The #%app in the out- 7 (add-τ (#%app efn earg) τout )) put of app is core-Racket’s function application form, though pro- grammers need not write it explicitly. Instead, macro expansion im- Figure 3. A type checking function application macro plicitly inserts it before applied functions. This enables modifying the behavior of function application, as we do here by exporting app as #%app. Thus a program in the LC language looks like: sion contains only references to Racket’s core syntax. This paper shows how to embed type checking within macro expansion. #lang lc lc-prog ((λ x (x x)) (λ x (x x))); => loop! 3. A Typed λ-Calculus Embedded Language where λ corresponds to lm in LAM and applying a λ behaves LC from section 2 implements the untyped λ-calculus. This section according to app in LC. Running LC-PROG loops forever. augments LC with types and type checking by transcribing formal Figure 1 depicts compilation of a Racket program, which in- type rules directly into its macro definitions, producing the simply- cludes macro expansion. The Racket compiler first “reads” a pro- typed λ-calculus and demonstrating that Racket’s macro infrastruc- gram’s surface text into a syntax object, which is a tree of symbols ture can be reused for type checking.
Recommended publications
  • Tt-Satisfiable
    CMPSCI 601: Recall From Last Time Lecture 6 Boolean Syntax: ¡ ¢¤£¦¥¨§¨£ © §¨£ § Boolean variables: A boolean variable represents an atomic statement that may be either true or false. There may be infinitely many of these available. Boolean expressions: £ atomic: , (“top”), (“bottom”) § ! " # $ , , , , , for Boolean expressions Note that any particular expression is a finite string, and thus may use only finitely many variables. £ £ A literal is an atomic expression or its negation: , , , . As you may know, the choice of operators is somewhat arbitary as long as we have a complete set, one that suf- fices to simulate all boolean functions. On HW#1 we ¢ § § ! argued that is already a complete set. 1 CMPSCI 601: Boolean Logic: Semantics Lecture 6 A boolean expression has a meaning, a truth value of true or false, once we know the truth values of all the individual variables. ¢ £ # ¡ A truth assignment is a function ¢ true § false , where is the set of all variables. An as- signment is appropriate to an expression ¤ if it assigns a value to all variables used in ¤ . ¡ The double-turnstile symbol ¥ (read as “models”) de- notes the relationship between a truth assignment and an ¡ ¥ ¤ expression. The statement “ ” (read as “ models ¤ ¤ ”) simply says “ is true under ”. 2 ¡ ¤ ¥ ¤ If is appropriate to , we define when is true by induction on the structure of ¤ : is true and is false for any , £ A variable is true iff says that it is, ¡ ¡ ¡ ¡ " ! ¥ ¤ ¥ ¥ If ¤ , iff both and , ¡ ¡ ¡ ¡ " ¥ ¤ ¥ ¥ If ¤ , iff either or or both, ¡ ¡ ¡ ¡ " # ¥ ¤ ¥ ¥ If ¤ , unless and , ¡ ¡ ¡ ¡ $ ¥ ¤ ¥ ¥ If ¤ , iff and are both true or both false. 3 Definition 6.1 A boolean expression ¤ is satisfiable iff ¡ ¥ ¤ there exists .
    [Show full text]
  • Lecture Notes on Types for Part II of the Computer Science Tripos
    Q Lecture Notes on Types for Part II of the Computer Science Tripos Prof. Andrew M. Pitts University of Cambridge Computer Laboratory c 2016 A. M. Pitts Contents Learning Guide i 1 Introduction 1 2 ML Polymorphism 6 2.1 Mini-ML type system . 6 2.2 Examples of type inference, by hand . 14 2.3 Principal type schemes . 16 2.4 A type inference algorithm . 18 3 Polymorphic Reference Types 25 3.1 The problem . 25 3.2 Restoring type soundness . 30 4 Polymorphic Lambda Calculus 33 4.1 From type schemes to polymorphic types . 33 4.2 The Polymorphic Lambda Calculus (PLC) type system . 37 4.3 PLC type inference . 42 4.4 Datatypes in PLC . 43 4.5 Existential types . 50 5 Dependent Types 53 5.1 Dependent functions . 53 5.2 Pure Type Systems . 57 5.3 System Fw .............................................. 63 6 Propositions as Types 67 6.1 Intuitionistic logics . 67 6.2 Curry-Howard correspondence . 69 6.3 Calculus of Constructions, lC ................................... 73 6.4 Inductive types . 76 7 Further Topics 81 References 84 Learning Guide These notes and slides are designed to accompany 12 lectures on type systems for Part II of the Cambridge University Computer Science Tripos. The course builds on the techniques intro- duced in the Part IB course on Semantics of Programming Languages for specifying type systems for programming languages and reasoning about their properties. The emphasis here is on type systems for functional languages and their connection to constructive logic. We pay par- ticular attention to the notion of parametric polymorphism (also known as generics), both because it has proven useful in practice and because its theory is quite subtle.
    [Show full text]
  • Open C++ Tutorial∗
    Open C++ Tutorial∗ Shigeru Chiba Institute of Information Science and Electronics University of Tsukuba [email protected] Copyright c 1998 by Shigeru Chiba. All Rights Reserved. 1 Introduction OpenC++ is an extensible language based on C++. The extended features of OpenC++ are specified by a meta-level program given at compile time. For dis- tinction, regular programs written in OpenC++ are called base-level programs. If no meta-level program is given, OpenC++ is identical to regular C++. The meta-level program extends OpenC++ through the interface called the OpenC++ MOP. The OpenC++ compiler consists of three stages: preprocessor, source-to-source translator from OpenC++ to C++, and the back-end C++ com- piler. The OpenC++ MOP is an interface to control the translator at the second stage. It allows to specify how an extended feature of OpenC++ is translated into regular C++ code. An extended feature of OpenC++ is supplied as an add-on software for the compiler. The add-on software consists of not only the meta-level program but also runtime support code. The runtime support code provides classes and functions used by the base-level program translated into C++. The base-level program in OpenC++ is first translated into C++ according to the meta-level program. Then it is linked with the runtime support code to be executable code. This flow is illustrated by Figure 1. The meta-level program is also written in OpenC++ since OpenC++ is a self- reflective language. It defines new metaobjects to control source-to-source transla- tion. The metaobjects are the meta-level representation of the base-level program and they perform the translation.
    [Show full text]
  • Chapter 9: Initial Theorems About Axiom System
    Initial Theorems about Axiom 9 System AS1 1. Theorems in Axiom Systems versus Theorems about Axiom Systems ..................................2 2. Proofs about Axiom Systems ................................................................................................3 3. Initial Examples of Proofs in the Metalanguage about AS1 ..................................................4 4. The Deduction Theorem.......................................................................................................7 5. Using Mathematical Induction to do Proofs about Derivations .............................................8 6. Setting up the Proof of the Deduction Theorem.....................................................................9 7. Informal Proof of the Deduction Theorem..........................................................................10 8. The Lemmas Supporting the Deduction Theorem................................................................11 9. Rules R1 and R2 are Required for any DT-MP-Logic........................................................12 10. The Converse of the Deduction Theorem and Modus Ponens .............................................14 11. Some General Theorems About ......................................................................................15 12. Further Theorems About AS1.............................................................................................16 13. Appendix: Summary of Theorems about AS1.....................................................................18 2 Hardegree,
    [Show full text]
  • Let's Get Functional
    5 LET’S GET FUNCTIONAL I’ve mentioned several times that F# is a functional language, but as you’ve learned from previous chapters you can build rich applications in F# without using any functional techniques. Does that mean that F# isn’t really a functional language? No. F# is a general-purpose, multi paradigm language that allows you to program in the style most suited to your task. It is considered a functional-first lan- guage, meaning that its constructs encourage a functional style. In other words, when developing in F# you should favor functional approaches whenever possible and switch to other styles as appropriate. In this chapter, we’ll see what functional programming really is and how functions in F# differ from those in other languages. Once we’ve estab- lished that foundation, we’ll explore several data types commonly used with functional programming and take a brief side trip into lazy evaluation. The Book of F# © 2014 by Dave Fancher What Is Functional Programming? Functional programming takes a fundamentally different approach toward developing software than object-oriented programming. While object-oriented programming is primarily concerned with managing an ever-changing system state, functional programming emphasizes immutability and the application of deterministic functions. This difference drastically changes the way you build software, because in object-oriented programming you’re mostly concerned with defining classes (or structs), whereas in functional programming your focus is on defining functions with particular emphasis on their input and output. F# is an impure functional language where data is immutable by default, though you can still define mutable data or cause other side effects in your functions.
    [Show full text]
  • Run-Time Type Information and Incremental Loading in C++
    Run-time Type Information and Incremental Loading in C++ Murali Vemulapati Sriram Duvvuru Amar Gupta WP #3772 September 1993 PROFIT #93-11 Productivity From Information Technology "PROFIT" Research Initiative Sloan School of Management Massachusetts Institute of Technology Cambridge, MA 02139 USA (617)253-8584 Fax: (617)258-7579 Copyright Massachusetts Institute of Technology 1993. The research described herein has been supported (in whole or in part) by the Productivity From Information Technology (PROFIT) Research Initiative at MIT. This copy is for the exclusive use of PROFIT sponsor firms. Productivity From Information Technology (PROFIT) The Productivity From Information Technology (PROFIT) Initiative was established on October 23, 1992 by MIT President Charles Vest and Provost Mark Wrighton "to study the use of information technology in both the private and public sectors and to enhance productivity in areas ranging from finance to transportation, and from manufacturing to telecommunications." At the time of its inception, PROFIT took over the Composite Information Systems Laboratory and Handwritten Character Recognition Laboratory. These two laboratories are now involved in research re- lated to context mediation and imaging respectively. LABORATORY FOR ELEC RONICS A CENTERCFORENTER COORDINATION LABORATORY ) INFORMATION S RESEARCH RESE CH E53-310, MITAL"Room Cambridge, MA 02M142-1247 Tel: (617) 253-8584 E-Mail: [email protected] Run-time Type Information and Incremental Loading in C++ September 13, 1993 Abstract We present the design and implementation strategy for an integrated programming environment which facilitates specification, implementation and execution of persistent C++ programs. Our system is implemented in E, a persistent programming language based on C++. The environment provides type identity and type persistence, i.e., each user-defined class has a unique identity and persistence across compilations.
    [Show full text]
  • Chapter 13: Formal Proofs and Quantifiers
    Chapter 13: Formal Proofs and Quantifiers § 13.1 Universal quantifier rules Universal Elimination (∀ Elim) ∀x S(x) ❺ S(c) Here x stands for any variable, c stands for any individual constant, and S(c) stands for the result of replacing all free occurrences of x in S(x) with c. Example 1. ∀x ∃y (Adjoins(x, y) ∧ SameSize(y, x)) 2. ∃y (Adjoins(b, y) ∧ SameSize(y, b)) ∀ Elim: 1 General Conditional Proof (∀ Intro) ✾c P(c) Where c does not occur outside Q(c) the subproof where it is introduced. ❺ ∀x (P(x) → Q(x)) There is an important bit of new notation here— ✾c , the “boxed constant” at the beginning of the assumption line. This says, in effect, “let’s call it c.” To enter the boxed constant in Fitch, start a new subproof and click on the downward pointing triangle ❼. This will open a menu that lets you choose the constant you wish to use as a name for an arbitrary object. Your subproof will typically end with some sentence containing this constant. In giving the justification for the universal generalization, we cite the entire subproof (as we do in the case of → Intro). Notice that although c may not occur outside the subproof where it is introduced, it may occur again inside a subproof within the original subproof. Universal Introduction (∀ Intro) ✾c Where c does not occur outside the subproof where it is P(c) introduced. ❺ ∀x P(x) Remember, any time you set up a subproof for ∀ Intro, you must choose a “boxed constant” on the assumption line of the subproof, even if there is no sentence on the assumption line.
    [Show full text]
  • Kodak Color Control Patches Kodak Gray
    Kodak Color Control Patches 0 - - _,...,...,. Blue Green Yellow Red White 3/Color . Black Kodak Gray Scale A 1 2 a 4 s -- - --- - -- - -- - -- -- - A Study of Compile-time Metaobject Protocol :J/1\'-(Jt.-S~..)(:$/;:t::;i':_;·I'i f-.· 7 •[:]f-. :::JJl.­ (:~9 ~~Jf'?E By Shigeru Chiba chiba~is.s.u-tokyo.ac.jp November 1996 A Dissertation Submitted to Department of Information Science Graduate School of Science The Un iversity of Tokyo In Partial Fulfillment of the Requirements For the Degree of Doctor of Science. Copyright @1996 by Shigeru Chiba. All Rights Reserved. - - - ---- - ~-- -- -~ - - - ii A Metaobject Protocol for Enabling Better C++ Libraries Shigeru Chiba Department of Information Science The University of Tokyo chiba~is.s.u-tokyo.ac.jp Copyrighl @ 1996 by Shi geru Chiba. All Ri ghts Reserved. iii iv Abstract C++ cannot be used to implement control/data abstractions as a library if their implementations require specialized code for each user code. This problem limits programmers to write libraries in two ways: it makes some kinds of useful abstractions that inherently require such facilities impossi­ ble to implement, and it makes other abstractions difficult to implement efficiently. T he OpenC++ MOP addresses this problem by providing li braries the ability to pre-process a program in a context-sensitive and non-local way. That is, libraries can instantiate specialized code depending on how the library is used and, if needed, substitute it for the original user code. The basic protocol structure of the Open C++ MOP is based on that of the CLOS MOP, but the Open C++ MOP runs metaobjects only at compile time.
    [Show full text]
  • 1 Simply-Typed Lambda Calculus
    CS 4110 – Programming Languages and Logics Lecture #18: Simply Typed λ-calculus A type is a collection of computational entities that share some common property. For example, the type int represents all expressions that evaluate to an integer, and the type int ! int represents all functions from integers to integers. The Pascal subrange type [1..100] represents all integers between 1 and 100. You can see types as a static approximation of the dynamic behaviors of terms and programs. Type systems are a lightweight formal method for reasoning about behavior of a program. Uses of type systems include: naming and organizing useful concepts; providing information (to the compiler or programmer) about data manipulated by a program; and ensuring that the run-time behavior of programs meet certain criteria. In this lecture, we’ll consider a type system for the lambda calculus that ensures that values are used correctly; for example, that a program never tries to add an integer to a function. The resulting language (lambda calculus plus the type system) is called the simply-typed lambda calculus (STLC). 1 Simply-typed lambda calculus The syntax of the simply-typed lambda calculus is similar to that of untyped lambda calculus, with the exception of abstractions. Since abstractions define functions tht take an argument, in the simply-typed lambda calculus, we explicitly state what the type of the argument is. That is, in an abstraction λx : τ: e, the τ is the expected type of the argument. The syntax of the simply-typed lambda calculus is as follows. It includes integer literals n, addition e1 + e2, and the unit value ¹º.
    [Show full text]
  • Query Rewriting Using Views in a Typed Mediator
    Язык СИНТЕЗ как ядро канонической информационной модели Л. А. Калиниченко ([email protected]) C. А. Ступников ([email protected]) Lecture outline Objectives of the language Frame language: semi-structured capabilities Type system of SYNTHESIS Classes and metaclasses Assertions Processes, workflows Formulae facilities of the language 2 History of the language . Preliminary draft version published in 1991 . First version published in 1993 . English version prepared in 1995 and extended in 1997 . Current version in English published in 2007 3 The SYNTHESIS is a multipurpose language The language is oriented on the following basic kinds of application: . serving as a kernel of the canonical information model; . providing facilities for unifying representation of heterogeneous information models of different kinds (of data, services, processes, ontologies); . providing sufficient modeling facilities for formalized definitions of mediators for various subject domains; . supporting mediation-based design of information systems; . providing modeling facilities for mediator and resource specifications for the mediation architecture; . serving for semantic reconciliation of the mediator and resource specifications to form compositions of resources refining mediator specifications; . serving as an interface for users during problem formulation and solving in various applications 4 Mediation orientation . Two different approaches to the problem of integrated representation of multiple information resources for an IS are distinguished: 1. moving from resources to problems (resource driven approach) 2. moving from an application to resources (application driven approach) The SYNTHESIS language is oriented on support of application-driven approach for mediation-based IS development. The mediator's layer is introduced to provide the users with the metainformation uniformly characterizing subject definitions in the canonical information model – providing application domain conceptual schema .
    [Show full text]
  • Problem Solving with Programming Course Material
    Problem Solving with Programming Course Material PROBLEM SOLVING WITH PROGRAMMING Hours/Week Marks Year Semester C L T P/D CIE SEE Total I II 2 - - 2 30 70 100 Pre-requisite Nil COURSE OUTCOMES At the end of the course, the students will develop ability to 1. Analyze and implement software development tools like algorithm, pseudo codes and programming structure. 2. Modularize the problems into small modules and then convert them into modular programs 3. Apply the pointers, memory allocation techniques and use of files for dealing with variety of problems. 4. Apply C programming to solve problems related to scientific computing. 5. Develop efficient programs for real world applications. UNIT I Pointers Basics of pointers, pointer to array, array of pointers, void pointer, pointer to pointer- example programs, pointer to string. Project: Simple C project by using pointers. UNIT II Structures Basics of structure in C, structure members, accessing structure members, nested structures, array of structures, pointers to structures - example programs, Unions- accessing union members- example programs. Project: Simple C project by using structures/unions. UNIT III Functions Functions: User-defined functions, categories of functions, parameter passing in functions: call by value, call by reference, recursive functions. passing arrays to functions, passing strings to functions, passing a structure to a function. Department of Computer Science and Engineering Problem Solving with Programming Course Material Project: Simple C project by using functions. UNIT IV File Management Data Files, opening and closing a data file, creating a data file, processing a data file, unformatted data files. Project: Simple C project by using files.
    [Show full text]
  • Solutions to Exercises
    Solutions to Exercises Solutions for Chapter 2 Exercise 2.1 Provide a function to check if a character is alphanumeric, that is lower case, upper case or numeric. One solution is to follow the same approach as in the function isupper for each of the three possibilities and link them with the special operator \/ : isalpha c = (c >= ’A’ & c <= ’Z’) \/ (c >= ’a’ & c <= ’z’) \/ (c >= ’0’ & c <= ’9’) An second approach is to use continued relations: isalpha c = (’A’ <= c <= ’Z’) \/ (’a’ <= c <= ’z’) \/ (’0’ <= c <= ’9’) A final approach is to define the functions isupper, islower and isdigit and combine them: isalpha c = (isupper c) \/ (islower c) \/ (isdigit c) This approach shows the advantage of reusing existing simple functions to build more complex functions. 268 Solutions to Exercises 269 Exercise 2.2 What happens in the following application and why? myfst (3, (4 div 0)) The function evaluates to 3, the potential divide by zero error is ignored because Miranda only evaluates as much of its parameter as it needs. Exercise 2.3 Define a function dup which takes a single element of any type and returns a tuple with the element duplicated. The answer is just a direct translation of the specification into Miranda: dup :: * -> (*,*) dup x = (x, x) Exercise 2.4 Modify the function solomonGrundy so that Thursday and Friday may be treated with special significance. The pattern matching version is easily modified; all that is needed is to insert the extra cases somewhere before the default pattern: solomonGrundy "Monday" = "Born" solomonGrundy "Thursday" = "Ill" solomonGrundy "Friday" = "Worse" solomonGrundy "Sunday" = "Buried" solomonGrundy anyday = "Did something else" By contrast, a guarded conditional version is rather messy: solomonGrundy day = "Born", if day = "Monday" = "Ill", if day = "Thursday" = "Worse", if day = "Friday" = "Buried", if day = "Sunday" = "Did something else", otherwise Exercise 2.5 Define a function intmax which takes a number pair and returns the greater of its two components.
    [Show full text]