Relocating Machine Instructions by Currying

Total Page:16

File Type:pdf, Size:1020Kb

Relocating Machine Instructions by Currying Relo cating Machine Instructions by Currying Norman Ramsey University of Virginia Relo cation adjusts machine instructions to account for changes in the lo cations of the instructions themselves or of external symb ols to which they refer Standard linkers implement a nite set of relo cation transformations suitable for a single architecture These transformations are enumer ated named and engraved in a machinedep endent ob jectle format and linkers must recognize them by name These names and their asso ciated transformations are an unnecessary source of machinedep endence An alternative is to use SLED Sp ecication Language for Enco ding and Deco ding to sp ecify representations of machine instructions Instructions are describ ed by constructors which denote functions mapping lists of op erands to instructions binary representations Any op erand can b e designated as relo catable meaning that the op erands value need not b e known at the time the instruction is enco ded From a SLED sp ecication the New Jersey MachineCo de To olkit can generate functions that enco de instructions in the native binary representation For instructions with relo catable op erands the to olkit also computes relo cating transformations To ol writers can create machineindep endent software that uses these transformations to relo cate machine instructions For example mld a retargetable linker built with the to olkit needs only lines of C co de for relo cation and that co de is machineindep endent The to olkit discovers relo cating transformations by currying enco ding functions An attempt to enco de an instruction with a relo catable op erand results in the creation of a closure The closure can b e applied when the values of the relo catable op erands b ecome known Currying provides a general machineindep endent metho d of relo cation Currying rewrites a term into two nested terms The standard implementation has the rst allo cate a closure and store therein its op erands and a p ointer to the second Using this strategy in the to olkit means that when it builds an application the to olkit generates co de for many dierent inner termsone for each instruction that uses a relo catable address Hoisting some of the computation out of the second into the rst makes many of the second s identicala handful are enough for a whole instruction set This optimization reduces the size of machine dep endent assembly and linking co de by for the Alpha MIPS SPARC and PowerPC and by ab out for the Pentium It also makes the second s equivalent to relo cating transformations named in standard ob jectle formats Categories and Subject Descriptors D Op erating Systems Systems Programs and Utili tiesLinkers D Programming Techniques Applicative Functional Programming D Programming Languages Language Classicationsspecialized application languages General Terms Relo cation Linking Currying Additional Key Words and Phrases higherorder functions INTRODUCTION Compiling whole programs is slow compiling units separately and linking the com piled units into a program sp eeds up the editcompilego cycle For separate compi lation a compiler must b e able to emit instructions and data without knowing the exact lo cations either of the instructions and data the compiler itself emits or of Authors current address Norman Ramsey Department of Computer Science University of Vir ginia Charlottesville VA Email nrcsvirginiaedu This work supp orted in part by NSF grant numb er ASC N Ramsey the instructions and data emitted by other compilations Using assembly language makes this task easy b ecause in assembly language all lo cations are represented symb olically Symb olic assemblylike units can b e linked to form programs Fraser and Hanson Jones but the linker or loader must translate all units from symb olic form into the binary representation required by the target hardware It is b elieved to b e more ecient to translate each unit separately into a binary form called relocatable object code Ob ject co de must contain more than just instructions and data To supp ort delayed binding of lo cations it must also represent The symb ols dened in the ob ject le and the lo cations to which they are b ound The symb ols imp orted from other units ie external symb ols The transformations that must b e applied to the instructions and data to account for their eventual placement at absolute addresses and also for the placements of the external symb ols on which they dep end Applying these transformations is called relocation Current ob jectco de formats force to ol writers to handle relo cation in a machine dep endent way Given an instructionset architecture a human b eing examines the instructions and determines which op erands can b e relo catable addresses and what relo cating transformations are needed Each transformation is named and linkers and other to ols must recognize transformations by name The names are informal and machinedep endent so retargetable to ols that manipulate ob ject co de must recognize each set of names on each machine This pap er makes several contributions It presents a machineindep endent au tomatic metho d of discovering relo cating transformations It presents an opti mization that makes the cost of the automatic metho d comparable to the cost of handimplemented metho ds and makes the discovered transformations equivalent to the transformations used in standard ob jectle formats Finally the pap er gives a machineindep endent representation of the transformations This new technique for relo cating machine instructions is an enabling technology for building machineindep endent to ols for static incremental and dynamic linking It will also simplify the construction of retargetable to ols that transform ob ject co de Ob jectco de transformation which is growing in imp ortance is used for proling and tracing Ball and Larus testing Hastings and Joyce enforcing protection Wahb e et al optimization Srivastava and Wall and binary translation Sites et al There are even frameworks for creating applications that transform ob ject co de Johnson Larus and Schnarr Srivastava and Eustace The techniques presented here build on the New Jersey MachineCo de To olkit Ramsey and Fernandez which reads a compact machine description and generates functions that enco de instructions The machine description is written in SLED Sp ecication Language for Enco ding and Deco ding which relates three rep resentations of instructions a symb olic representation akin to assembly language assembly language itself and the binary representation used by the hardware Real instruction sets can b e sp ecied with mo dest eort our Alpha MIPS SPARC and Pentium sp ecications Ramsey and Fernandez are and Relo cating Machine Instructions by Currying lines In SLED an instruction is represented symb olically by its name and a list of its op erands the collection of all instructions resembles an algebraic data typ e The machine description indicates which op erands are relo catable addresses and currying the enco ding function with resp ect to those op erands results in a relo cating transformation Currying rewrites the enco ding function into two nested terms In the standard implementation the outer allo cates a closure and stores therein its op erands and a p ointer to the inner which uses the contents of the closure to enco de relo cate the instruction The inner s are the relo cating transformations discovered by the to olkit and the closures take the place of relo cation entries in traditional ob ject les Using the standard implementation of currying the to olkit generates co de for many dierent inner termsone for each instruction that uses a relo catable ad dress Hoisting some of the computation out of the inner into the outer makes many of the inner s identicala handful are enough for a whole instruction set This optimization is closely related to fully lazy lamb dalifting Peyton Jones It reduces the size of machinedep endent assembly and linking co de by for the Alpha MIPS SPARC and PowerPC and by ab out for the Pentium It also makes the relo cating transformations discovered by the to olkit equivalent to those that are now implemented by hand To supp ort machineindep endent use of these transformations the to olkit asso ciates each one with a string that can b e interpreted to have the eect of applying the transformation These strings can b e used in an ob ject le as meaningful formal machineindep endent names DESCRIBING INSTRUCTION REPRESENTATIONS SLED describ es the binary representation of an instruction as a sequence of tokens On a RISC machine each instruction is a single bit token On a machine like the Pentium formats vary for example the instruction add DX has an bit op co de token followed by another bit token that has b oth op co de and addressmo de bits followed by the bit displacement and the bit immediate op erand Each token in an instruction is partitioned into elds a eld is a contiguous range of bits within a token On RISC machines dierent instruction formats are represented by dierent partitions of the instruction token Fields contain op co des op erands mo des or other information Op co des and op erands can b e distributed among multiple elds Patterns constrain the values of elds they may constrain elds in a single token or in a sequence of tokens They can b e used to describ e binary representations of op co des of whole instructions and of groups of instructions Constructors connect the symb olic and binary representations of instructions At a symb olic level an
Recommended publications
  • Reversible Programming with Negative and Fractional Types
    9 A Computational Interpretation of Compact Closed Categories: Reversible Programming with Negative and Fractional Types CHAO-HONG CHEN, Indiana University, USA AMR SABRY, Indiana University, USA Compact closed categories include objects representing higher-order functions and are well-established as models of linear logic, concurrency, and quantum computing. We show that it is possible to construct such compact closed categories for conventional sum and product types by defining a dual to sum types, a negative type, and a dual to product types, a fractional type. Inspired by the categorical semantics, we define a sound operational semantics for negative and fractional types in which a negative type represents a computational effect that “reverses execution flow” and a fractional type represents a computational effect that“garbage collects” particular values or throws exceptions. Specifically, we extend a first-order reversible language of type isomorphisms with negative and fractional types, specify an operational semantics for each extension, and prove that each extension forms a compact closed category. We furthermore show that both operational semantics can be merged using the standard combination of backtracking and exceptions resulting in a smooth interoperability of negative and fractional types. We illustrate the expressiveness of this combination by writing a reversible SAT solver that uses back- tracking search along freshly allocated and de-allocated locations. The operational semantics, most of its meta-theoretic properties, and all examples are formalized in a supplementary Agda package. CCS Concepts: • Theory of computation → Type theory; Abstract machines; Operational semantics. Additional Key Words and Phrases: Abstract Machines, Duality of Computation, Higher-Order Reversible Programming, Termination Proofs, Type Isomorphisms ACM Reference Format: Chao-Hong Chen and Amr Sabry.
    [Show full text]
  • Foundation API Client Library PHP – Usage Examples By: Juergen Rolf Revision Version: 1.2
    Foundation API Client Library PHP – Usage Examples By: Juergen Rolf Revision Version: 1.2 Revision Date: 2019-09-17 Company Unrestricted Foundation API Client Library PHP – Installation Guide Document Information Document Details File Name MDG Foundation API Client Library PHP - Usage Examples_v1_2 external.docx Contents Usage Examples and Tutorial introduction for the Foundation API Client Library - PHP Author Juergen Rolf Version 1.2 Date 2019-09-17 Intended Audience This document provides a few examples helping the reader to understand the necessary mechanisms to request data from the Market Data Gateway (MDG). The intended audience are application developers who want to get a feeling for the way they can request and receive data from the MDG. Revision History Revision Date Version Notes Author Status 2017-12-04 1.0 Initial Release J. Rolf Released 2018-03-27 1.1 Adjustments for external J. Rolf Released release 2019-09-17 1.2 Minor bugfixes J. Ockel Released References No. Document Version Date 1. Quick Start Guide - Market Data Gateway (MDG) 1.1 2018-03-27 APIs external 2. MDG Foundation API Client Library PHP – Installation 1.2 2019-09-17 Guide external Company Unrestricted Copyright © 2018 FactSet Digital Solutions GmbH. All rights reserved. Revision Version 1.2, Revision Date 2019-09-17, Author: Juergen Rolf www.factset.com | 2 Foundation API Client Library PHP – Installation Guide Table of Contents Document Information ............................................................................................................................
    [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]
  • Chapter 6: the Linker
    6. The Linker 6-1 Chapter 6: The Linker References: • Brian W. Kernighan / Dennis M. Ritchie: The C Programming Language, 2nd Ed. Prentice-Hall, 1988. • Samuel P. Harbison / Guy L. Steele Jr.: C — A Reference Manual, 4th Ed. Prentice-Hall, 1995. • Online Documentation of Microsoft Visual C++ 6.0 (Standard Edition): MSDN Library: Visual Studio 6.0 release. • Horst Wettstein: Assemblierer und Binder (in German). Carl Hanser Verlag, 1979. • Peter Rechenberg, Gustav Pomberger (Eds.): Informatik-Handbuch (in German). Carl Hanser Verlag, 1997. Kapitel 12: Systemsoftware (H. M¨ossenb¨ock). Stefan Brass: Computer Science III Universit¨atGiessen, 2001 6. The Linker 6-2 Overview ' $ 1. Introduction (Overview) & % 2. Object Files, Libraries, and the Linker 3. Make 4. Dynamic Linking Stefan Brass: Computer Science III Universit¨atGiessen, 2001 6. The Linker 6-3 Introduction (1) • Often, a program consists of several modules which are separately compiled. Reasons are: The program is large. Even with fast computers, editing and compiling a single file with a million lines leads to unnecessary delays. The program is developed by several people. Different programmers cannot easily edit the same file at the same time. (There is software for collaborative work that permits that, but it is still a research topic.) A large program is easier to understand if it is divided into natural units. E.g. each module defines one data type with its operations. Stefan Brass: Computer Science III Universit¨atGiessen, 2001 6. The Linker 6-4 Introduction (2) • Reasons for splitting a program into several source files (continued): The same module might be used in different pro- grams (e.g.
    [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]
  • Message from the Editor
    Article Reading Qualitative Studies Margarete Sandelowski University of North Carolina at Chapel Hill Chapel Hill, North Carolina, USA Julie Barroso University of North Carolina at Chapel Hill Chapel Hill, North Carolina, USA © 2002 Sandelowski et al. This is an Open Access article distributed under the terms of the Creative Commons Attribution License (http://creativecommons.org/licenses/by/2.0), which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. Abstract In this article, the authors hope to shift the debate in the practice disciplines concerning quality in qualitative research from a preoccupation with epistemic criteria toward consideration of aesthetic and rhetorical concerns. They see epistemic criteria as inevitably including aesthetic and rhetorical concerns. The authors argue here for a reconceptualization of the research report as a literary technology that mediates between researcher/writer and reviewer/reader. The evaluation of these reports should thus be treated as occasions in which readers seek to make texts meaningful, rather than for the rigid application of standards and criteria. The authors draw from reader-response theories, literature on rhetoric and representation in science, and findings from an on-going methodological research project involving the appraisal of a set of qualitative studies. Keywords: Reader-response, reading, representation, rhetoric, qualitative research, quality criteria, writing Acknowledgments: We thank the members of
    [Show full text]
  • HP Openvms Utility Routines Manual
    HP OpenVMS Utility Routines Manual Order Number: BA554-90019 June 2010 This manual describes the OpenVMS utility routines, a set of routines that provide a programming interface to various OpenVMS utilities. Revision/Update Information: This manual supersedes the HP OpenVMS Utility Routines Manual, OpenVMS Alpha Version 8.3. Software Version: OpenVMS Version 8.4 for Integrity servers OpenVMS Alpha Version 8.4 Hewlett-Packard Company Palo Alto, California © Copyright 2010 Hewlett-Packard Development Company, L.P. Confidential computer software. Valid license from HP required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor’s standard commercial license. The information contained herein is subject to change without notice. The only warranties for HP products and services are set forth in the express warranty statements accompanying such products and services. Nothing herein should be construed as constituting an additional warranty. HP shall not be liable for technical or editorial errors or omissions contained herein. Intel and Itanium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries. ZK4493 The HP OpenVMS documentation set is available on CD. This document was prepared using DECdocument, Version 3.3-1B. Contents Preface ............................................................ xvii 1 Introduction to Utility Routines 2 Access Control List (ACL) Editor Routine 2.1 Introduction to the ACL Editor Routine ........................... ACL–1 2.2 Using the ACL Editor Routine: An Example ....................... ACL–1 2.3 ACL Editor Routine . ........................................ ACL–2 ACLEDIT$EDIT ...........................................
    [Show full text]
  • Design Patterns in Ocaml
    Design Patterns in OCaml Antonio Vicente [email protected] Earl Wagner [email protected] Abstract The GOF Design Patterns book is an important piece of any professional programmer's library. These patterns are generally considered to be an indication of good design and development practices. By giving an implementation of these patterns in OCaml we expected to better understand the importance of OCaml's advanced language features and provide other developers with an implementation of these familiar concepts in order to reduce the effort required to learn this language. As in the case of Smalltalk and Scheme+GLOS, OCaml's higher order features allows for simple elegant implementation of some of the patterns while others were much harder due to the OCaml's restrictive type system. 1 Contents 1 Background and Motivation 3 2 Results and Evaluation 3 3 Lessons Learned and Conclusions 4 4 Creational Patterns 5 4.1 Abstract Factory . 5 4.2 Builder . 6 4.3 Factory Method . 6 4.4 Prototype . 7 4.5 Singleton . 8 5 Structural Patterns 8 5.1 Adapter . 8 5.2 Bridge . 8 5.3 Composite . 8 5.4 Decorator . 9 5.5 Facade . 10 5.6 Flyweight . 10 5.7 Proxy . 10 6 Behavior Patterns 11 6.1 Chain of Responsibility . 11 6.2 Command . 12 6.3 Interpreter . 13 6.4 Iterator . 13 6.5 Mediator . 13 6.6 Memento . 13 6.7 Observer . 13 6.8 State . 14 6.9 Strategy . 15 6.10 Template Method . 15 6.11 Visitor . 15 7 References 18 2 1 Background and Motivation Throughout this course we have seen many examples of methodologies and tools that can be used to reduce the burden of working in a software project.
    [Show full text]
  • Scala by Example (2009)
    Scala By Example DRAFT January 13, 2009 Martin Odersky PROGRAMMING METHODS LABORATORY EPFL SWITZERLAND Contents 1 Introduction1 2 A First Example3 3 Programming with Actors and Messages7 4 Expressions and Simple Functions 11 4.1 Expressions And Simple Functions...................... 11 4.2 Parameters.................................... 12 4.3 Conditional Expressions............................ 15 4.4 Example: Square Roots by Newton’s Method................ 15 4.5 Nested Functions................................ 16 4.6 Tail Recursion.................................. 18 5 First-Class Functions 21 5.1 Anonymous Functions............................. 22 5.2 Currying..................................... 23 5.3 Example: Finding Fixed Points of Functions................ 25 5.4 Summary..................................... 28 5.5 Language Elements Seen So Far....................... 28 6 Classes and Objects 31 7 Case Classes and Pattern Matching 43 7.1 Case Classes and Case Objects........................ 46 7.2 Pattern Matching................................ 47 8 Generic Types and Methods 51 8.1 Type Parameter Bounds............................ 53 8.2 Variance Annotations.............................. 56 iv CONTENTS 8.3 Lower Bounds.................................. 58 8.4 Least Types.................................... 58 8.5 Tuples....................................... 60 8.6 Functions.................................... 61 9 Lists 63 9.1 Using Lists.................................... 63 9.2 Definition of class List I: First Order Methods..............
    [Show full text]
  • The Programming Language Concurrent Pascal
    IEEE TRANSACTIONS ON SOFTWARE ENGINEERING, VOL. SE-I, No.2, JUNE 1975 199 The Programming Language Concurrent Pascal PER BRINCH HANSEN Abstract-The paper describes a new programming language Disk buffer for structured programming of computer operating systems. It e.lt­ tends the sequential programming language Pascal with concurx:~t programming tools called processes and monitors. Section I eltplains these concepts informally by means of pictures illustrating a hier­ archical design of a simple spooling system. Section II uses the same enmple to introduce the language notation. The main contribu~on of Concurrent Pascal is to extend the monitor concept with an .ex­ Producer process Consumer process plicit hierarchy Of access' rights to shared data structures that can Fig. 1. Process communication. be stated in the program text and checked by a compiler. Index Terms-Abstract data types, access rights, classes, con­ current processes, concurrent programming languages, hierarchical operating systems, monitors, scheduling, structured multiprogram­ ming. Access rights Private data Sequential 1. THE PURPOSE OF CONCURRENT PASCAL program A. Background Fig. 2. Process. INCE 1972 I have been working on a new programming .. language for structured programming of computer S The next picture shows a process component in more operating systems. This language is called Concurrent detail (Fig. 2). Pascal. It extends the sequential programming language A process consists of a private data structure and a Pascal with concurrent programming tools called processes sequential program that can operate on the data. One and monitors [1J-[3]' process cannot operate on the private data of another This is an informal description of Concurrent Pascal.
    [Show full text]
  • 61A Lecture 6 Lambda Expressions VS Currying
    Announcements • Homework 2 due Tuesday 9/17 @ 11:59pm • Project 2 due Thursday 9/19 @ 11:59pm • Optional Guerrilla section next Monday for students to master higher-order functions . Organized by Andrew Huang and the readers 61A Lecture 6 . Work in a group on a problem until everyone in the group understands the solution • Midterm 1 on Monday 9/23 from 7pm to 9pm Friday, September 13 . Details and review materials will be posted early next week . There will be a web form for students who cannot attend due to a conflict 2 Lambda Expressions >>> ten = 10 An expression: this one evaluates to a number >>> square = x * x Also an expression: evaluates to a function Lambda Expressions >>> square = lambda x: x * x Important: No "return" keyword! A function with formal parameter x that returns the value of "x * x" >>> square(4) 16 Must be a single expression Lambda expressions are not common in Python, but important in general (Demo) Lambda expressions in Python cannot contain statements at all! 4 Lambda Expressions Versus Def Statements def square(x): square = lambda x: x * x VS return x * x • Both create a function with the same domain, range, and behavior. • Both functions have as their parent the environment in which they were defined. Currying • Both bind that function to the name square. • Only the def statement gives the function an intrinsic name. The Greek letter lambda Example: http://goo.gl/XH54uE 5 Function Currying def make_adder(n): return lambda k: n + k >>> make_adder(2)(3) There's a general 5 relationship between (Demo) >>> add(2, 3) these functions 5 Newton's Method Currying: Transforming a multi-argument function into a single-argument, higher-order function.
    [Show full text]
  • CSE 341 : Programming Languages
    CSE 341 : Programming Languages Lecture 10 Closure Idioms Zach Tatlock Spring 2014 More idioms • We know the rule for lexical scope and function closures – Now what is it good for A partial but wide-ranging list: • Pass functions with private data to iterators: Done • Combine functions (e.g., composition) • Currying (multi-arg functions and partial application) • Callbacks (e.g., in reactive programming) • Implementing an ADT with a record of functions (optional) 2 Combine functions Canonical example is function composition: fun compose (f,g) = fn x => f (g x) • Creates a closure that “remembers” what f and g are bound to • Type ('b -> 'c) * ('a -> 'b) -> ('a -> 'c) but the REPL prints something equivalent • ML standard library provides this as infix operator o • Example (third version best): fun sqrt_of_abs i = Math.sqrt(Real.fromInt(abs i)) fun sqrt_of_abs i = (Math.sqrt o Real.fromInt o abs) i val sqrt_of_abs = Math.sqrt o Real.fromInt o abs 3 Left-to-right or right-to-left val sqrt_of_abs = Math.sqrt o Real.fromInt o abs As in math, function composition is “right to left” – “take absolute value, convert to real, and take square root” – “square root of the conversion to real of absolute value” “Pipelines” of functions are common in functional programming and many programmers prefer left-to-right – Can define our own infix operator – This one is very popular (and predefined) in F# infix |> fun x |> f = f x fun sqrt_of_abs i = i |> abs |> Real.fromInt |> Math.sqrt 4 Another example • “Backup function” fun backup1 (f,g) = fn x => case
    [Show full text]