Author: Dave Fancher

Dave Fancher is a Lead Software Engineer at Vibenomics in Fishers, Indiana, a Microsoft MVP Visual Studio & Development Technologies, author of The Book of F# from No Starch Press, and Pluralsight author. He has been building software with the .NET Framework since version 1.1. Dave is active within the Indiana software development community as a member of IndySA, a speaker at user groups throughout the state, and a two-time contributor to Indy GiveCamp. When not writing code he enjoys spending time with his family, watching movies, photography, and gaming on on his Xbox One.

Building F# Type Providers on Pluralsight!

I was wrapping up The Book of F# and discussing the foreword with Bryan Hunter, he asked if I’d like to be connected to some of the folks at Pluralsight to discuss the possibility of an F# course. I agreed and a few days later I was on the phone brainstorming course ideas with them.

Of everything we discussed I was really only excited about a few topics enough to think I could put together a full course for them. Naturally the ones I was most excited about were already spoken for so I started trying to think of some other ideas. At that point I sort of fizzled out from seemingly endless distractions like changing jobs, speaking at a variety of events, and so on. Over the course of a few months I’d pretty much forgotten about the discussions. Fortunately for me, Pluralsight hadn’t forgotten and my acquisitions editor emailed me to see what happened.

We soon started talking again and one of the ideas I was originally excited about was now available and I’d been working on a related conference talk so I had the start of an outline. After a few iterations I was ready to start recording my Building F# Type Providers course.

Fast forward to earlier this week when I noticed some blog traffic from an unexpected source – my Pluralsight author profile page! I quickly discovered that my course was live!


If you’re wanting to learn more about one of F#’s most interesting features, I invite you to watch the course where I show a few existing type providers in action before walking through creating a simple type provider for reading the ID3 tag from an MP3 file using the Type Provider Starter Pack.


Functional C#: Fluent Interfaces and Functional Method Chaining

This is adapted from a talk I’ve been refining a bit. I’m pretty happy with it overall but please let me know what you think in the comments.

Update: I went to correct a minor issue in a code sample and WordPress messed up the code formatting. Even after reverting to the previous version I still found issues with escaped quotes and casing changes on some generic type definitions. I’ve tried to fix the problems but I may have missed a few spots. I apologize for any odd formatting issues.

I’ve been developing software professionally for 15 years or so. Like many of today’s enterprise developers much of my career has been spent with object-oriented languages but when I discovered functional programming a few years ago it changed the way I think about code at the most fundamental levels. As such I no longer think about problems in terms of object hierarchies, encapsulation, or and associated behavior. Instead I think in terms of independent functions and the data upon which they operate in order to produce the desired result. (more…)

FileZilla Server and Windows Azure

I was setting up a new virtual machine in Windows Azure today and wanted to host an FTP server. Having spent most of my career isolated inside corporate environments and largely disconnected from server administration this was fairly new ground for me.

I knew going into it that I was going to have to tweak some firewall rules and whatnot but establishing communication was a bit more involved than I initially expected.

The FTP solution I selected was FileZilla Server. It’s a rather robust solution that provides the security I wanted with minimal configuration. Getting the server components installed was effortless as was creating the security groups and users. Once I had everything configured the way I wanted I created the rules to allow traffic to hit ports 21 and 990 on the server through the Windows Firewall with Advanced Security control panel.

For my first test I simply tried to FTP to localhost on the server itself. Both accounts I’d configured worked perfectly. Then, to test the firewall rules I tried to connect from my development workstation but was unable to connect.

After scratching my head for a bit I remembered seeing endpoint configuration in the Azure portal. I added two endpoints, one for port 25 and one for port 990 and was then able to connect but the FTP client kept failing to retrieve a directory list. The log showed that the client was attempting to use passive mode which requires additional ports. I quickly found the passive mode settings in the FileZilla server options. From there I was able to specify a custom range which I could then allow to pass through the firewall. The other thing I needed to change was the IPv4 specific setting to force the server to use the server’s public virtual IP address as listed on the VM’s dashboard in the Azure Portal.

FileZilla Passive Mode Settings

FileZilla Passive Mode Settings

