Expert F# (Expert's Voice in .NET)
1590598504, 9781590598504
Expert F# is about practical programming in a beautiful language that puts the power and elegance of functional programm
110
84
6MB
English
Pages 636
[621]
Year 2007
Report DMCA / Copyright
DOWNLOAD PDF FILE
Table of contents :
Title Page
Copyright Page
Contents at a Glance
Table of Contents
Foreword
About the Authors
About the Technical Reviewer
Acknowledgments
CHAPTER 1 Introduction
The Genesis of F#
About This Book
Who This Book Is For
CHAPTER 2 Getting Started with F# and .NET
Creating Your First F# Program
Turning On the Lightweight Syntax Option
Documenting Code Using XMLDocs
Understanding Scope and Using “let”
Understanding Types
Calling Functions
Using Data Structures
Using Properties and the Dot-Notation
Using Tuples
Using Imperative Code
Using .NET Libraries from F#
Using open to Access Namespaces and Modules
Using new and Setting Properties
Fetching a Web Page
Summary
CHAPTER 3 Introducing Functional Programming
Getting Started with F# Arithmetic
Basic Literals
Arithmetic Operators
Bitwise Operations
Arithmetic Conversions
Arithmetic Comparisons
Overloaded Math Functions
Introducing Simple Strings
Working with String Literals and Primitives
Building Strings
Working with Lists and Options
Using F# Lists
Using F# Option Values
Using Option Values for Control
Working with Conditionals: && and ||
Defining Recursive Functions
Introducing Function Values
Using Anonymous Function Values
Computing with Aggregate Operators
Composing Functions with >>
Building Functions with Partial Application
Using Local Functions
Using Functions As Abstract Values
Iterating with Aggregate Operators
Abstracting Control with Functions
Using .NET Methods As First-Class Functions
Getting Started with Pattern Matching
Matching on Structured Values
Guarding Rules and Combining Patterns
Getting Started with Sequences
Using Range Expressions
Iterating a Sequence
Transforming Sequences with Aggregate Operators
Which Types Can Be Used As Sequences?
Using Lazy Sequences from External Sources
Using Sequence Expressions
Creating Sequence Expressions Using for
Enriching Sequence Expressions with Additional Clauses
Enriching Sequence Expressions to Specify Lists and Arrays
Exploring Some Simple Type Definitions
Defining Type Abbreviations
Defining Records
Handling Non-unique Record Field Names
Cloning Records
Defining Discriminated Unions
Using Discriminated Unions As Records
Defining Multiple Types Simultaneously
Summary
CHAPTER 4 Introducing Imperative Programming
Imperative Looping and Iterating
Simple for loops
Simple while loops
More Iteration Loops Over Sequences
Using Mutable Records
Mutable Reference Cells
Avoiding Aliasing
Hiding Mutable Data
Using Mutable Locals
Working with Arrays
Generating and Slicing Arrays
Two-Dimensional Arrays
Introducing the Imperative .NET Collections
Using Resizeable Arrays
Using Dictionaries
Using Dictionary’s TryGetValue
Using Dictionaries with Compound Keys
Some Other Mutable Data Structures
Exceptions and Controlling Them
Catching Exceptions
Using try . . . finally
Defining New Exception Types
Having an Effect: Basic I/O
Very Simple I/O: Reading and Writing Files
.NET I/O via Streams
Some Other I/O-Related Types
Using System.Console
Using printf and Friends
Generic Structural Formatting
Cleaning Up with IDisposable, use, and using
Working with null Values
Some Advice: Functional Programming with Side Effects
Consider Replacing Mutable Locals and Loops with Recursion
Separate Pure Computation from Side-Effecting Computations
Separating Mutable Data Structures
Not All Side Effects Are Equal
Avoid Combining Imperative Programming and Laziness
Summary
CHAPTER 5 Mastering Types and Generics
Understanding Generic Type Variables
Writing Generic Functions
Understanding Some Important Generic Functions
Generic Comparison
Generic Hashing
Generic Pretty-Printing
Generic Boxing and Unboxing
Generic Binary Serialization via the .NET Libraries
Making Things Generic
Generic Algorithms Through Explicit Arguments
Generic Algorithms Through Abstract Object Types
Understanding .NET Types
Reference Types and Value Types
Other Flavors of .NET Types
Understanding Subtyping
Casting Up Statically
Casting Down Dynamically
Performing Type Tests via Pattern Matching
Using Flexible # Types
Knowing When Upcasts Are Applied Automatically
Troubleshooting Type Inference Problems
Using a Visual Editing Environment
Using Type Annotations
Understanding the Value Restriction
Working Around the Value Restriction
Understanding Generic Overloaded Operators
Summary
CHAPTER 6 Working with Objects and Modules
Getting Started with Objects and Members
Using Constructed Classes
Adding Further Object Notation to Your Types
Working with Indexer Properties
Adding Overloaded Operators
Using Named and Optional Arguments
Using Optional Property Settings
Adding Method Overloading
Defining Object Types with Mutable State
Getting Started with Object Interface Types
Defining New Object Interface Types
Implementing Object Interface Types Using Object Expressions
Implementing Object Interface Types Using Concrete Types
Using Common Object Interface Types from the .NET Libraries
Understanding Hierarchies of Object Interface Types
More Techniques to Implement Objects
Combining Object Expressions and Function Parameters
Defining Partially Implemented Class Types
Using Partially Implemented Types via Delegation
Using Partially Implemented Types via Implementation Inheritance
Using Modules and Static Members
Extending Existing Types and Modules
Working with F# Objects and .NET Types
Structs
Delegates
Enums
Summary
CHAPTER 7 Encapsulating and Packaging Your Code
Hiding Things Away
Hiding Things with Local Definitions
Hiding Things with Accessibility Annotations
Using Namespaces and Modules
Putting Your Code in a Namespace
Using Files As Modules
Using Signature Types and Files
Using Explicit Signature Types and Signature Files
When Are Signature Types Checked?
Creating Assemblies, DLLs, and EXEs
Compiling EXEs
Compiling DLLs
Mixing Scripting and Compiled Code
Choosing Optimization Settings
Generating Documentation
Building Shared Libraries and the Using Global Assembly Cache
Using Static Linking
Packaging Applications
Packaging Different Kinds of Code
Using Data and Configuration Settings
Building Installers
Deploying Web Applications
Summary
CHAPTER 8 Mastering F#: Common Techniques
Equality, Hashing, and Comparison
Efficient Precomputation and Caching
Precomputation and Partial Application
Precomputation and Objects
Memoizing Computations
Lazy Values
Other Variations on Caching and Memoization
Cleaning Up Resources
Cleaning Up with use
Managing Resources with More Complex Lifetimes
Cleaning Up Internal Objects
Cleaning Up Unmanaged Objects
Cleaning Up in Sequence Expressions
Using using
Stack As a Resource: Tail Calls and Recursion
Tail Recursion and List Processing
Tail Recursion and Object-Oriented Programming
Tail Recursion and Processing Unbalanced Trees
Using Continuations to Avoid Stack Overflows
Another Example: Processing Syntax Trees
Events and Wiring
Events As First-Class Values
Creating and Publishing Events
Summary
CHAPTER 9 Introducing Language-Oriented Programming
Using XML As a Concrete Language Format
Using the System.Xml Namespace
From Concrete XML to Abstract Syntax
Working with Abstract Syntax Representations
Abstract Syntax Representations: “Less Is More”
Processing Abstract Syntax Representations
Transformational Traversals of Abstract Syntax Representations
Using On-Demand Computation with Abstract Syntax Trees
Caching Properties in Abstract Syntax Trees
Memoizing Construction of Syntax Tree Nodes
Introducing Active Patterns
Converting the Same Data to Many Views
Matching on .NET Object Types
Defining Partial and Parameterized Active Patterns
Hiding Abstract Syntax Implementations with Active Patterns
Embedded Computational Languages with Workflows
An Example: Success/Failure Workflows
Defining a Workflow Builder
Workflows and “Untamed” Side Effects
Example: Probabilistic Workflows
Combining Workflows and Resources
Recursive Workflow Expressions
Using F# Reflection
Reflecting on Types
Schema Compilation by Reflecting on Types
Using F# Quotations
Example: Using F# Quotations for Error Estimation
Resolving Top Definitions
Summary
CHAPTER 10 Using the F# and .NET Libraries
A High-Level Overview
Namespaces from the .NET Framework
Namespaces from the F# Libraries
Using the System Types
Using Regular Expressions and Formatting
Matching with System.Text.RegularExpressions
Formatting Strings Using .NET Formatting
Encoding and Decoding Unicode Strings
Encoding and Decoding Binary Data
Using Further F# and .NET Data Structures
System.Collections.Generic and Other .NET Collections
Introducing Microsoft.FSharp.Math
Using Matrices and Vectors
Using Operator Overloads on Matrices and Vectors
Supervising and Isolating Execution
Further Libraries for Reflective Techniques
Using General Types
Using Microsoft.FSharp.Reflection
Some Other .NET Types You May Encounter
Some Other .NET Libraries
Summary
CHAPTER 11 Working with Windows Forms and Controls
Writing “Hello, World!” in a Click
Understanding the Anatomy of a Graphical Application
Composing User Interfaces
Drawing Applications
Writing Your Own Controls
Developing a Custom Control
Anatomy of a Control
Displaying Samples from Sensors
Building the GraphControl: The Model
Building the GraphControl: Style Properties and Controller
Building the GraphControl: The View
Putting It Together
Creating a Mandelbrot Viewer
Computing Mandelbrot
Setting Colors
Creating the Visualization Application
Creating the Application Plumbing
Summary
CHAPTER 12 Working with Symbolic Representations
Symbolic Differentiation and Expression Rendering
Modeling Simple Algebraic Expressions
Implementing Local Simplifications
A Richer Language of Algebraic Expressions
Parsing Algebraic Expressions
Simplifying Algebraic Expressions
Symbolic Differentiation of Algebraic Expressions
Rendering Expressions
Building the User Interface
Verifying Circuits with Propositional Logic
Representing Propositional Logic
Evaluating Propositional Logic Naively
From Circuits to Propositional Logic
Checking Simple Properties of Circuits
Representing Propositional Formulae Efficiently Using BDDs
Circuit Verification with BDDs
Summary
CHAPTER 13 Reactive, Asynchronous, and Concurrent Programming
Introducing Some Terminology
Using and Designing Background Workers
Building a Simpler Iterative Worker
Raising Additional Events from Background Workers
Connecting a Background Worker to a GUI
Introducing Asynchronous Computations
Fetching Multiple Web Pages Asynchronously
Understanding Thread Hopping
Under the Hood: What Are Asynchronous Computations?
File Processing Using Asynchronous Workflows
Running Asynchronous Computations
Common I/O Operations in Asynchronous Workflows
Under the Hood: Implementing a Primitive Asynchronous Step
Under the Hood: Implementing Async.Parallel
Understanding Exceptions and Cancellation
Passing and Processing Messages
Introducing Message Processing
Creating Objects That React to Messages
Scanning Mailboxes for Relevant Messages
Example: Asynchronous Web Crawling
Using Shared-Memory Concurrency
Creating Threads Explicitly
Shared Memory, Race Conditions, and the .NET Memory Model
Using Locks to Avoid Race Conditions
Using ReaderWriterLock
Some Other Concurrency Primitives
Summary
CHAPTER 14 Building Web Applications
Serving Static Web Content
Serving Dynamic Web Content with ASP.NET
Understanding the Languages Used in ASP.NET
A Simple ASP.NET Web Application
Deploying and Running the Application
Using Code-Behind Files
Using ASP.NET Input Controls
Displaying Data from Databases
Going Further with ASP.NET
ASP.NET Directives
Server Controls
Debugging, Profiling, and Tracing
Understanding the ASP.NET Event Model
Maintaining the View State
Understanding the Provider Model
Creating Custom ASP.NET Server Controls
Building Ajax Rich Client Applications
More on F# Web Tools
Using Web Services
Consuming Web Services
Calling Web Services Asynchronously
Summary
CHAPTER 15 Working with Data
Querying In-Memory Data Structures
Select/Where/From Queries Using Aggregate Operators
Using Aggregate Operators in Queries
Accumulating Using “Folding” Operators
Expressing Some Queries Using Sequence Expressions
Using Databases to Manage Data
Choosing Your Database Engine
Understanding ADO.NET
Establishing Connections to a Database Engine
Creating a Database
Creating Tables, Inserting, and Fetching Records
Using Untyped Datasets
Generating Typed Datasets Using xsd.exe
Using Stored Procedures
Using Data Grids
Working with Databases in Visual Studio
Creating a Database
Visual Data Modeling: Adding Relationships
Accessing Relational Data with F# LinqToSql
Generating the Object/Relational Mapping
Building the DataContext Instance
Using LinqToSql from F#
Working with XML As a Generic Data Format
Constructing XML via LINQ
Storing, Loading, and Traversing LinqToXml Documents
Querying XML
Summary
CHAPTER 16 Lexing and Parsing
Processing Line-Based Input
On-Demand Reading of Files
Using Regular Expressions
Tokenizing with FsLex
The fslex Input in More Detail
Generating a Simple Token Stream
Tracking Position Information Correctly
Handling Comments and Strings
Recursive-Descent Parsing
Limitations of Recursive-Descent Parsers
Parsing with FsYacc
The Lexer for Kitty
The Parser for Kitty
Parsing Lists
Resolving Conflicts, Operator Precedence, and Associativity
Putting It Together
Binary Parsing and Pickling Using Combinators
Summary
CHAPTER 17 Interoperating with C and COM
Common Language Runtime
Memory Management at Run Time
COM Interoperability
Platform Invoke
Getting Started with PInvoke
Data Structures
Marshalling Strings
Function Pointers
PInvoke Memory Mapping
Wrapper Generation and Limits of PInvoke
Summary
CHAPTER 18 Debugging and Testing F# Programs
Debugging F# Programs
Using Advanced Features of the Visual Studio Debugger
Instrumenting Your Program with the System.Diagnostics Namespace
Debugging Concurrent and Graphical Applications
Debugging and Testing with F# Interactive
Controlling F# Interactive
Some Common F# Interactive Directives
Understanding How F# Interactive Compiles Code
Unit Testing
Summary
CHAPTER 19 Designing F# Libraries
Designing Vanilla .NET Libraries
Understanding Functional Design Methodology
Understanding Where Functional Programming Comes From
Understanding Functional Design Methodology
Applying the .NET Design Guidelines to F#
Some Recommended Coding Idioms
Summary
APPENDIX F# Brief Language Guide
Comments and Attributes
Basic Types and Literals
Types
Patterns and Matching
Functions, Composition, and Pipelining
Binding and Control Flow
Exceptions
Tuples, Arrays, Lists, and Collections
Operators
Type Definitions and Objects
Namespaces and Modules
Sequence Expressions and Workflows
Index