Inside F#

Brian's thoughts on F# and .NET

Archive for September, 2008

How does functional programming affect the structure of your code?

Posted by Brian on September 22, 2008

I recently listened to Ted and Amanda talking about F# on ".Net Rocks".  Ted mentioned something about how with functional programming, some object-oriented (OO) design patterns (like ‘Command’) just disappear because you don’t need them when you have first-class functions.  That’s a topic near and dear to my heart; back in school I co-authored a paper about this (see "FC++: Functional Tools for OO Tasks" on the FC++ page).  It got me thinking about how "code comes out different" in F# versus C#, which in turn got me thinking about a conversation I had with Luke a couple months ago, where Luke argued convincingly that functional programming (FP) differentiates itself most obviously when programming "in the small".  So I was thinking about all this stuff and it inspired me to write this blog entry where I try to get down all my thoughts on this.

Defining some terms

I want to discuss how functional programming techniques affect the structure of your code at three different levels, which today I will call "in the large", "in the medium", and "in the small".  By "in the large" I mean a high level that affects and crosscuts multiple classes and functions throughout a program.  By "in the medium" I mean the level of a single API or group of related APIs (e.g. a class, an interface, or a couple tightly-coupled classes or functions).  By "in the small" I mean the level of individual method/function bodies – the actual code that "does stuff" as opposed to the structural/scaffolding/modularizing organization of that code.  Functional programming in general (and F# in particular) affect the structure of code at all of these levels to various degrees, so I’ll talk about each level in turn.

A note…

Though I will cite a number of examples, I’m not showing any code in this blog entry.  A catalog of "this is some code in C#, here’s the somehow-corresponding code in F#" could be interesting/useful, but is not my purpose today.  I just want to talk about how code differs, and try to categorize and describe the essential differences I see, without getting too distracted by the details of any specific examples.  So I’ll try to use examples "just enough" to get you thinking along the lines I’m thinking; you will need to follow hyperlinks in order to learn more about some examples I mention that you may not be familiar with.

In the large

I think that functional programming has the least influence on the structure of programs in the large, simply because when doing architecture or high-level design, you’re "too high up" for specific implementation techniques to matter too much.  At this level, the strongest influence is the problem-domain itself; a good architecture decomposes a system into a set of modules and interactions that solve the problem under its key constraints (which may include performance/throughput of the system, distribution, reliability, etc.).  This is true regardless of whether you’re wearing an FP hat or an OO hat; these styles can help shape your thinking about the problem, but don’t necessarily affect the final structure of the solution.

This is not to say that this level is completely free of FP influence.  Though a now a quarter-century old, the oft-cited Why Functional Programming Matters has a great example here: section 5 talks about how laziness is essential to the architecture of a particular performant program and crosscuts whole API.  The idea of using on-demand computations to decouple producers of data from their consumers is definitely useful, but it can be realized in myriad ways (coroutines, pipes, streams, IEnumerable<T>, …), so I’m not sure that FP can stake a complete claim here.  But adding FP strategies to your mental bag of tricks can help diversify how you think about problems at a high level.

It bears mention that F# is a great tool for realizing a wide range of system architectures: whether your problem lends itself to service-orientation with stateless servers passing messages, or to high-performance computing that must take advantage of multiple cores, or to traditional OO modeling, decomposition, and encapsulation suitable to many desktop applications, the features in F# make for a natural implementation fit.  By blending FP and OO, F# has the long reach to straightforwardly implement a wide range of designs, and its deep integration with .Net provides a very rich platform of libraries to build atop.

In the medium

Recall that by "in the medium", I mean program structure at the level of classes, interfaces, and individual method APIs.  The good news here is that for a great many cases, OO design is just right.  OO has dominated for the past couple of decades, and with good reason: decomposing a domain into classes (nouns) and methods (verbs and predicates) associated with those classes is an outstanding way to decompose a problem domain and structure a solution in source code. 

However there are some cases where the OO strategy of "classes/nouns first" creates inferior solutions.  The Command design pattern is a good example of such a case.  The purely object-oriented solution realizes this pattern with a Command class or interface with a single method called "Execute".  This is clearly just a function dressed up in "class" clothes.  Whereas an OO solution requires lots of interacting named entities (a Command class or interface, an Execute method, concrete subtypes that fill in the method implementation and potentially capture extra state), a solution in a language with first-class functions requires none of these.  A function type (e.g. "int->unit") is a sufficient description of the interface, and any named function or lambda with the right signature can be used as a concrete implementation.  Closures make it trivial to capture any extra state that is needed.  In short, all of the "structure" described by this pattern is unnecessary; first-class functions are a direct fit for the domains that "Command" tries to solve, and classes and interfaces are unnecessary.  Similar observations can be made for a number of other design patterns, including Observer and Strategy.

There are other places where functional programming affects the structure of your code "in the medium".  The Visitor pattern is another design pattern that can be handled differently using functional techniques; I discussed folds and catamorphisms at length in a prior blog entry.  The availability of F# discriminated union (DU) types create opportunities to structure certain kinds of code more simply; a fixed class hierarchy can often be represented with a single DU type; I showed an example of this in a prior blog entry on DUs.

In C# (especially before C# 3.0), there were a number of situations where you would create named delegate types and/or classes (like FooEventArgs) to handle "events" or other customizations to the behavior of classes in a library.  Again, these are best handled with function types (and the lambdas and "Func" delegates in C# 3.0 are progress towards reducing the extra needless friction that comes from some such APIs).  Finally, sometimes in OO languages you are forced to package functions inside classes, when in fact the functions are happy to float free at the top level.  Consider mathematical functions like "sqrt" or "pow" – whereas an OO languages typically forces you to stick these in a class and always qualify calls (e.g. "Math.Pow()"), in a language like F#, you can define functions like these in a open-able module or just at the top-level of your program, and access these by their short names (e.g. just "pow") or by defining operators (like "**"). 

In the small

By "in the small", I mean code at the level of individual method and function bodies.  It’s here where functional programming in general, and using F# in particular, change the structure of your code most obviously.  When "variables" are immutable by default, and you usually don’t need type annotations, and control is often expressed via expressions (if-then-else, pattern matching) and recursion, and you can define local/nested functions as easily as defining local variables… your code ends up looking pretty different at this level compared to typical code you’d see in other languages.  The ability to author higher-order functions (like maps and folds) along with the ease of writing lambdas often means that code which you might typically write with a loop or recursion can be written with just a single call to a higher-order function; see this Joel on Software article for details on how and why this is so important and useful.

Examples here abound; just the other day I saw this blog post (check it out), which is a good example of the difference in styles "in the small".  Sure, you can write the "List.min_by" function in C# and call it with a lambda, or use a LINQ query, but either of those C# solutions just highlights the FP style of programming.  The point is that FP features like higher-order functions and currying are the enablers of this style of programming, and they can dramatically change and simplify the code you write in the small, down at the level of individual functions/methods or portions of method/algorithm implementations.

Furthermore, the "in the small" level is arguably the most important level of code, since it’s the only level that has to be there.  There are plenty of times when you’re doing exploratory programming, or scripting, or writing glue code, when you simply won’t need to utilize any features for structuring/organizing programs "in the medium/large".  Here, F# features, such as the ability to program directly at the top-level, type inference, and higher-order functions are huge wins that enable you to create shorter, simpler code.  And most of these advantages still apply in larger programs, inside the bodies of individual functions and methods.  The advantages of FP "in the small" accrue to programs of all sizes.

Summing up

I think that functional programming affects the structure on a number of levels.  FP’s influence is weakest "in the large"; at this level, the structure of the problem itself dominates, and FP’s influence comes mostly shaping one’s thinking about architectures or high-level designs.  FP’s influence is more apparent "in the medium", where the design of some APIs can be simplified – sometimes dramatically in a few specific domains that are especially well-suited to FP.   FP differentiates itself the most "in the small" – this is the level where computations happen, this is level where the majority of code (for programs of all sizes) is written, this is where most FP-specific constructs take hold.

Coda

I think it’s difficult to write convincing prose about programming without showing any code, but in this entry I linked to a number of examples that illustrated my points and matched my personal experience, in the hopes of causing you to recall similar examples from your own experiences programming in FP versus OO style.  I expect that there are many other good examples out on the web that illustrate "how the code codes out differently" when you have your FP hat on… for those of you who don’t yet have much of your own FP experience to draw on, I’d encourage you to seek out more examples to see more of the concrete differences (and consider posting links to the best ones in the comments section of this blog entry, to make them easy for other readers to find).

Posted in Uncategorized | 2 Comments »

Reusing F# code libraries with Visual Studio

Posted by Brian on September 16, 2008

Continuing with the theme of a prior blog entry, I want to discuss two practical ways to reuse code across multiple applications.

Suppose I have some general-purpose utility code that I find to be reusable in a number of programs that I’m authoring.  Rather than cut-and-pasting the code into various programs (which has all kinds of maintenance issues – if you are cut-and-pasting code within your projects, you are probably doing something wrong!), there are two common techniques in Visual Studio for reusing code.

Code library projects, and solutions with multiple projects

Perhaps the commonest way to reuse code is to put it in a library.  An F# library project (File>New Project):

FSLibProj

is a project that compiles down to a DLL (as you can see in the Output Window below):

FSLibProjBuild

So now I have a library that I can reference to access this functionality.  I can reference this functionality from a different program by creating a solution with multiple projects.  First, I create a new project for my app:

FSAppProj

Next, I add an existing project to the solution:

AddExistingProject

and select the library project that I just created.  Now my solution contains two projects:

TwoProjSoln

Note that the project is "by reference" – Visual Studio hasn’t copied anything, the source code and the project file still have their same old location on disk, we are just referencing them from a different solution.

To make the library accessible to my application, I add a project reference by doing an ‘Add Reference’ on the app:

AddProjRef1

and selecting the ‘Projects’ tab to add a reference to the Library1 project:

AddProjRef2

I see the new reference appear in the solution explorer:

P2PRefVisible

And now I can write code in my app that references code from the library, has working Intellisense, etc:

RefLibFromApp

That’s a project-to-project reference, and it’s a common way to reuse code – I can reference Library1 from whatever other applications I write, in whatever language (e.g. I could just as well have referenced the F# library project from a new C# console application project) using this technique.

Including individual source code files by reference using ‘Add as Link’

Another way to reuse source code is to recompile the same code into different applications.  I covered the mechanics of how to achieve this (‘Add as Link’) in a prior blog entry, check it out.  I can create a new F# Application project in a new solution, and ‘Add as Link’ a source code file from the Library1 project, resulting in:

UsingLinkedCode

The little ‘arrow’ sub-glyph on the ‘Module1.fs’ icon shows that this is a linked file.  As a linked file, no copying has been done – the source file still just lives in a single place on disk (under the Library1 folder), but that source file is going to get compiled into this project.  As a result, again I can reference that code from other code in the current application:

RefLibFromApp

This ‘code reuse’ strategy is probably used less often than project-to-project references.  It has a number of disadvantages (functionality often cannot simply be ‘lifted out’ of a project on a per-file basis – often the code in the file references other files in the project, or has dependencies on references (‘add reference’) from the original project), but does have some potential advantages as well (the code is re-compiled directly into the referencing project, so with this strategy I just have a .EXE that contains everything, rather than a .EXE and a .DLL that the .EXE references). 

So I’ve demonstrated a couple ways to reuse code in Visual Studio without resorting to cut-and-paste.  Nothing too earth-shattering here, but I often find that people are blissfully ignorant of lots of useful Visual Studio features (I count myself in this group – until I started working on the F# Visual Studio integration, there were tons of VS features I knew nothing about, despite using VS for years), so I hope this helps demo the mechanics of some features and suggests how you will use them in practice.

Next time

Whereas recent blog entries have discussed some pragmatics regarding the physical aspects and tooling aspects of structuring your code (e.g. files and folders on disk, as well as VS projects and solutions), next time I hope to discuss how F# and functional programming affect the structure of actual source code that you write, compared to writing code with OO languages.

Posted in Uncategorized | 1 Comment »

Quick aside: F# CTP compiler flags (command-line options)

Posted by Brian on September 6, 2008

One thing that changed in the CTP release of F# is the names of various compiler options.  Below is a brief table that shows the old names and new names of many command-line flags. 

Old flag New flag
-i  /  –generate-interface-file –sig
-doc –doc
-Ooff –optimize-
-O0, 01, etc –optimize
–warn –warnaserror[+|-] <int list>
–all-warnings-as-errors –warnaserror
–warn-as-error <int> –warnaserror <int>
–utf8-output –utf8output
–clr-root –cliroot
–target-exe –target exe
–target-winexe –target winexe
–target-dll –target library
–target-module –target module
–static-link –staticlink
–public-keyfile –keyfile <file> –delaysign
–link-resource –linkresource
–base-address –baseaddress
–generate-debug-file / –no-debug-file –debug / –debug –pdbonly
–generate-html –generatehtml
–html-output-directory –htmloutputdir
–html-css –htmlcss
–html-namespace-file –htmlnamespacefile
–html-namespace-file-append –htmlnamespacefileappend
–no-framework –noframework
–all-tailcalls –optimize
–no-tailcalls –optimize- notailcalls

As with a number of other changes in the CTP, these changes were to make things more regular and consistent with other Visual Studio languages.  The compiler help itself also now displays in a format similar to that of the C# and VB compilers (csc.exe and vbc.exe); here’s the output of "fsc.exe /?":

Microsoft F# Compiler, (c) Microsoft Corporation, All Rights Reserved
F# Version 1.9.6.2, compiling for .NET Framework Version v2.0.50727

                – OUTPUT FILES –
–out <string>                Name of the output file (Short form: -o)
–target exe <string>         Build an executable with a console
–target winexe <string>      Build an executable without a stdin/stdout/stderr
–target library <string>     Build a library (Short form: -a)
–target module <string>      Build a module that can be added to another
                              assembly
–delaysign[+|-]              Delay-sign the assembly using only the public
                              portion of the strong name key
–doc <string>                Write the xmldoc of the assembly to the given
                              file.
–keyfile <string>            Specify a strong name key file
–platform <string>           Limit which platforms this code can run on:
                              x86, Itanium, x64 or anycpu. The default is
                              anycpu
–nooptimizationdata          Only include optimization information essential
                              for implementing inlined constructs. Inhibits
                              cross-module inlining but improves binary
                              compatibility
–nointerfacedata             Don’t add a resource to the generated assembly
                              containing F#-specific metadata
–sig <string>                Print the inferred interface of the assembly
                              to a file

                – INPUT FILES –
–reference <string>          Reference an F# or .NET assembly (Short form: -r)

                – RESOURCES –
–win32res <string>           Specify a Win32 resource file (.res)
–resource <string>           Embed the specified managed resource
–linkresource <string>       Link the specified resource to this assembly
                              where the resinfo format is
                                  <file>[,<string name>[,public|private]]

                – CODE GENERATION –
–debug[+|-]                  Emit debug information (Short form: -g)
–debug <string>              Specify debugging type: full, pdbonly. default,
                              (‘full’ is the default and enables attaching a
                              debugger to a running program)
–optimize[+|-]               Enable optimizations (Short form: -O)
–optimize[+|-] <string list> Control specific optimizations (Short form: -O)
                              The following optimizations may be selectively
                              enabled or disabled: nojitoptimize,
                              nojittracking, nolocaloptimize, nocrossoptimize,
                              notailcalls

                – ERRORS AND WARNINGS –
–warnaserror[+|-]            Report all warnings as errors
–warnaserror[+|-] <int list> Report specific warnings as errors
–warn <int>                  Set a warning level (0-4)
–nowarn <string list>        Disable specific warning messages

                – LANGUAGE –
–checked[+|-]                Generate overflow checks
–define <string>             Define conditional compilation symbols (Short
                              form: -d)
–mlcompatibility             Ignore OCaml-compatibility warnings.

                – HTML –
–generatehtml                Generate HTML documentation
–htmloutputdir <string>      Output directory for HTML documentation
–htmlcss <string>            Set the name of the Cascading Style Sheet
–htmlnamespacefile <string>  Set the name of the master namespaces.html
                              file assumed to be in the output directory
–htmlnamespacefileappend     Append to the master namespace file when
                              generating HTML documentation

                – MISCELLANEOUS –
–nologo                      Don’t show the splash text on startup
–help                        Display this usage message (Short form: -?)

                – ADVANCED –
–baseaddress <string>        Base address for the library to be built
–codepage <int>              Specify the codepage used to read source files
–utf8output                  Output compiler messages in UTF-8 encoding
–fullpaths                   Compiler generates fully qualified paths
–cliroot <string>            Use to override where the compiler looks for
                              mscorlib.dll and framework components
–cliversion <string>         Version of the framework to target (for
                              example, 2.0, 3.0 or 3.5). The default is 2.0
–noframework                 Do not reference the .NET Framework assemblies
                              by default
–times                       Display timing profiles for compilation
–standalone                  Statically link the F# library and all
                              referenced DLLs that depend on it into the
                              assembly being generated.
–staticlink <string>         Statically link the given assembly and all
                              referenced DLLs that depend on this assembly.
                              Use an assembly name e.g. mylib, not a DLL name
–pdb <string>                Name the output debug file
–lib <string list>           Specify a directory for the include path (Short
                              form: -I)

By the way, you might notice the version number is 1.9.6.2 – yesterday we released a minor update to the CTP with a few high priority fixes.  Thanks again to everyone who has given great feedback on the CTP release!

Posted in Uncategorized | Leave a Comment »

Using multiple F# source files, and a useful debugging technique

Posted by Brian on September 6, 2008

In some prior blog entries, I highlighted some features of the project system that enable you to use and organize multiple files as well as multiple projects within your solution.  In my next blog entries, I want to continue showing you some more features along these lines, but now with more of an eye towards pragmatics, including some advice on how to choose among different ways to organize your code.

Multiple files in F#, and the implicit module

Suppose I have a tiny F# source code file like this:

let AnyAsString x = 
    sprintf "%A" x

This is a surprisingly handy function (we’ll see why shortly) – it takes any F# value and returns a reasonably-formatted human-readable string version of that value.  (You can read more about the various F# printf functions and specifiers here.)  Suppose I want to call this function from a different source file further down in my project – how do I do it?  Just trying to call it directly doesn’t work; for example if I write

    AnyAsString [1;2;3]

in a different file, I get

The value or constructor ‘AnyAsString’ is not defined.

The reason is that, if you write code at the "top level" of a file without using a "namespace" or a "module" (and I’ll talk more about when/how to use namespaces and modules to organize your code in a future blog entry), then F# implicitly puts your code in a module whose name is the source code filename.  So if my AnyAsString function were defined in "Debug.fs", then to call it from another file I need to write

    Debug.AnyAsString [1;2;3]

Put another way, the original code I showed for that file is equivalent to

// Debug.fs
module Debug

let AnyAsString x = 
    sprintf "%A" x

only this version is less subtle (by virtue of being explicit about the module).

Debugging F# code – breakpoints, locals, and the immediate window

Consider this silly little program which I’ve defined in Program.fs:

// Program.fs
// demonstrate calling a function from another file
printfn "%s" (Debug.AnyAsString [1;2;3])  

type Suit =
    | Club
    | Diamond
    | Heart
    | Spade

type Rank =
    | Ace | Deuce | Trey | Four | Five 
    | Six | Seven | Eight | Nine | Ten
    | Jack | Queen | King
    
type Card = 
    | Card of Suit * Rank

let bullet = Card(Spade,Ace)
printfn "%A" bullet

let Guess(yourCard : Card) =
    if yourCard = bullet then
        printfn "I knew it, everyone always picks the ace of spades!"
    else
        printfn "Not the spade ace?  You are very clever."

let myCard = Card(Diamond,Trey)
printfn "(mine is %A)" myCard
Guess(myCard)

The program itself is not very interesting or meaningful, but that’s good, because I want to focus on the tooling.  Suppose I put a breakpoint on the first line of the Guess function (by clicking in the margin or pressing F9):

CardBreakpoint

and run the program inside the debugger.  When I hit the breakpoint, in the Locals window (Debug > Windows > Locals), you’ll see the "yourCard" parameter (near the bottom):

CardLocals1

but the value of the card (3 of diamonds) is not apparent from this view.  (EDIT, Jan 2010: note that the default debugger experience here has greatly improved, see this entry.)  Even expanding the "+" entry for this local variable will not help much.  However, thanks to our Debug.AnyAsString function, we can easily see the value using the Immediate window (Debug > Windows > Immediate).  In the Immediate window, I can type "Debug.AnyAsString(yourCard)" and it shows me the value (near the bottom right):

CardImmediate

There are a number of improvements to the out-of-the-box F# debugging experience that we hope to make in future releases, but in the meantime, this is one alternative technique you can use to inspect the value of local variables inside the debugger.

AnyAsString is an example of a "utility function" that you may find useful in many of your F# programs.  Next time I’ll discuss various ways to organize and reuse small libraries of utility code across multiple projects and solutions.

Posted in Uncategorized | 1 Comment »