Just as before, simply adding the firewall rules wasn’t enough to allow communication. I had to add the passive mode ports as endpoints as well. I initially found this to be more than a bit tedious but fortunately the Add-AzureEndpoint PowerShell cmdlet eased some of the pain.

Azure FTP Endpoints

Azure FTP Endpoints

Once all the rules and endpoints were in place I was able to successfully connect from my development workstation to the server and get directory listings.


Receiving Webhooks With IIS Express

One of the projects I’m currently working on is using a service that reports various events back to our system via webhooks. Since the features I’m working on aren’t ready for deployment yet I was looking for a decent way to test the integration in my development environment to ensure that I’m not only receiving the correct data but also that I’m handling it properly.

The service’s documentation recommended pointing the webhooks to another service such as RequestBin to inspect the contents. I did mess around with that approach for a bit and although I was certainly able to see the requests in the RequestBin log and push them on to the application with fiddler, it really didn’t seem like an adequate solution and I was tired so I went to bed.

It turns out that sleeping on it was exactly what I needed. Sometime overnight I subconsciously worked out a better solution; I could open up IIS Express to handle remote connections and configure NAT on my router to forward requests for that port directly to the IIS Express instance. It turns out that getting all this working was actually quite simple.

Allowing Remote Connections

Allowing remote connections to IIS Express requires a little work but it’s pretty straight-forward and is outlined in this stackoverflow post. In short we need to:

  1. Create an additional IP binding for the IIS Express site to allow traffic from all hosts.
  2. Allow connections to the port from anyone
  3. Create a firewall rule to allow traffic to the port on the development machine

Creating an IIS Express Binding

IIS Express sites are managed per-user. To create the IIS Express binding we simply need to create a new entry for the site in the configuration file located at %userprofile%\documents\iisexpress\config\applicationhost.config. In the file locate the site then duplicate the binding, changing the allowed host to *. For example, if the current binding is:

I’ve used port 99999 in these examples for demonstration purposes only. You’ll want to use the port listed in your configuration file.

<binding protocol="http" bindingInformation="*:99999:localhost" />

You’d create a copy and change localhost to * such that it reads like this:

<binding protocol="http" bindingInformation="*:99999:*" />

It’s very important that you leave the original binding in place. Yes, it is redundant to have a binding for all hosts and another for only localhost but Visual Studio uses the localhost binding to initialize IIS Express. If that binding isn’t present Visual Studio will create a duplicate site entry and you’ll likely start seeing errors such as the one pictured below.

URL Binding Failure

URL Binding Failure

Setting Security on the Port

Once you’ve created the IIS Express binding you need to allow connections to the port. This is done by executing target=”_blank”>netsh to add a URL reservation for the new binding. In this case we’ll be using netsh http add urlacl to register the address we bound to the IIS Express site and granting permission to everyone.

netsh http add urlacl url=http://*:99999/ user=everyone

Note that “everyone” refers to the Everyone group in Windows. If you’re using a non-English version you’ll need to change that to the localized name for your language.

Creating a Firewall Rule

The final step is allowing traffic to that port through the local firewall. Accomplishing this varies according to which firewall solution you’re using. For Windows firewall you can control this through the control panel or by executing the following netsh command which changes some advanced firewall configuration settings.

netsh advfirewall firewall add rule name=”IISExpressWeb” dir=in protocol=tcp localport=99999 profile=private remoteip=any action=allow

Configuring NAT

Configuring NAT is not something I can really help with in this article because each environment will have its own instructions and restrictions. For me and my home office network it was easy because I simply had to add a custom application that referenced the configured port and host machine in my router’s firewall configuration.

Alternatively, I could have configured the IP Passthrough to route traffic to the development machine but I deemed this to be too much exposure to the outside world and left it with NAT.

Accepting Webhooks

Once I’d configured everything on my network to accept the webhook traffic I went to the external application’s dashboard and registered my computer as a webhook recipient using the WLAN IP address I obtained from my router’s status page and the port I bound to IIS Express for the application. I then set a breakpoint in the webhook processing logic, ran the application, made a change in the remote system to initiate sending an event, then watched in amazement as my breakpoint was hit and the watch window showed data received from the remote service.

Mission accomplished.

Setting up a Home Recording Studio

