You are previewing Expert F# 2.0.
O'Reilly logo
Expert F# 2.0

Book Description

Expert F# 2.0 is about practical programming in a beautiful language that puts the power and elegance of functional programming into the hands of professional developers. In combination with .NET, F# achieves unrivaled levels of programmer productivity and program clarity.

Expert F# 2.0 is

  • The authoritative guide to F# by the inventor of F#

  • A comprehensive reference of F# concepts, syntax, and features

  • A treasury of expert F# techniques for practical, real-world programming

F# isn't just another functional programming language. It's a general-purpose language ideal for real-world development. F# seamlessly integrates functional, imperative, and object-oriented programming styles so you can flexibly and elegantly solve any programming problem. Whatever your background, you'll find that F# is easy to learn, fun to use, and extraordinarily powerful. F# will change the way you think about—and go about—programming.

Written by F#'s inventor and two major contributors to its development, Expert F# 2.0 is the authoritative, comprehensive, and in-depth guide to the language and its use. Designed to help others become experts, the first part of the book quickly yet carefully describes the F# language. The second part then shows how to use F# elegantly for a wide variety of practical programming tasks.

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

Table of Contents

  1. Copyright
  2. Foreword
  3. About the Authors
  4. About the Technical Reviewer
  5. Acknowledgments
  6. 1. Introduction
    1. 1.1. The Genesis of F#
    2. 1.2. About This Book
    3. 1.3. Who This Book Is For
  7. 2. Getting Started with F# and .NET
    1. 2.1. Creating Your First F# Program
      1. 2.1.1. Documenting Code Using XMLDocs
      2. 2.1.2. Using let
      3. 2.1.3. Understanding Types
      4. 2.1.4. Calling Functions
      5. 2.1.5. Lightweight Syntax
      6. 2.1.6. Understanding Scope
      7. 2.1.7. Using Data Structures
      8. 2.1.8. Using Properties and the Dot-Notation
      9. 2.1.9. Using Tuples
      10. 2.1.10. Using Imperative Code
    2. 2.2. Using .NET Libraries from F#
      1. 2.2.1. Using open to Access Namespaces and Modules
      2. 2.2.2. Using new and Setting Properties
      3. 2.2.3. Fetching a Web Page
    3. 2.3. Summary
  8. 3. Creating Your First F# Program—Introducing Functional Programming
    1. 3.1. Getting Started with F# Arithmetic
      1. 3.1.1. Basic Literals
      2. 3.1.2. Arithmetic Operators
      3. 3.1.3. Bitwise Operations
      4. 3.1.4. Arithmetic Conversions
      5. 3.1.5. Arithmetic Comparisons
      6. 3.1.6. Overloaded Math Functions
    2. 3.2. Introducing Simple Strings
      1. 3.2.1. Working with String Literals and Primitives
      2. 3.2.2. Building Strings
    3. 3.3. Working with Lists and Options
      1. 3.3.1. Using F# Lists
      2. 3.3.2. Using F# Option Values
      3. 3.3.3. Using Option Values for Control
      4. 3.3.4. Working with Conditionals: && and ||
    4. 3.4. Defining Recursive Functions
    5. 3.5. Introducing Function Values
      1. 3.5.1. Using Anonymous Function Values
      2. 3.5.2. Computing with Aggregate Operators
      3. 3.5.3. Composing Functions with >>
      4. 3.5.4. Building Functions with Partial Application
      5. 3.5.5. Using Local Functions
      6. 3.5.6. Using Functions as Abstract Values
      7. 3.5.7. Iterating with Aggregate Operators
      8. 3.5.8. Abstracting Control with Functions
      9. 3.5.9. Using .NET Methods as First-Class Functions
    6. 3.6. Getting Started with Pattern Matching
      1. 3.6.1. Matching on Structured Values
      2. 3.6.2. Guarding Rules and Combining Patterns
    7. 3.7. Getting Started with Sequences
      1. 3.7.1. Using Range Expressions
      2. 3.7.2. Iterating a Sequence
      3. 3.7.3. Transforming Sequences with Aggregate Operators
      4. 3.7.4. Which Types Can Be Used as Sequences?
      5. 3.7.5. Using Lazy Sequences from External Sources
    8. 3.8. Using Sequence Expressions
      1. 3.8.1. Creating Sequence Expressions Using for
      2. 3.8.2. Enriching Sequence Expressions with Additional Logic
      3. 3.8.3. Generating Lists and Arrays Using Sequence Expressions
    9. 3.9. Exploring Some Simple Type Definitions
      1. 3.9.1. Defining Type Abbreviations
      2. 3.9.2. Defining Records
      3. 3.9.3. Handling Non-Unique Record Field Names
      4. 3.9.4. Cloning Records
      5. 3.9.5. Defining Discriminated Unions
      6. 3.9.6. Using Discriminated Unions as Records
      7. 3.9.7. Defining Multiple Types Simultaneously
    10. 3.10. Summary
  9. 4. Introducing Imperative Programming
    1. 4.1. Imperative Looping and Iterating
      1. 4.1.1. Simple for Loops
      2. 4.1.2. Simple while Loops
      3. 4.1.3. More Iteration Loops over Sequences
    2. 4.2. Using Mutable Records
      1. 4.2.1. Mutable Reference Cells
      2. 4.2.2. Avoiding Aliasing
      3. 4.2.3. Hiding Mutable Data
    3. 4.3. Using Mutable Locals
    4. 4.4. Working with Arrays
      1. 4.4.1. Generating and Slicing Arrays
      2. 4.4.2. Two-Dimensional Arrays
    5. 4.5. Introducing the Imperative .NET Collections
      1. 4.5.1. Using Resizeable Arrays
      2. 4.5.2. Using Dictionaries
      3. 4.5.3. Using Dictionary's TryGetValue
      4. 4.5.4. Using Dictionaries with Compound Keys
      5. 4.5.5. Some Other Mutable Data Structures
    6. 4.6. Exceptions and Controlling Them
      1. 4.6.1. Catching Exceptions
      2. 4.6.2. Using try . . . finally
      3. 4.6.3. Defining New Exception Types
    7. 4.7. Having an Effect: Basic I/O
      1. 4.7.1. Very Simple I/O: Reading and Writing Files
      2. 4.7.2. .NET I/O via Streams
      3. 4.7.3. Some Other I/O-Related Types
      4. 4.7.4. Using System.Console
      5. 4.7.5. Using printf and Friends
      6. 4.7.6. Generic Structural Formatting
      7. 4.7.7. Cleaning Up with IDisposable, use, and using
    8. 4.8. Working with null Values
    9. 4.9. Some Advice: Functional Programming with Side Effects
      1. 4.9.1. Consider Replacing Mutable Locals and Loops with Recursion
      2. 4.9.2. Separate Pure Computation from Side-Effecting Computations
      3. 4.9.3. Separate Mutable Data Structures
      4. 4.9.4. Not All Side Effects Are Equal
      5. 4.9.5. Avoid Combining Imperative Programming and Laziness
    10. 4.10. Summary
  10. 5. Mastering Types and Generics
    1. 5.1. Understanding Generic Type Variables
    2. 5.2. Writing Generic Functions
    3. 5.3. Understanding Some Important Generic Functions
      1. 5.3.1. Generic Comparison
      2. 5.3.2. Generic Hashing
      3. 5.3.3. Generic Pretty-Printing
      4. 5.3.4. Generic Boxing and Unboxing
      5. 5.3.5. Generic Binary Serialization via the .NET Libraries
    4. 5.4. Making Things Generic
      1. 5.4.1. Generic Algorithms through Explicit Arguments
      2. 5.4.2. Generic Algorithms through Abstract Object Types
      3. 5.4.3. Arithmetic Operators and Generic Algorithms through Inlining
    5. 5.5. Understanding .NET Types
      1. 5.5.1. Reference Types and Value Types
      2. 5.5.2. Other Flavors of .NET Types
    6. 5.6. Understanding Subtyping
      1. 5.6.1. Casting Up Statically
      2. 5.6.2. Casting Down Dynamically
      3. 5.6.3. Performing Type Tests via Pattern Matching
      4. 5.6.4. Knowing When Upcasts Are Applied Automatically
      5. 5.6.5. Flexible Types
    7. 5.7. Units of Measure
    8. 5.8. Troubleshooting Type-Inference Problems
      1. 5.8.1. Using a Visual Editing Environment
      2. 5.8.2. Using Type Annotations
      3. 5.8.3. Understanding the Value Restriction
      4. 5.8.4. Working Around the Value Restriction
        1. 5.8.4.1. Technique 1: Constrain Values to Be Nongeneric
        2. 5.8.4.2. Technique 2: Ensure Generic Functions Have Explicit Arguments
        3. 5.8.4.3. Technique 3: Add Dummy Arguments to Generic Functions When Necessary
        4. 5.8.4.4. Technique 4: Add Explicit Type Arguments When Necessary
      5. 5.8.5. Understanding Generic Overloaded Operators
    9. 5.9. Summary
  11. 6. Working with Objects and Modules
    1. 6.1. Getting Started with Objects and Members
    2. 6.2. Using Classes
    3. 6.3. Adding Further Object Notation to Your Types
      1. 6.3.1. Working with Indexer Properties
      2. 6.3.2. Adding Overloaded Operators
      3. 6.3.3. Using Named and Optional Arguments
      4. 6.3.4. Using Optional Property Settings
      5. 6.3.5. Adding Method Overloading
    4. 6.4. Defining Object Types with Mutable State
    5. 6.5. Getting Started with Object Interface Types
      1. 6.5.1. Defining New Object Interface Types
      2. 6.5.2. Implementing Object Interface Types Using Object Expressions
      3. 6.5.3. Implementing Object Interface Types Using Concrete Types
      4. 6.5.4. Using Common Object Interface Types from the .NET Libraries
      5. 6.5.5. Understanding Hierarchies of Object Interface Types
    6. 6.6. More Techniques to Implement Objects
      1. 6.6.1. Combining Object Expressions and Function Parameters
      2. 6.6.2. Defining Partially Implemented Class Types
      3. 6.6.3. Using Partially Implemented Types via Delegation
      4. 6.6.4. Using Partially Implemented Types via Implementation Inheritance
    7. 6.7. Using Modules and Static Members
    8. 6.8. Extending Existing Types and Modules
    9. 6.9. Working with F# Objects and .NET Types
      1. 6.9.1. Structs
      2. 6.9.2. Delegates
      3. 6.9.3. Enums
    10. 6.10. Summary
  12. 7. Encapsulating and Packaging Your Code
    1. 7.1. Hiding Things Away
      1. 7.1.1. Hiding Things with Local Definitions
      2. 7.1.2. Hiding Things with Accessibility Annotations
    2. 7.2. Using Namespaces and Modules
      1. 7.2.1. Putting Your Code in a Namespace
      2. 7.2.2. Using Files as Modules
    3. 7.3. Creating Assemblies, DLLs, and EXEs
      1. 7.3.1. Compiling EXEs
      2. 7.3.2. Compiling DLLs
      3. 7.3.3. Mixing Scripting and Compiled Code
      4. 7.3.4. Choosing Optimization Settings
      5. 7.3.5. Generating Documentation
      6. 7.3.6. Building Shared Libraries and Using the Global Assembly Cache
      7. 7.3.7. Using Static Linking
    4. 7.4. Using Signature Types and Files
      1. 7.4.1. Using Explicit Signature Types and Signature Files
      2. 7.4.2. When Are Signature Types Checked?
    5. 7.5. Packaging Applications
      1. 7.5.1. Packaging Different Kinds of Code
      2. 7.5.2. Using Data and Configuration Settings
    6. 7.6. Summary
  13. 8. Mastering F#: Common Techniques
    1. 8.1. Equality, Hashing, and Comparison
      1. 8.1.1. Asserting Equality, Hashing, and Comparison Using Attributes
      2. 8.1.2. Fully Customizing Equality, Hashing, and Comparison on a Type
      3. 8.1.3. Suppressing Equality, Hashing, and Comparison on a Type
      4. 8.1.4. Customizing Generic Collection Types
    2. 8.2. Efficient Precomputation and Caching
      1. 8.2.1. Precomputation and Partial Application
      2. 8.2.2. Precomputation and Objects
      3. 8.2.3. Memoizing Computations
      4. 8.2.4. Lazy Values
      5. 8.2.5. Other Variations on Caching and Memoization
    3. 8.3. Cleaning Up Resources
      1. 8.3.1. Cleaning Up with use
      2. 8.3.2. Managing Resources with More Complex Lifetimes
      3. 8.3.3. Cleaning Up Internal Objects
      4. 8.3.4. Cleaning Up Unmanaged Objects
      5. 8.3.5. Cleaning Up in Sequence Expressions
      6. 8.3.6. Using using
    4. 8.4. Stack as a Resource: Tail Calls and Recursion
      1. 8.4.1. Tail Recursion and List Processing
      2. 8.4.2. Tail Recursion and Object-Oriented Programming
      3. 8.4.3. Tail Recursion and Processing Unbalanced Trees
      4. 8.4.4. Using Continuations to Avoid Stack Overflows
      5. 8.4.5. Another Example: Processing Syntax Trees
    5. 8.5. Events
      1. 8.5.1. Events as First-Class Values
      2. 8.5.2. Creating and Publishing Events
    6. 8.6. Summary
  14. 9. Introducing Language-Oriented Programming
    1. 9.1. Using XML as a Concrete Language Format
      1. 9.1.1. Using the System.Xml Namespace
      2. 9.1.2. From Concrete XML to Abstract Syntax
    2. 9.2. Working with Abstract Syntax Representations
      1. 9.2.1. Abstract Syntax Representations: Less Is More
      2. 9.2.2. Processing Abstract Syntax Representations
      3. 9.2.3. Transformational Traversals of Abstract Syntax Representations
      4. 9.2.4. Using On-Demand Computation with Abstract Syntax Trees
      5. 9.2.5. Caching Properties in Abstract Syntax Trees
      6. 9.2.6. Memoizing Construction of Syntax Tree Nodes
    3. 9.3. Introducing Active Patterns
      1. 9.3.1. Converting the Same Data to Many Views
      2. 9.3.2. Matching on .NET Object Types
      3. 9.3.3. Defining Partial and Parameterized Active Patterns
      4. 9.3.4. Hiding Abstract Syntax Implementations with Active Patterns
    4. 9.4. Embedded Computational Languages with Workflows
      1. 9.4.1. An Example: Success/Failure Workflows
      2. 9.4.2. Defining a Workflow Builder
      3. 9.4.3. Workflows and Untamed Side Effects
      4. 9.4.4. Example: Probabilistic Workflows
      5. 9.4.5. Combining Workflows and Resources
      6. 9.4.6. Recursive Workflow Expressions
    5. 9.5. Using F# Reflection
      1. 9.5.1. Reflecting on Types
      2. 9.5.2. Schema Compilation by Reflecting on Types
      3. 9.5.3. Using the F# Dynamic Reflection Operators
    6. 9.6. Using F# Quotations
      1. 9.6.1. Example: Using F# Quotations for Error Estimation
      2. 9.6.2. Resolving Top Definitions
    7. 9.7. Summary
  15. 10. Using the F# and .NET Libraries
    1. 10.1. A High-Level Overview
      1. 10.1.1. Namespaces from the .NET Framework
      2. 10.1.2. Namespaces from the F# Libraries
    2. 10.2. Using the System Types
    3. 10.3. Using Regular Expressions and Formatting
      1. 10.3.1. Matching with System.Text.RegularExpressions
      2. 10.3.2. Formatting Strings Using .NET Formatting
      3. 10.3.3. Encoding and Decoding Unicode Strings
      4. 10.3.4. Encoding and Decoding Binary Data
    4. 10.4. Using Further F# and .NET Data Structures
      1. 10.4.1. System.Collections.Generic and Other .NET Collections
    5. 10.5. Introducing Microsoft.FSharp.Math
      1. 10.5.1. Using Matrices and Vectors
      2. 10.5.2. Using Operator Overloads on Matrices and Vectors
    6. 10.6. Supervising and Isolating Execution
    7. 10.7. Further Libraries for Reflective Techniques
      1. 10.7.1. Using General Types
      2. 10.7.2. Using Microsoft.FSharp.Reflection
    8. 10.8. Some Other .NET Types You May Encounter
    9. 10.9. Some Other .NET Libraries
    10. 10.10. Summary
  16. 11. Building Graphical User Interfaces
    1. 11.1. Writing "Hello, World!" in a Click
    2. 11.2. Understanding the Anatomy of a Graphical Application
    3. 11.3. Composing User Interfaces
    4. 11.4. Drawing Applications
    5. 11.5. Writing Your Own Controls
      1. 11.5.1. Developing a Custom Control
      2. 11.5.2. Anatomy of a Control
    6. 11.6. Displaying Samples from Sensors
      1. 11.6.1. Building the GraphControl: The Model
      2. 11.6.2. Building the GraphControl: Style Properties and Controller
      3. 11.6.3. Building the GraphControl: The View
      4. 11.6.4. Putting It Together
    7. 11.7. Creating a Mandelbrot Viewer
      1. 11.7.1. Computing Mandelbrot
      2. 11.7.2. Setting Colors
      3. 11.7.3. Creating the Visualization Application
      4. 11.7.4. Creating the Application Plumbing
    8. 11.8. Windows Presentation Foundation
      1. 11.8.1. When GUIs Meet the Web
      2. 11.8.2. Drawing
      3. 11.8.3. Controls
      4. 11.8.4. Bitmaps and Images
      5. 11.8.5. Final Considerations
    9. 11.9. Summary
  17. 12. Working with Symbolic Representations
    1. 12.1. Symbolic Differentiation and Expression Rendering
      1. 12.1.1. Modeling Simple Algebraic Expressions
      2. 12.1.2. Implementing Local Simplifications
      3. 12.1.3. A Richer Language of Algebraic Expressions
      4. 12.1.4. Parsing Algebraic Expressions
      5. 12.1.5. Simplifying Algebraic Expressions
      6. 12.1.6. Symbolic Differentiation of Algebraic Expressions
      7. 12.1.7. Rendering Expressions
        1. 12.1.7.1. Converting to VisualExpr
        2. 12.1.7.2. Rendering
      8. 12.1.8. Building the User Interface
    2. 12.2. Verifying Circuits with Propositional Logic
      1. 12.2.1. Representing Propositional Logic
      2. 12.2.2. Evaluating Propositional Logic Naively
      3. 12.2.3. From Circuits to Propositional Logic
      4. 12.2.4. Checking Simple Properties of Circuits
      5. 12.2.5. Representing Propositional Formulae Efficiently Using BDDs
      6. 12.2.6. Circuit Verification with BDDs
    3. 12.3. Summary
  18. 13. Reactive, Asynchronous, and Parallel Programming
    1. 13.1. Introducing Some Terminology
    2. 13.2. Using and Designing Background Workers
      1. 13.2.1. Building a Simpler Iterative Worker
      2. 13.2.2. Raising Additional Events from Background Workers
      3. 13.2.3. Connecting a Background Worker to a GUI
    3. 13.3. Introducing Asynchronous and Parallel Computations
      1. 13.3.1. Fetching Multiple Web Pages in Parallel, Asynchronously
      2. 13.3.2. Understanding Thread Hopping
      3. 13.3.3. Under the Hood: What Are Asynchronous Computations?
      4. 13.3.4. Parallel File Processing Using Asynchronous Workflows
      5. 13.3.5. Running Asynchronous Computations
      6. 13.3.6. Common I/O Operations in Asynchronous Workflows
      7. 13.3.7. Under the Hood: Implementing Async.Parallel
      8. 13.3.8. Using async for CPU Parallelism with Fixed Tasks
      9. 13.3.9. Understanding Exceptions and Cancellation
    4. 13.4. Passing and Processing Messages
      1. 13.4.1. Introducing Message Processing
      2. 13.4.2. Creating Objects That React to Messages
      3. 13.4.3. Scanning Mailboxes for Relevant Messages
      4. 13.4.4. Example: Asynchronous Web Crawling
    5. 13.5. Using Shared-Memory Concurrency
      1. 13.5.1. Creating Threads Explicitly
      2. 13.5.2. Shared Memory, Race Conditions, and the .NET Memory Model
      3. 13.5.3. Using Locks to Avoid Race Conditions
      4. 13.5.4. Using ReaderWriterLock
      5. 13.5.5. Some Other Concurrency Primitives
    6. 13.6. Summary
  19. 14. Building Smart Web Applications
    1. 14.1. Serving Static Web Content
    2. 14.2. Serving Dynamic Web Content with ASP.NET
      1. 14.2.1. Understanding the Languages Used in ASP.NET
      2. 14.2.2. A Simple ASP.NET Web Application
      3. 14.2.3. Deploying and Running the Application
      4. 14.2.4. Using Code-Behind Files
    3. 14.3. Using ASP.NET Input Controls
    4. 14.4. Displaying Data from Databases
    5. 14.5. Going Further with ASP.NET
      1. 14.5.1. ASP.NET Directives
      2. 14.5.2. Server Controls
      3. 14.5.3. Debugging, Profiling, and Tracing
      4. 14.5.4. Understanding the ASP.NET Event Model
      5. 14.5.5. Maintaining the View State
      6. 14.5.6. Understanding the Provider Model
        1. 14.5.6.1. Configuring the Provider Database
      7. 14.5.7. Creating Custom ASP.NET Server Controls
    6. 14.6. Building Ajax Rich Client Applications
      1. 14.6.1. More on the WebSharper Platform
        1. 14.6.1.1. Getting Started with WebSharper
        2. 14.6.1.2. WebSharper Pagelets
        3. 14.6.1.3. Calling Server Code from the Client
    7. 14.7. WebSharper Formlets
      1. 14.7.1.
        1. 14.7.1.1. .NET Proxies and JavaScript Stubs
        2. 14.7.1.2. Automated Resource Tracking and Handling
        3. 14.7.1.3. Dependent Formlets and Flowlets
    8. 14.8. Using WSDL Web Services
      1. 14.8.1. Consuming Web Services
      2. 14.8.2. Calling Web Services Asynchronously
    9. 14.9. Summary
  20. 15. Working with Data
    1. 15.1. Querying In-Memory Data Structures
      1. 15.1.1. Select/Where/From Queries Using Aggregate Operators
      2. 15.1.2. Using Aggregate Operators in Queries
      3. 15.1.3. Accumulating Using Folding Operators
      4. 15.1.4. Expressing Some Queries Using Sequence Expressions
    2. 15.2. Using Databases to Manage Data
      1. 15.2.1. Choosing Your Database Engine
      2. 15.2.2. Understanding ADO.NET
      3. 15.2.3. Establishing Connections to a Database Engine
      4. 15.2.4. Creating a Database
      5. 15.2.5. Creating Tables and Inserting and Fetching Records
      6. 15.2.6. Using Untyped Datasets
      7. 15.2.7. Generating Typed Datasets Using xsd.exe
      8. 15.2.8. Using Stored Procedures
      9. 15.2.9. Using Data Grids
    3. 15.3. Working with Databases in Visual Studio
      1. 15.3.1. Creating a Database
      2. 15.3.2. Visual Data Modeling: Adding Relationships
    4. 15.4. Accessing Relational Data with Linq Queries
      1. 15.4.1. Generating the Object/Relational Mapping
      2. 15.4.2. Building the DataContext Instance
      3. 15.4.3. Using LINQ from F#
    5. 15.5. Working with XML as a Generic Data Format
      1. 15.5.1. Constructing XML via LINQ
      2. 15.5.2. Storing, Loading, and Traversing LinqToXml Documents
      3. 15.5.3. Querying XML
    6. 15.6. Summary
  21. 16. Lexing and Parsing
    1. 16.1. Processing Line-Based Input
      1. 16.1.1. On-Demand Reading of Files
      2. 16.1.2. Using Regular Expressions
    2. 16.2. Tokenizing with FsLex
      1. 16.2.1. The FsLex Input in More Detail
      2. 16.2.2. Generating a Simple Token Stream
      3. 16.2.3. Tracking Position Information Correctly
      4. 16.2.4. Handling Comments and Strings
    3. 16.3. Recursive-Descent Parsing
      1. 16.3.1. Limitations of Recursive-Descent Parsers
    4. 16.4. Parsing with FsYacc
      1. 16.4.1. The Lexer for Kitty
      2. 16.4.2. The Parser for Kitty
      3. 16.4.3. Parsing Lists
      4. 16.4.4. Resolving Conflicts, Operator Precedence, and Associativity
      5. 16.4.5. Putting It Together
    5. 16.5. Binary Parsing and Pickling Using Combinators
    6. 16.6. Summary
  22. 17. Interoperating with C and COM
    1. 17.1. Common Language Runtime
    2. 17.2. Memory Management at Runtime
    3. 17.3. COM Interoperability
    4. 17.4. Platform Invoke
      1. 17.4.1. Getting Started with PInvoke
      2. 17.4.2. Data Structures
      3. 17.4.3. Marshalling Strings
      4. 17.4.4. Function Pointers
      5. 17.4.5. PInvoke Memory Mapping
      6. 17.4.6. Wrapper Generation and Limits of PInvoke
    5. 17.5. Summary
  23. 18. Debugging and Testing F# Programs
    1. 18.1. Debugging F# Programs
      1. 18.1.1. Using Advanced Features of the Visual Studio Debugger
      2. 18.1.2. Instrumenting Your Program with the System.Diagnostics Namespace
      3. 18.1.3. Debugging Concurrent and Graphical Applications
    2. 18.2. Debugging and Testing with F# Interactive
      1. 18.2.1. Controlling F# Interactive
      2. 18.2.2. Some Common F# Interactive Directives
      3. 18.2.3. Understanding How F# Interactive Compiles Code
      4. 18.2.4. F# Interactive and Visual Studio
    3. 18.3. Unit Testing
    4. 18.4. Summary
  24. 19. Designing F# Libraries
    1. 19.1. Designing Vanilla .NET Libraries
    2. 19.2. Understanding Functional Design Methodology
      1. 19.2.1.
        1. 19.2.1.1.
          1. 19.2.1.1.1. Understanding Where Functional Programming Comes From
          2. 19.2.1.1.2. Understanding Functional Design Methodology
    3. 19.3. Applying the .NET Library Design Guidelines to F#
      1. 19.3.1.
        1. 19.3.1.1.
          1. 19.3.1.1.1. Recommendation: Use the .NET Naming and Capitalization Conventions Where Possible
          2. 19.3.1.1.2. Recommendation: Avoid Using Underscores in Names
          3. 19.3.1.1.3. Recommendation: Follow the .NET Guidelines for Exceptions
          4. 19.3.1.1.4. Recommendation: Consider Using Option Values for Return Types Instead of Raising Exceptions
          5. 19.3.1.1.5. Recommendation: Follow the .NET Guidelines for Value Types
          6. 19.3.1.1.6. Recommendation: Consider Using Explicit Signature Files for Your Framework
          7. 19.3.1.1.7. Recommendation: Consider Avoiding the Use of Implementation Inheritance for Extensibility
          8. 19.3.1.1.8. Recommendation: Use Properties and Methods for Attributes and Operations Essential to a Type
          9. 19.3.1.1.9. Recommendation: Avoid Revealing Concrete Data Representations Such as Records
          10. 19.3.1.1.10. Recommendation: Use Active Patterns to Hide the Implementations of Discriminated Unions
          11. 19.3.1.1.11. Recommendation: Use Object Interface Types Instead of Tuples or Records of Functions
          12. 19.3.1.1.12. Recommendation: Understand When Currying Is Useful in Functional Programming APIs
          13. 19.3.1.1.13. Recommendation: Use Tuples for Return Values, Arguments, and Intermediate Values
    4. 19.4. Some Recommended Coding Idioms
      1. 19.4.1.
        1. 19.4.1.1.
          1. 19.4.1.1.1. Recommendation: Use the Standard Operators
          2. 19.4.1.1.2. Recommendation: Place the Pipeline Operator |> at the Start of a Line
          3. 19.4.1.1.3. Recommendation: Format Object Expressions Using the member Syntax
    5. 19.5. Summary
  25. A. F# Brief Language Guide
    1. A.1. Comments and Attributes
    2. A.2. Basic Types and Literals
    3. A.3. Types
    4. A.4. Patterns and Matching
    5. A.5. Functions, Composition, and Pipelining
    6. A.6. Binding and Control Flow
    7. A.7. Exceptions
    8. A.8. Tuples, Arrays, Lists, and Collections
    9. A.9. Operators
    10. A.10. Type Definitions and Objects
    11. A.11. Namespaces and Modules
    12. A.12. Sequence Expressions and Workflows