You are previewing Expert F# 4.0, Fourth Edition.
O'Reilly logo
Expert F# 4.0, Fourth Edition

Book Description

Learn from F#'s inventor to become an expert in the latest version of this powerful programming language so you can seamlessly integrate functional, imperative, object-oriented, and query programming style flexibly and elegantly to solve any programming problem. Expert F# 4.0 will help you achieve unrivaled levels of programmer productivity and program clarity across multiple platforms including Windows, Linux, Android, OSX, and iOS as well as HTML5 and GPUs.

F# 4.0 is a mature, open source, cross-platform, functional-first programming language which empowers users and organizations to tackle complex computing problems with simple, maintainable, and robust code.

Expert F# 4.0 is:

  • A comprehensive guide to the latest version of F# by the inventor of the language
  • A treasury of F# techniques for practical problem-solving
  • An in-depth case book of F# applications and F# 4.0 concepts, syntax, and features
  • Written by F#'s inventor and two major F# community members, Expert F# 4.0 is a comprehensive and in-depth guide to the language and its use. Designed to help others become experts, the book quickly yet carefully describes the paradigms supported by F# language, and then shows how to use F# elegantly for a practical web, data, parallel and analytical programming tasks.

    The world's experts in F# show you how to program in F# the way they do!

    Table of Contents

    1. Cover
    2. Title
    3. Copyright
    4. Contents at a Glance
    5. Contents
    6. About the Authors
    7. About the Technical Reviewers
    8. Acknowledgments
    9. Chapter 1: Introduction
      1. The Genesis of F#
      2. About This Book
      3. Who This Book Is For
    10. Chapter 2: Your First F# Program: Getting Started with F#
      1. Creating Your First F# Program
        1. Documenting Code
        2. Using let
        3. Understanding Types
        4. Calling Functions
        5. Lightweight Syntax
        6. Understanding Scope
        7. Using Data Structures
        8. Using Properties and the Dot-Notation
        9. Using Tuples
        10. Using Imperative Code
      2. Using Object-Oriented Libraries from F#
        1. Using open to Access Namespaces and Modules
        2. Fetching a Web Page
      3. Getting and Using Packages
      4. Accessing External Data Using F# Packages
      5. Starting a Web Server and Serving Data using F# Packages
      6. Summary
    11. Chapter 3: Introducing Functional Programming
      1. Starting with Numbers and Strings
        1. Some Simple Types and Literals
        2. Arithmetic Conversions
        3. Arithmetic Comparisons
        4. Simple Strings
      2. Working with Conditionals: & and ||
      3. Defining Recursive Functions
      4. Lists
      5. Options
      6. Getting Started with Pattern Matching
        1. Matching on Structured Values
        2. Guarding Rules and Combining Patterns
        3. Further Ways of Forming Patterns
      7. Introducing Function Values
        1. Using Function Values
        2. Computing with Collection Functions
        3. Using Fluent Notation on Collections
        4. Composing Functions with >>
        5. Building Functions with Partial Application
        6. Using Local Functions
        7. Iterating with Functions
        8. Abstracting Control with Functions
        9. Using Object Methods as First-Class Functions
        10. Some Common Uses of Function Values
      8. Summary
    12. Chapter 4: Introducing Imperative Programming
      1. About Functional and Imperative Programming
      2. Imperative Looping and Iterating
        1. Simple for Loops
        2. Simple While Loops
        3. More Iteration Loops over Sequences
      3. Using Mutable Records
        1. Avoiding Aliasing
      4. Using Mutable let Bindings
        1. Hiding Mutable Data
      5. Working with Arrays
        1. Generating and Slicing Arrays
        2. Two-Dimensional Arrays
      6. Introducing the Imperative .NET Collections
        1. Using Resizable Arrays
        2. Using Dictionaries
        3. Using Dictionary’s TryGetValue
        4. Using Dictionaries with Compound Keys
        5. Some Other Mutable Data Structures
      7. Exceptions and Controlling Them
        1. Catching Exceptions
        2. Using try . . . finally
        3. Defining New Exception Types
      8. Having an Effect: Basic I/O
        1. .NET I/O via Streams
        2. Some Other I/O-Related Types
        3. Using System.Console
      9. Combining Functional and Imperative Efficient Precomputation and Caching
        1. Precomputation and Partial Application
        2. Precomputation and Objects
        3. Memoizing Computations
        4. Lazy Values
        5. Other Variations on Caching and Memoization
        6. Mutable Reference Cells
      10. Combining Functional and Imperative: Functional Programming with Side Effects
        1. Consider Replacing Mutable Locals and Loops with Recursion
        2. Separating Pure Computation from Side-Effecting Computations
        3. Separating Mutable Data Structures
        4. Not All Side Effects Are Equal
        5. Avoid Combining Imperative Programming and Laziness
      11. Summary
    13. Chapter 5: Understanding Types in Functional Programming
      1. Exploring Some Simple Type Definitions
        1. Defining Type Abbreviations
        2. Defining Record Types
        3. Handling Non-Unique Record Field Names
        4. Cloning Records
        5. Defining Discriminated Unions
        6. Using Discriminated Unions as Records
        7. Defining Multiple Types Simultaneously
      2. Understanding Generics
        1. Writing Generic Functions
        2. Some Important Generic Functions
      3. Making Things Generic
        1. Generic Algorithms through Explicit Arguments
        2. Generic Algorithms through Function Parameters
        3. Generic Algorithms through Inlining
      4. More on Different Kinds of Types
        1. Reference Types and Value Types
        2. Other Flavors of .NET Types
      5. Understanding Subtyping
        1. Casting Up Statically
        2. Casting Down Dynamically
        3. Performing Type Tests via Pattern Matching
        4. Knowing When Upcasts Are Applied Automatically
        5. Flexible Types
      6. Troubleshooting Type-Inference Problems
        1. Using a Visual Editing Environment
        2. Using Type Annotations
        3. Understanding the Value Restriction
        4. Working Around the Value Restriction
        5. Understanding Generic Overloaded Operators
      7. Summary
    14. Chapter 6: Programming with Objects
      1. Getting Started with Objects and Members
      2. Using Classes
      3. Adding Further Object Notation to Your Types
        1. Working with Indexer Properties
        2. Adding Overloaded Operators
        3. Using Named and Optional Arguments
        4. Adding Method Overloading
      4. Defining Object Types with Mutable State
        1. Using Optional Property Settings
        2. Declaring Auto-Properties
      5. Getting Started with Object Interface Types
        1. Defining New Object Interface Types
        2. Implementing Object Interface Types Using Object Expressions
        3. Implementing Object Interface Types Using Concrete Types
        4. Using Common Object Interface Types from the .NET Libraries
        5. Understanding Hierarchies of Object Interface Types
      6. More Techniques for Implementing Objects
        1. Combining Object Expressions and Function Parameters
        2. Defining Partially Implemented Class Types
        3. Using Partially Implemented Types via Delegation
        4. Using Partially Implemented Types via Implementation Inheritance
      7. Combining Functional and Objects: Cleaning Up Resources
        1. Resources and IDisposable
        2. Managing Resources with More-Complex Lifetimes
        3. Cleaning Up Internal Objects
        4. Cleaning Up Unmanaged Objects
      8. Extending Existing Types and Modules
      9. Working with F# Objects and .NET Types
        1. Structs
        2. Delegates
        3. Enums
        4. Working with null Values
      10. Summary
    15. Chapter 7: Encapsulating and Organizing Your Code
      1. Hiding Things
        1. Hiding Things with Local Definitions
        2. Hiding Things with Accessibility Annotations
      2. Organizing Code with Namespaces and Modules
        1. Putting Your Code in a Module
        2. Putting Your Modules and Types in Namespaces
        3. Defining a Module with the Same Name as a Type
        4. Preventing Client Code from Opening a Module
        5. Using Files as Modules
        6. Automatically Opening Modules
      3. Projects, Assemblies, and Compilation Order
        1. Creating Assemblies, DLLs, and EXEs
        2. Project Files and Compilation Order
      4. Using Signature Files
        1. Designing with Signatures
        2. When Are Signature Types Checked?
      5. Reusing Your Code
        1. Using Files as Small Reusable Components
      6. Creating and Sharing Packages
      7. Summary
    16. Chapter 8: Working with Textual Data
      1. Building Strings and Formatting Data
        1. Building Strings
        2. More about String Literals
        3. Using printf and Friends
        4. Generic Structural Formatting
        5. Formatting Strings Using .NET Formatting
      2. Parsing Strings and Textual Data
        1. Parsing Basic Values
        2. Processing Line-Based Input
      3. Using Regular Expressions
        1. More on Matching with System.Text.RegularExpressions
        2. More Robust Code with the Regular Expression Type Provider
      4. Using XML as a Concrete Language Format
        1. Using the System.Xml Namespace
        2. From Concrete XML to Abstract Syntax
        3. Using the FSharp.Data XmlTypeProvider
      5. Using JSON as a Concrete Language Format
        1. Parsing JSON Data
        2. Using the FSharp.Data JsonProvider
      6. Some Recursive Descent Parsing
        1. A Simple Tokenizer
        2. Recursive-Descent Parsing
      7. Binary Parsing and Formatting
        1. Encoding and Decoding Unicode Strings
        2. Encoding and Decoding Binary Data
      8. Summary
    17. Chapter 9: Working with Sequences and Tree-Structured Data
      1. Getting Started with Sequences
        1. Using Range Expressions
        2. Iterating a Sequence
        3. Transforming Sequences with Functions
        4. Which Types Can Be Used as Sequences?
        5. Using Lazy Sequences from External Sources
        6. Using Sequence Expressions
        7. Enriching Sequence Expressions with Additional Logic
        8. Generating Lists and Arrays Using Sequence Expressions
      2. More on Working with Sequences
        1. Using Other Sequence Operators: Truncate and Sort
        2. Selecting Multiple Elements from Sequences
        3. Finding Elements and Indexes in Sequences
        4. Grouping and Indexing Sequences
        5. Folding Sequences
        6. Cleaning Up in Sequence Expressions
        7. Expressing Operations Using Sequence Expressions
      3. Structure beyond Sequences: Domain Modeling
        1. Transforming Domain Models
        2. Using On-Demand Computation with Domain Models
        3. Caching Properties in Domain Models
        4. Memoizing Construction of Domain Model Nodes
      4. Active Patterns: Views for Structured Data
        1. Converting the Same Data to Many Views
        2. Matching on .NET Object Types
        3. Defining Partial and Parameterized Active Patterns
        4. Hiding Representations with Active Patterns
      5. Equality, Hashing, and Comparison
        1. Asserting Equality, Hashing, and Comparison Using Attributes
        2. Fully Customizing Equality, Hashing, and Comparison on a Type
        3. Suppressing Equality, Hashing, and Comparison on a Type
        4. Customizing Generic Collection Types
      6. Tail Calls and Recursive Programming
        1. Tail Recursion and List Processing
        2. Tail Recursion and Object-Oriented Programming
        3. Tail Recursion and Processing Unbalanced Trees
        4. Using Continuations to Avoid Stack Overflows
        5. Another Example: Processing Syntax Trees
      7. Summary
    18. Chapter 10: Numeric Programming and Char?ting
      1. Getting Started with FsLab
      2. Basic Charting with FSharp.Charting
      3. Basic Numeric Types and Literals
        1. Arithmetic Operators
        2. Checked Arithmetic
        3. Arithmetic Conversions
        4. Arithmetic Comparisons
        5. Overloaded Math Functions
        6. Bitwise Operations
      4. Sequences, Statistics, and Numeric Code
        1. Summing, Averaging, Maximizing, and Minimizing Sequences
        2. Counting and Categorizing
        3. Writing Fresh Numeric Code
        4. Making Numeric Code Generic
        5. Example: KMeans
      5. Statistics, Linear Algebra, and Distributions with Math.NET
        1. Basic Statistical Functions in Math.NET Numerics
        2. Using Histograms and Distributions from Math.NET Numerics
        3. Using Matrices and Vectors from Math.NET
        4. Matrix Inverses, Decomposition, and Eigenvalues
      6. Time Series and Data Frames with Deedle
      7. Units of Measure
        1. Adding Units to a Numeric Algorithms
        2. Adding Units to a Type Definition
        3. Applying and Removing Units
        4. Some Limitations of Units of Measure
      8. Summary
    19. Chapter 11: Reactive, Asynchronous, and Parallel Programming
      1. Introducing Terminology
      2. Events
        1. Creating and Publishing Events
        2. Events as First-Class Values
        3. From Events to Observables
      3. Asynchronous Computations
        1. Fetching Multiple Web Pages in Parallel, Asynchronously
        2. Understanding Asynchronous Computations
        3. Example: Parallel File Processing Using Async Computations
        4. Running Async Computations
        5. Common I/O Operations in Asynchronous Computations
        6. Understanding Exceptions and Cancellations
        7. Interoperating with .NET Tasks
      4. Agents
        1. Introducing Agents
        2. Creating Objects That React to Messages
        3. ScanningMailboxes for Relevant Messages
      5. Example: An Asynchronous Agent for Web Crawling
        1. Example: Using async for CPU Parallelism
        2. Under the Hood: Implementing Async.Parallel
      6. Using Shared-Memory Concurrency
        1. Creating Threads Explicitly
        2. Creating Tasks Explicitly
        3. Shared Memory, Race Conditions, and the .NET Memory Model
        4. Using Locks to Avoid Race Conditions
        5. Using ReaderWriterLock
        6. Some Other Concurrency Primitives
      7. Summary
    20. Chapter 12: Symbolic Programming with Structured Data
      1. Verifying Circuits with Propositional Logic
        1. Representing Propositional Logic
        2. Evaluating Propositional Logic Naively
        3. From Circuits to Propositional Logic
        4. Checking Simple Properties of Circuits
        5. Representing Propositional Formulae Efficiently Using BDDs
        6. Circuit Verification with BDDs
      2. Expression Simplification and Differentiation
        1. Implementing Local Simplifications
        2. A Richer Language of Algebraic Expressions
        3. Parsing Algebraic Expressions
        4. Simplifying Algebraic Expressions
        5. Symbolic Differentiation of Algebraic Expressions
        6. The Driver
        7. The Web API
      3. Summary
    21. Chapter 13: Integrating External Data and Services
      1. Some Basic REST Requests
        1. Getting Data in JSON Format
        2. Parsing and Handling Multiple Pages
      2. Getting Started with Queries
        1. Example: Language-Integrated SQL
        2. Sorting
        3. Aggregation
        4. Nullables
        5. Inner Queries
        6. Grouping
        7. Joins
      3. More Choices for SQL
        1. Directly Embedding T-SQL Using SqlCommandProvider
        2. Raw Access to Databases Using ADO.NET
        3. Establishing Connections Using ADO.NET
        4. Creating a Database Using ADO.NET
        5. Creating Tables Using ADO.NET
        6. Using Stored Procedures via ADO.NET
      4. Summary
    22. Chapter 14: Building Smart Web Applications
      1. Serving Web Content Directly
      2. Rich Client Web Applications with WebSharper
        1. Getting Started with WebSharper
        2. Pagelets - Working with Reactive HTML and Client-Side Code
        3. HTML Templates
        4. Sitelets
        5. Developing REST Applications
        6. Formlets and Piglets: Building Functional Web Forms
        7. Automated Resource Tracking and Handling
        8. Using Third-Party JavaScript Libraries
        9. Working with .NET Proxies
      3. Summary
    23. Chapter 15: Visualization and Graphical User Interfaces
      1. Getting Started with Eto
      2. Writing “Hello, World!” in a Click
      3. Understanding the Anatomy of a Graphical Application
      4. Composing Controls and Menus
      5. Composing User Interfaces
      6. Drawing Applications
      7. Creating a Mandelbrot Viewer
        1. Computing Mandelbrot
        2. Setting Colors
        3. Creating the Visualization Application
        4. Creating the Application Plumbing
      8. Writing Your Own Controls
        1. Developing a Custom Control
        2. Anatomy of a Control
      9. The World, the View, and Coordinate Systems
        1. Drawing an Analog Clock
        2. World and View Coordinates
      10. Lightweight Controls
      11. Summary
    24. Chapter 16: Language-Oriented Programming
      1. Computation Expressions
        1. An Example: Success/Failure Computation Expressions
        2. Defining a Computation-Expression Builder
        3. Computation Expressions and Untamed Side Effects
        4. Computation Expressions with Custom Query Operators
        5. Example: Probabilistic Computations
        6. Combining Computation Expressions and Resources
        7. Recursive Workflow Expressions
      2. Using F# Reflection
        1. Reflecting on Types
        2. Schema Compilation by Reflecting on Types
        3. Using the F# Dynamic Reflection Operators
      3. Using F# Quotations
        1. Example: Using F# Quotations for Error Estimation
        2. Resolving Reflected Definitions
      4. Writing an F# Type Provider
      5. Summary
    25. Chapter 17: Libraries and Interoperability
      1. Types, Memory, and Interoperability
      2. Libraries: A High-Level Overview
        1. Namespaces from the .NET Framework
        2. Namespaces from FSharp.Core and FSharp.Data Libraries
        3. Some F# Community Libraries
      3. Using the System Types
      4. Using Further F# and .NET Data Structures
        1. System.Collections.Generic and Other .NET Collections
      5. Supervising and Isolating Execution
      6. Further Libraries for Reflective Techniques
        1. Using General Types
        2. Using FSharp.Reflection
        3. Some Other .NET Types You May Encounter
        4. Some F# Community Type Providers
      7. Under the Hood: Interoperating with C# and Other .NET Languages
        1. Memory Management at Runtime
      8. Interoperating with C and C++ with PInvoke
        1. Getting Started with PInvoke
        2. Mapping C Data Structures to F# Code
        3. Marshalling Parameters to and from C
        4. Marshalling Strings to and from C
        5. Passing Function Pointers to C
        6. Wrapper Generation and the Limits of PInvoke
      9. Summary
    26. Chapter 18: Developing and Testing F# Code
      1. Developing Your Code
        1. Editing Your Code
        2. Mixing Scripting and Compiled Code
        3. Choosing Optimization Settings
        4. Generating Documentation
        5. Building Libraries
        6. Using Static Linking
        7. Packaging Different Kinds of Code
        8. Managing Dependencies
        9. Using Data and Configuration Settings
      2. Using F# Interactive Effectively
        1. Controlling F# Interactive
        2. Some Common F# Interactive Directives
        3. Understanding How F# Interactive Compiles Code
      3. Using Tracing Diagnostics
      4. Debugging Your Code with an IDE
        1. Debugging Across Multiple Languages
        2. Debugging Concurrent Applications
      5. Testing Your Code
        1. Using Test Fixtures in NUnit/XUnit
        2. Combining NUnit/XUnit and F# Interactive Debugging
        3. Property-based Testing Using FsCheck
      6. Summary
    27. Chapter 19: Designing F# Libraries
      1. Designing Vanilla .NET Libraries
      2. Understanding Functional-Design Methodology
        1. Understanding Where Functional Programming Comes From
        2. Understanding Functional-Design Methodology
      3. Applying the Good Library Design to F#
        1. Recommendation: Use Correct Naming and Capitalization Conventions Where Possible
        2. Recommendation: Avoid Using Underscores in Names
        3. Recommendation: Follow the Recommended Guidelines for Exceptions
        4. Recommendation: Consider Using Option Values for Return Types Instead of Raising Exceptions
        5. Recommendation: Follow the Recommended Guidelines for Value Types
        6. Recommendation: Consider Using Explicit Signature Files for Your Framework
        7. Recommendation: Consider Avoiding the Use of Implementation Inheritance for Extensibility
        8. Recommendation: Use Properties and Methods for Attributes and Operations Essential to a Type
        9. Recommendation: Avoid Revealing Concrete Data Representations Such as Records
        10. Recommendation: Use Active Patterns to Hide the Implementations of Discriminated Unions
        11. Recommendation: Use Object-Interface Types Instead of Tuples or Records of Functions
        12. Recommendation: Understand When Currying Is Useful in Functional Programming APIs
        13. Recommendation: Use Tuples for Return Values, Arguments, and Intermediate Values
        14. Recommendation: Use Async for Asynchronous Computations
        15. Recommendation: Use Choice or a Named Type for Alternative Results
      4. Some Recommended Coding Idioms
        1. Recommendation: Use the Standard Operators
        2. Recommendation: Place the Pipeline Operator |> at the Start of a Line
        3. Recommendation: Format Object Expressions Using the member Syntax
      5. Summary
    28. Appendix: F# Brief Language Guide
      1. Comments and Attributes
      2. Basic Types and Literals
      3. Types
      4. Patterns and Matching
      5. Functions, Composition, and Pipelining
      6. Binding and Control Flow
      7. Exceptions
      8. Tuples, Arrays, Lists, and Collections
      9. Operators
      10. Type Definitions and Objects
      11. Namespaces and Modules
      12. Sequence Expressions and Workflows
      13. Queries and Quotations
    29. Index