I’ve been preparing to do some audio recording in my home but getting started has not been without its share of challenges. Having a rambunctious 5 year-old certainly limits the times when I can record without interruption but that’s certainly manageable. The biggest problem I’ve been facing is the house itself.

My house sucks for recording. It is an echo chamber; a cavernous open floor plan of approximately 2000 square feet where only its three bedrooms are isolated from the rest of the house. To say that the house was not designed with audio recording in mind is a fact akin to stating that the sky is blue or that water is wet. The front door opens into a foyer which is connected to my daughter’s play room and the living room. In addition to the walkway, the play room has a giant window that connects it directly to the living room. The living room is an open space that connects to the dining area and kitchen and flows upward into the loft on the second floor. The only effective spaces  for recording in the house are the three bedrooms upstairs which are connected to a central hallway. Given that two of the bedrooms are allocated for use as actual bedrooms and the third serves dual purpose as a guest room and my wife’s craft room, that leaves me the worst possible place in the house to record: the loft.

My wife and I have discussed some renovations that would isolate the loft, giving me a man cave of sorts. Isolating the loft would certainly help with many of the problems I’m trying to solve but unfortunately it’s not in the budget right now. I needed to seek an alternate solution that didn’t involve hiding in the master closet.

I started by purchasing some studio foam panels from Auralex. Not only were their panels highly recommended but I’d recently learned that Auralex is based just a few miles from my house so I’d be supporting a local business. I went with the D36-DST Roominator kit which includes 36 12 inch by 12 inch panels. I attached the panels to the walls immediately around my desk and the ceiling directly above my chair.

The Auralex panels seem to do a great job absorbing the sound as long as I was right next to them. I’ve definitely noticed their effect but given the house’s horrible acoustics they weren’t enough to eliminate the echo. I still needed to isolate the loft somehow.

My always creative wife suggested somehow mounting some curtains across the room. We toyed with a few ideas but wanted to keep the project as inexpensive as possible. Given that the loft is approximately 15 feet across and the ceiling is approximately 9 feet high we were going to need quite a bit of fabric. We also needed to determine how to hang the fabric,. We first thought about a tension rod or mounting a curtain rod from the ceiling but then she found this post on Apartment Therapy which seemed like it might do the trick.

Because I wanted the curtains to help reduce the echo we decided to get some velvet from Jo-Ann’s instead of the lighter sheets mentioned in the Apartment Therapy article. Beyond that, we took pretty much the same approach, adjusting a bit for strength mostly to alleviate my fear that the velvet’s weight would pull one (or both) of the eye hooks out of the wall.

Curtain Materials:

The project cost around $250.00 in materials between the Auralex panels and the curtain supplies. Excluded from that total are the cable cutters I had to purchase because I didn’t have anything capable of cutting the wire rope, and the tape we used to try hemming the velvet (epic failure on that one).

Over the course of the project I learned a few things.

  1. Wire rope is really hard to cut.
  2. Cheap velvet doesn’t help as much as we’d hoped.
  3. I should never work with fabric. We tried using some fabric tape to hem the velvet but that was a colossal failure. My wife ended up hand-sewing the velvet after the cloth got stuck in the sewing machine.
  4. I should get some real curtains to cover the window. It currently has wood blinds but I still get a lot of noise from the road.
  5. I should probably get a few more Auralex panels.

Since completing the project I’ve recorded and submitted a production sample video and it seems to have passed all of the initial quality gates so overall I’m quite happy with the result. I do still notice some echo on the recording but it’s markedly better than it was before hanging the panels and curtains. Even sitting here, writing this with the curtains closed I notice an improvement in the acoustics. I do still need to remember to shut off the furnace before recording (and turn it back on when I’m done – oops) but that’s a minor inconvenience compared to being sequestered to a closet.

I realize this configuration is far from ideal so if you have any suggestions for how I could improve it I’d love to hear them!

Jumping on the Band(wagon)

A few months ago, my wife and I considered jumping into the quantified self scene by purchasing a pair of Fitbit devices. My biggest problem was that I didn’t really care that much about tracking my activity. Sure, being able to monitor my sleep patterns and that type of thing would be nice to know but if I was going to wear something all the time, I wanted it to do more – I wanted it to tie in to my calendar and other notifications. That’s where the Microsoft Band comes in.

My Microsoft BandThe Band was released in late October without much fanfare. I hadn’t even heard of it until it was released and I saw some buzz on Twitter. Even then I had no idea what it was and assumed it was a game or something. A bit later I decided to actually look it up and discovered that it was a wearable device that met my expectations perfectly. I wanted one.

Despite there being a Microsoft Store just a few miles from my house I figured that since I was about to leave for the MVP Summit I’d just grab one at the Bellevue store. Little did I know that the devices had sold out everywhere and it wouldn’t be until January until I could get one. I’ve now had my Band for about a week and have given it quite a workout. In all I think that despite a few flaws the device is quite impressive, especially for it’s first generation.

Extending the Phone

For me, the Band’s primary purpose is to be an extension of my phone and for the most part it plays its role quite well. I love that the Band vibrates to notify me of upcoming appointments, incoming calls (including Skype), text messages, emails, and social media messages. Before getting the Band I was constantly distracted by my phone. Glancing at the phone whenever it buzzed often required stopping whatever I was doing to fish it out of my pocket only to immediately dismiss the notification. With the Band, I can still stay up-to-date with all my notifications but since I wear it face-up on my right wrist seeing the notification typically requires only diverting my gaze. This also allows me to leave my phone outside of my immediate vicinity and continue receiving the notifications. In fact, as I’m typing this, my phone is charging in another room but I’m still getting the notifications on my wrist.

What I find really nice is that the Band doesn’t merely display notifications. By tapping on certain notifications, emails and text messages in particular, the device will display the first few lines of the message. This is particularly helpful for determining whether certain messages require immediate attention or can be deferred until later. Additionally, for text messages you can configure up to four predefined which you can select as a response to a message. It would be nice to have a few more slots but four seems like a decent starting point.

While the Band’s initial release is an adequate starting point in that it satisfies my basic requirements for such a device I still think there’s still plenty of room for improvement. The number one thing I want a future update to introduce is some additional actions for managing email. Currently, all the Band can do here is display part of a message. I’d like to be able to change the read/unread state, toggle a flag, or delete the message right from the Band. Including these options would go a long way toward further reducing my dependency on my phone. (I’ve entered a suggestion for this on UserVoice. Please give it some votes if you agree!)

Since I primarily use the Band for notifications, it would be nice if the “lock” screen (in quotes because the Band isn’t truly locked) would display some summary information such as the number of unread emails. I imagine this would be a configurable option and possibly only visible in watch mode (something else I love) but it would certainly make the information more accessible than unlocking the device and scrolling through the tiles. On a related note, reading a notification should clear the indicators on the tiles so it’s not necessary to dismiss the notification then go to the individual apps to remove the indicator. (Vote for this suggestion on UserVoice.)

The final major thing I’d really like to see improved here is the alarm system. I use my phone’s alarm feature extensively with different alarms set for different times and different days. I’d really like to see those better integrated with the band so I don’t have to set the same alarm in two places.


I'm CortanaI love Cortana. I like Cortana so much I have a Cortana t-shirt and even have a figurine on my desk at work. I use Cortana regularly for creating appointments and reminders, checking headlines. I particularly love the context-based reminders that pop up when I talk to someone or arrive somewhere. But you know what? Before the Band most of my interactions with Cortana were text-based. I’d fire up the Cortana app on my phone and type my request. Yes, I could have used the voice features but doing so always felt awkward on the phone.

With the Band I’ve found that I’m using Cortana not only more frequently but more effectively, too. For instance, when I leave the office at the end of the day I typically call my wife to let her know I’m on my way home. Even if I were to use Cortana’s voice commands on the phone it required getting my phone from my pocket, waking it up, holding the search button, then telling Cortana to call her. Now all I have to do is hold a button on my wrist, say “call my wife” and next thing I know, my car’s stereo has switched to the call.

Health & Fitness

Sleep Tracker Microsoft primarily markets the Band as a fitness device using the tagline “Live healthier and be more productive” but for me, this is a tertiary concern. As such I haven’t really spent much time messing around with these features beyond the sleep tracker. In fact, I’ve never opened the run tracker and I’d be amazed if I ever decide to try out one of the workout plans.

The sleep tracker feature was clearly the part of this feature set that I was most interested in. The first night I tried it I fully expected it to tell me I’m not sleeping effectively. When I awoke I was surprised to see that it determined that my sleep was approximately 92% efficient. I was excited to share this figure with my wife who typically tells me I don’t sleep enough but it turned out that she had 94% efficiency so my excitement was short-lived.

Beyond the sleep tracker I occasionally glance at the step counter, calorie meter, and heart rate monitor. I can’t say I’ve ever manually counted my steps for an extended period of time or considered the other metrics so I can’t attest to their accuracy but they’re somewhat interesting nonetheless. Perhaps if I get the sudden urge to care I’ll pay a bit more attention to them.


I’m not normally much of a Starbucks fan but the Starbucks app on the Band makes it so convenient that it’s hard to turn down. When I purchased the band I received a $5 gift card which I registered on their site, added some more money, and entered the card into the Band app. Once the app is connected to a card, opening it displays a PDF417 bar code that represents the configured card. To use it, just display the code, swipe your wrist past the scanner, and watch the barista’s jaw drop in wonder at this new technology.

Despite its simplicity, my anecdotal experiences tell me that this is something that Microsoft should leverage more when promoting the device. It would be nice if the app could tie into the Starbucks system to obtain the remaining balance but I can see not having that feature at this time. I really think that expanding this feature beyond Starbucks to include gift and loyalty cards from other vendors would be a huge selling point.

Life Hack: I’ve been having a bit of extra fun with this Band feature. Now that I have the convenience of a reloadable gift card on my wrist all those Bing rewards points I’ve accumulated over the years but haven’t cashed in can now go to $5 Starbucks gift cards. I can then transfer the balance from those cards to the one I tied to my Band! I’ve already transferred three cards from Bing Rewards to keep the coffee coming.

Hardware & Comfort

In addition to the built-in microphone, haptic vibration motor, and Bluetooth 4.0, the Band’s spec sheet lists ten sensors:

  • Optical heart rate sensor
  • 3-axis accelerometer
  • Gyrometer
  • GPS
  • Ambient light sensor
  • Skin temperature sensor
  • UV sensor
  • Capacitive sensor
  • Galvanic skin response

The screen is a 320 x 106 pixel capacitive 1.4″ TFT color display and seems adequate for such a small device. My only real complaint in this area is that vertical scrolling on messages can be a bit cumbersome if you don’t hit the correct part of the screen. I’m gradually learning where the sweet spot is and have noticed this being less of a problem as I adjust.

The Band is intended to be worn constantly (removing for charging which takes about 2 hours, of course). I haven’t worn a watch in years so adjusting to having something on my wrist all the time has taken some adjustment. At first I had some skin irritation under the charging connector but that seems to have subsided and despite the occasional flare-up, I hardly notice the device unless it’s notifying me of something.

I’ve found the thermal plastic elastomer material used in the Band’s construction to be a bit stiff which makes putting on and removing the device somewhat clumsy but since it’s intended for constant use, this is hardly a concern. What worries me more is the construction around the battery compartments and of the connector.

Band ConnectorTo ensure an advertised two-days of operation (I’m noticing a bit less) the Band has two batteries – one in each strap. Prior to purchasing my Band I looked at plenty of display models and I noticed that the straps were actually pulling away from the battery compartments. It’s likely that this was a symptom of overuse and people not realizing that most of the strap isn’t flexible. So far I haven’t seen any signs of this problem on my Band or my wife’s but it’s still a concern.

On the other hand, the connector at the end of each strap seems rather flimsy to me. It’s a clip-based system with two tiny prongs that latch inside a track. So far they’ve seemed OK but as I was getting used to wearing it, I did catch the band on something and thought it might snap one of them. I’ve also heard a few reports of the connector weakening and giving out after about a month.

One thing that has definitely been a bit of a concern is that the device had been losing its Bluetooth connection with my phone on a somewhat regular basis. This generally required me to disable and re-enable Bluetooth on both my phone and the Band. I did a little research to see if anyone else was experiencing the problem and it seemed that others using the Band with a Lumia 1020 were finding that they had the problem if there were too many apps running in the background on the phone. The Battery Saver app didn’t show much of anything out of the ordinary but that got me thinking about one of the games I’d been playing. Since I stopped playing Bejeweled Live on the phone I haven’t seen the problem so I’m hoping that’s the culprit.

Overall Impressions

Now that I’ve lived with the Band and tried it out in a variety of conditions, I have to say I’m quite impressed with this first generation product despite a few rough spots like the message management capabilities or potential hardware issues. Having something that unobtrusively alerts me of incoming messages has greatly reduced my direct dependence upon my phone.

January Indy F# Meetup

We’re on a roll! The third consecutive Indy F# Meetup is on Tuesday, January 20th at 7:00 PM. As always, we’ll be meeting at Launch Fishers. Check out the meetup page to register and for logistics information.

When we started the group we decided to alternate the format between dojos and lectures. Since last month was a type provider lecture this month will mark a return to the dojo format. We thought it would be fun to change pace and hone our recursion skills a bit by working through the community-driven fractal forest dojo. I haven’t worked through this one yet myself but I’ve seen lots of beautiful images tweeted by people who have so it should be a great time and experience. I hope you’ll join us!

Extending F# Pipelines with a Tee Function

In functional programming we strive to minimize side-effects but not only are some side-effects desirable, in the largely object-oriented world in which many of us still operate such side-effects are often unavoidable. There are plenty of APIs that rely on side-effects particularly when it comes to initializing types or properties. One example that immediately comes to mind is building up an HttpResponseMessage in Web API 2. Consider the following snippet which creates a response containing the contents of a stream and sets some relevant header values:

member __.GetFile() =
  // ... SNIP ...
  let response = new HttpResponseMessage(HttpStatusCode.OK, Content = new StreamContent(stream))
  response.Content.Headers.ContentType <- MediaTypeHeaderValue("application/octet-stream")
  response.Content.Headers.ContentLength <- Nullable.op_Implicit stream.Length
  response.Content.Headers.ContentDisposition <- new ContentDispositionHeaderValue("attachment", FileName = "test.pdf")

This code is straight-forward but it’s highly imperative. Like side-effects, imperative code isn’t necessarily a bad thing but it would be nice to tame it a bit by initializing the header values as part of a pipeline while still returning the response message. Doing so isn’t hard: just create the HttpResponseMessage instance via the constructor and pipe it to a function that does the initialization before returning, right?

member __.GetFile() =
  // ... SNIP ...
  new HttpResponseMessage(HttpStatusCode.OK, Content = new StreamContent(stream))
  |> (fun response -> response.Content.Headers.ContentType <- MediaTypeHeaderValue("application/octet-stream")
                      response.Content.Headers.ContentLength <- Nullable.op_Implicit stream.Length
                      response.Content.Headers.ContentDisposition <- new ContentDispositionHeaderValue("attachment", FileName = "test.pdf")

This is a perfectly acceptable approach and is something I’ve definitely done plenty of times but all it has achieved is moving the explicit return into the function. After doing this a few times, you might start to think there has to be a way to standardize this pattern and you’d be right.

Over the holidays I finally found some time to relax and although I spent a great deal of time glued to Assassin’s Creed: Unity on my Xbox One I managed to read a few more articles than usual. Something that struck me as interesting was that I noticed a theme across several of the code samples: they were using a tee function within a pipeline. The tee function isn’t part of the core F# libraries and I couldn’t recall having encountered it before so I started doing some background investigation.

One of the first sites I found that mentioned the function in the context of F# was Scott Wlaschin’s excellent Railway Oriented Programming article which I’d read previously but clearly not thoroughly enough. In the article Scott says he named the function after a Unix command of the same name. The Unix command, which is named after plumbing tee fittings, splits a pipeline such that input flows to both standard output and a file. This is certainly useful for logging in shell scripts but its possibilities are much more interesting in an F# pipeline.

The tee function is a simple function which essentially says “given a value, apply a function to it, ignore the result, then return the original value.” It’s basic definition is as follows:

let inline tee fn x = x |> fn |> ignore; x

By introducing the tee function into the pipelined version of the GetFile method we can remove the explicit return:

member __.GetFile() =
  // ... SNIP ...
  new HttpResponseMessage(HttpStatusCode.OK, Content = new StreamContent(stream))
  |> tee (fun response -> response.Content.Headers.ContentType <- MediaTypeHeaderValue("application/octet-stream")
                          response.Content.Headers.ContentLength <- Nullable.op_Implicit stream.Length
                          response.Content.Headers.ContentDisposition <- new ContentDispositionHeaderValue("attachment", FileName = "test.pdf"))

Now the pipeline looks more like what we might expect since we’re no longer explicitly returning the response from the lambda expression.

Depending on your style preferences, injecting the tee function explicitly into the pipeline as you would a Seq.filter or other such function might bother you. To me, the tee function is a perfect candidate for a custom operator so let’s define one.

let inline ( |>! ) x fn = tee fn x

Here we’ve defined |>! as the tee operator (this is the same symbol that WebSharper uses). Notice how the parameter order is reversed from the tee function. This is due to the fact that when using our new operator, we’re not relying on partial application to invoke the tee function. Now we can eliminate the explicit reference to the function, making the operation look like a natural part of the F# language.

member __.GetFile() =
  // ... SNIP ...
  new HttpResponseMessage(HttpStatusCode.OK, Content = new StreamContent(stream))
  |>! (fun response -> response.Content.Headers.ContentType <- MediaTypeHeaderValue("application/octet-stream")
                       response.Content.Headers.ContentLength <- Nullable.op_Implicit stream.Length
                       response.Content.Headers.ContentDisposition <- new ContentDispositionHeaderValue("attachment", FileName = "test.pdf"))

Since the tee function/operator is intended to allow side-effects within a pipeline it is ideal for adding logging or other diagnostics into a pipeline (as was the intent in the original Unix command). For instance, to write out a message as each header value is set, we can simply split the tee’d function above into separate functions, inserting a tee’d logging function in between:

member __.GetFile() =
  // ... SNIP ...
  new HttpResponseMessage(HttpStatusCode.OK, Content = new StreamContent(stream))
  |>! (fun _ -> Debug.WriteLine "Created response")
  |>! (fun r -> r.Content.Headers.ContentType <- MediaTypeHeaderValue("application/octet-stream"))
  |>! (fun r -> Debug.WriteLine("Set content type: {0}",
                                [| box r.Content.Headers.ContentType.MediaType |]))
  |>! (fun r -> r.Content.Headers.ContentLength <- Nullable.op_Implicit stream.Length)
  |>! (fun r -> Debug.WriteLine("Set content length: {0}",
                                [| box r.Content.Headers.ContentLength.Value |]))
  |>! (fun r -> r.Content.Headers.ContentDisposition <- new ContentDispositionHeaderValue("attachment", FileName = "test.txt"))
  |>! (fun r -> Debug.WriteLine("Set content disposition: {0}",
                                [| box r.Content.Headers.ContentDisposition.DispositionType |]))

By introducing the tee function and operator you give yourself another tool for taming the imperative code and side-effects that tend to pop up in software projects of any complexity.

Nebraska Code Conference Call For Speakers

Wait… What? Nebraska? Yes! Nebraska! Last year I had the good fortune to present both a workshop and a breakout session at Nebraska Code Camp and the entire experience was one of the highlights of my year. The event has evolved from a two-day code camp to a three-day code conference being held March 19-21 in Lincoln! A bigger conference means a new venue, more sessions, and more networking opportunities that you definitely won’t want to miss.

The Nebraska Code Conference call for speakers is currently underway and I highly recommend submitting a talk but hurry, the call closes on January 16th. Even if you’ve never given a talk before, there’s no better time to start than now! I also have it on good authority that the conference organizers would like to see a decent number of F# talks so to all of my F# friends: please get those submissions in!


2014 in Review

The stats helper monkeys prepared a 2014 annual report for this blog.

Here’s an excerpt:

Madison Square Garden can seat 20,000 people for a concert. This blog was viewed about 63,000 times in 2014. If it were a concert at Madison Square Garden, it would take about 3 sold-out performances for that many people to see it.

Click here to see the complete report.