Exploring HealthKit With Xamarin: Provisioning and Permissions Illustrated Walkthrough

One of the more interesting frameworks in iOS 8 is Health Kit, system-wide persistent storage for health-related information. I’m just beginning to explore the namespace myself, but thought I’d walk through the steps you need to manipulate Health Kit with Xamarin.

Because health-related information is so sensitive, developing for Health Kit requires:

  1. The app be developed using an “Explicit App ID” with Health Kit Services explicitly enabled (see below);
  2. The Entitlements.plist must have a com.apple.developer.healthkit key set to true; and
  3. At initial runtime, the user must grant access via a detailed permissions dialog

Additionally, it’s worth emphasizing the importance of checking error codes in Health Kit API function calls. If a user does not grant permission or if for any other reason the app makes a call to a non-permitted API, this does not raise an exception. Rather, a null or otherwise empty result will be returned and typically an out NSError or closure-parameter will be set.

Provisioning and Permissions

Xamarin has a great article on device provisioning, but just to hit the highlights for Health Kit:

You need to set an “Explicit App ID” and explicitly enable “Health Kit” as an app service. Here, I’m created an ID for an app whose ID is “{PREFIX}.com.xamarin.HKWork”:

Screen-Shot-2014-07-11-at-7.49.46-AM

Screen Shot 2014-07-11 at 7.51.14 AM

After you do that, you’ll have to create a new provisioning profile for this App ID:

Screen Shot 2014-07-11 at 7.59.17 AM

Once you’ve awaited the generation of the profile, download it and double-click to install it on your development system:

Screen Shot 2014-07-11 at 8.05.17 AM

Now, in your Xamarin Studio project, open your Info.plist and set the Bundle Identifier to your explicit App ID (without the team prefix):

Screen Shot 2014-07-11 at 8.56.35 AM

And set your project’s Bundle Signing options so that you are using your new provisioning profile:

Screen Shot 2014-07-11 at 8.14.07 AM

(Now that I’ve written that, I suspect that you can probably leave it as “Automatic”, since the App ID is explicitly the same as that in the custom provisioning profile: that’s how the two are matched by the system. But still, I’m going to leave the step just to be clear what’s happening. And I don’t think there’s any harm in setting the provisioning profile explicitly.)

You’ve taken care of Info.plist, so now open Entitlements.plist. (Some project templates don’t automatically generate an Entitlements.plist file. If your project doesn’t have one, use File/New File…/iOS and choose Entitlements.plist.) Click on “Source” and add a new key com.apple.developer.HealthKit of type Boolean with a value of Yes (== true):

Screen Shot 2014-07-11 at 9.14.53 AM

Write code to request permission from the app user

To use Health Kit, the user must grant your app access. This involves these API calls:

var temperatureKey = HKQuantityTypeIdentifierKey.BodyTemperature;
var tempQuantityType = HKObjectType.GetQuantityType (temperatureKey);

var hks = new HKHealthStore ();
hks.RequestAuthorizationToShare (new NSSet (new [] { tempQuantityType }), new NSSet (), (success, error) => {
	Console.WriteLine ("Authorized:" + success);
	if (error != null) {
		Console.WriteLine ("Authorization error: " + error);
	}
});

Here, we are requesting authorization to share body temperature data (i.e., “share data generated by my app with the HealthStore database”). When this app is run, the user will be presented with the Health Kit permissions dialog, which will give the user fine-grained control over the requested types of data you’ll share. In this case, for instance, the dialog inside the Health app looks like this:

IMG_1314

Write a brilliant app

I have no insight into how to do that.

… that has some health-related information

Oh good, I can help with that.

Creating and storing data in the shared HealthKit store involves these API calls:

var temperatureKey = HKQuantityTypeIdentifierKey.BodyTemperature;
var tempQuantityType = HKObjectType.GetQuantityType (temperatureKey);
var myCurrentTemp = HKQuantity.FromQuantity (HKUnit.DegreeFahrenheit, 98.6);
var meta = NSDictionary.FromObjectAndKey (new NSNumber (4), HKMetadataKey.BodyTemperatureSensorLocation);
var tempSample = HKQuantitySample.FromType (tempQuantityType, myCurrentTemp, new NSDate (), new NSDate (), meta);

hks.SaveObject(tempSample, (success, error) => {
	Console.WriteLine("Write succeeded: " + success);
	if(error != null)
	{
		Console.WriteLine(error);
	}
});

I trust it’s obvious that the types of data you attempt to store must match those you’ve requested permission from the end-user and that your error-handling should be considerably more sophisticated (since it’s incredibly possible that app users are going to be very cautious about allowing access to their medical data, even if it’s clearly central to the app’s value).

The resulting shared data (assuming that permissions are granted) looks like this in the Health app:

image1

Notice that although I created the data using Fahrenheit, in this case it’s being displayed as Celsius (which I imagine is the opposite of the likely use-case!). Units of measure and conversions are built in to Health Kit, which I’ll cover in a later post. For now, though: Happy Healthing!

The Protocol Pattern

In C# (and F#), one can define extension methods on interfaces. These extension methods can have implementations, which can be used as default implementations for implementors of the extension. I haven’t heard a name for this technique.

Example:

interface IFoo
{

}

static class IFoo_Extensions 
{
	public static void Foo(this IFoo self) { Console.WriteLine("Foo"); }
}

class ImplementingClass : IFoo
{

}


class MainClass
{
	public static void Main (string[] args)
	{
		var aFoo = new ImplementingClass ();
		aFoo.Foo (); //Prints "Foo" from extension default implementation

	}
}

Xamarin uses this pattern extensively when binding Objective-C Protocols, which are essentially interfaces with optional methods. For instance, if you have an interface where some methods must be implemented by the library user but some aren’t, you can do this:

interface IFoo
{
	//Methods defined here, as always, must be implemented
	void Necessary ();
}

static class IFoo_Extensions
{
	//"Optional" methods defined here with default implementations
	public static void Optional (this IFoo self)
	{
	}
}

class ImplementingClass : IFoo
{
	public void Necessary ()
	{
		Console.WriteLine ("Necessary");
	}

//    public void Optional()
//    {
//        Console.WriteLine("Overridden");
//    }

}

Obviously, it’s not exactly the same to have a default implementation defined in an extension method as it is to have an optional method that simply does not exist. But conceptually it’s close enough that I’ve started referring to this technique as the “Protocol Pattern.”

Thoughts?

Local Notifications in iOS 8 With Xamarin

As of iOS 8, the user has to provide explicit permission for apps to respond to local notifications. This means that now, the first time the program is run, you need to run code such as:

//F#
UIUserNotificationSettings.GetSettingsForTypes(
    UIUserNotificationType.Alert 
    ||| UIUserNotificationType.Badge 
    ||| UIUserNotificationType.Sound, 
    new NSSet())
|> UIApplication.SharedApplication.RegisterUserNotificationSettings

or

//C#
var settings = UIUserNotificationSettings.GetSettingsForTypes(
    UIUserNotificationType.Alert 
    || UIUserNotificationType.Badge 
    || UIUserNotificationType.Sound, 
    new NSSet());
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);

Which will present a user dialog. When they complete that dialog, the system will call the UIAppDelegate.DidRegisterUserNotificationSettings method. You can check the status using UIApplication.CurrentUserNotificationSettings.

If you try to send a notification without these settings being allowed, you will get a runtime error of the form:

Attempting to schedule a local notification {...} with an alert but haven't received permission from the user to display alerts
Attempting to schedule a local notification {...} with a sound but haven't received permission from the user to play sounds
Attempting to schedule a local notification {...} with a badge number but haven't received permission from the user to badge the application

F# For Scripting

It’s F# Week at Xamarin. Also, in the US, it’s only a 4-day work-week. F# saves 20% of your time. QED.

Anyway, I don’t have any actually interesting F# to share, but I recommend:

But what I thought I could quickly contribute is that:

  • F# is an awesome scripting language; and
  • Scripting may be the best way to learn F#

Scripting tasks often involve transforming a stream of text by repeatedly Filtering, Assigning, Reducing, Transforming, and Slicing it (“a sequence of FARTS“) and this is an area where the functional approach is pretty clearly easier to work with than the OOP approach of a network of cooperating objects.

And since scripting tasks are often private or semi-private low-complexity chores, they’re an excellent domain for regularly exercising your knowledge of a new language. It’s all well and good to carve out a couple weekends and work through a book but nothing beats regular exposure.

(While I’m on the subject, these are currently my favorite F# books. Initial exploration:

Deeper dives:

)

F# scripts are F# files with the .fsx extension. On OS X with mono, they can be run with fsharpi script.fsx or:

#if run_with_bin_sh
  exec fsharpi --exec $0 $*
#endif
printfn "%A" fsi.CommandLineArgs

To add references, use #r:

#if run_with_bin_sh
  exec fsharpi --exec $0 $*
#endif

#r "System.Core.dll"
#r "System.Xml"

open System
open System.Xml.Linq
open System.IO

//...etc...

I’ve been using F# for scripting for more than a year now and I can honestly say that it’s displaced Ruby as my scripting language of choice.

Give it a shot!

iOS 8, Scene Kit @ 60FPS, programmed in F#, using Xamarin.iOS

I have the best job in the world:

namespace SceneKitFSharp

open System
open MonoTouch.UIKit
open MonoTouch.Foundation
open MonoTouch.SceneKit
open MonoTouch.CoreAnimation

type MySceneKitController () =
    inherit UIViewController()

    override this.ViewDidLoad () =
        let scene = new SCNScene ()

        //Positions everyone!
        let boxNode = new SCNNode ()
        boxNode.Geometry <- new SCNBox(
            Width = 1.0F, 
            Height = 1.0F, 
            Length = 1.0F, 
            ChamferRadius = 0.02f
        )
        scene.RootNode.AddChildNode (boxNode)

        let material = new SCNMaterial ()
        material.Diffuse.Contents <- UIImage.FromFile ("textureX.png")
        material.Specular.Contents <- UIColor.Gray
        material.LocksAmbientWithDiffuse <- true
        boxNode.Geometry.FirstMaterial <- material

        //Lights!
        let lightNode = new SCNNode()
        lightNode.Light <- new SCNLight ()
        lightNode.Light.LightType <- SCNLightType.Omni
        lightNode.Position <- new SCNVector3 (0.0F, 10.0F, 10.0F)
        scene.RootNode.AddChildNode (lightNode)

        let ambientLightNode = new SCNNode ()
        ambientLightNode.Light <- new SCNLight ()
        ambientLightNode.Light.LightType <- SCNLightType.Ambient
        ambientLightNode.Light.Color <- UIColor.DarkGray
        scene.RootNode.AddChildNode (ambientLightNode)

        //Camera!
        let cameraNode = new SCNNode ()
        cameraNode.Camera <- new SCNCamera ()
        scene.RootNode.AddChildNode (cameraNode)
        cameraNode.Position <- new SCNVector3 (0.0F, 0.0F, 3.0F)


        // Action!
        let animation = new CABasicAnimation(
            KeyPath = "rotation"
        )
        let t = new SCNVector4 (1.0F, 1.0F, 0.0F, float32 (Math.PI * 2.0))
        animation.To <- NSValue.FromVector (t)

        animation.Duration <- float 5.0F
        animation.RepeatCount <- float32 Double.MaxValue //repeat forever
        boxNode.AddAnimation(animation,new NSString("rotation"))

        let scnView = new SCNView(UIScreen.MainScreen.Bounds)
        scnView.Scene <- scene
        scnView.AllowsCameraControl <- true
        scnView.ShowsStatistics <- true
        scnView.BackgroundColor <- UIColor.Black

        this.View <- scnView
       

[<Register ("AppDelegate")>]
type AppDelegate () =
    inherit UIApplicationDelegate ()

    // This method is invoked when the application is ready to run.
    override this.FinishedLaunching (app, options) =
        let window = new UIWindow (UIScreen.MainScreen.Bounds)
        window.RootViewController <- new MySceneKitController()
        window.MakeKeyAndVisible ()
        true

module Main =
    [<EntryPoint>]
    let main args =
        UIApplication.Main (args, null, "AppDelegate")
        0

IMG_0272

photo

Using Xamarin.Forms.Maps: You have to Init() first!

The first time I wrote a Xamarin.Forms.Maps program, I couldn’t figure out why my map wasn’t appearing. And then I put a call to Xamarin.FormsMaps.Init() into the AppDelegate (iOS) and MainActivity (Android):

Shared:

    public class App
	{
		public static Page GetMainPage ()
		{	
			return new ContentPage { 
				Content = new StackLayout {
					Children = {
						new BoxView { BackgroundColor = Color.Green },
						new Map(MapSpan.FromCenterAndRadius(new Position(37,-122), Distance.FromMiles(10))){
							VerticalOptions = LayoutOptions.FillAndExpand,
							HeightRequest = 100,
							WidthRequest = 960,
							BackgroundColor = Color.Blue
						},
						new BoxView { BackgroundColor = Color.Red }
					}
				}
			};
		}
	}

iOS:

    namespace HelloMap.iOS
	{
		[Register ("AppDelegate")]
		public partial class AppDelegate : UIApplicationDelegate
		{
			UIWindow window;

			public override bool FinishedLaunching (UIApplication app, NSDictionary options)
			{
				Forms.Init ();
				FormsMaps.Init ();

				window = new UIWindow (UIScreen.MainScreen.Bounds);
				
				window.RootViewController = App.GetMainPage ().CreateViewController ();
				window.MakeKeyAndVisible ();
				
				return true;
			}
		}
	}

Android:

    namespace HelloMap.Android
	{
		[Activity (Label = "HelloMap.Android.Android", MainLauncher = true)]
		public class MainActivity : AndroidActivity
		{
			protected override void OnCreate (Bundle bundle)
			{
				base.OnCreate (bundle);

				Xamarin.Forms.Forms.Init (this, bundle);
				FormsMaps.Init(this, bundle);

				SetPage (App.GetMainPage ());
			}
		}
	}

Happy Cross-Platform Coding!

Screen Shot 2014-05-30 at 1.52.09 PM

50 PRINT “HAPPY BIRTHDAY”

I think BASIC’s greatest strength may be that it was something that many people — not just those with a particular background — could learn. There was no gatekeeper, either literally or figuratively: you didn’t have to push punchcards under a bank-teller window nor did you have to learn recursion before learning recursion. In the 80s, virtually every machine ran BASIC and learning how to login and start the interpreter was generally the hardest part of beginning to “program an X machine.”

People get drop-through imperative programming: either the line-by-line flexibility of BASIC or the blocks of FORTRAN and Flash (I didn’t understand Flash until I realized that it’s just FORTRAN with worse numerics and better graphics). You don’t have to be a born programmer to understand:

 10 PRINT "HELP! I AM CAUGHT IN A PROGRAM LOOP!"
 20 GOTO 10

I imagine that 95% of the people who got a passing grade in their BASIC programming class or typed in a few games from the back of COMPUTE! magazine never wrote themselves another program. But the 5% who did found that personal computers could help them in their job. And the 1-in-100 or 1-in-1000 who went beyond that found themselves in a community where only drive and talent mattered and credentials meant nothing.

I’m a college dropout and never took a CS course in my life. At 25 I was hired as Technical Editor for a magazine that specialized in Artificial Intelligence and for Computer Language, the best programming magazine of all time (as far as size or circulation goes, we were the “We Try Harder” Avis to Dr. Dobb’s Journal‘s Hertz).

Today, the design of programming languages is discussed at sites like Lambda the Ultimate and while I can muddle through even some of the more arcane papers, and while I understand the value of a dense, high signal-to-noise ratio on certain topics, it seems to me that there’s not nearly enough reflection on the market triumphs of popular languages. I’m not advocating a return to the line-numbered BASIC interpreters (single-threaded, as if that had to be mentioned!) of my youth, but I am saying that 50 years ago, Kemeny, Kurtz, and colleagues captured lightning in a bottle. So did Dan Bricklin, inventor of the computerized spreadsheet, another tool for manipulating data and calculations that empowered an audience vastly larger than that emerging from the bottleneck of “Computer Science courses at good universities.”

I’m not suggesting that marketshare is the only, or even dominant, factor in assessing a language’s quality. In the case of JavaScript, for instance, I see an example of the contingent nature of history, as discussed in Steven Jay Gould’s classic Wonderful Life. JavaScript is a market triumph, it behooves all professional programmers to master it, but I think it’s fair to say that it has some flaws as a programming language.

Nor am I saying that there’s not a lot of discussion of “beginner’s languages.” I volunteer at a local school and am tremendously impressed by Scratch, for instance. Because Scratch is accessible at such a young age, it may generate the same kind of nostalgia that some of us share for BASIC. But I don’t suspect that it will have the truly broad, industry-expanding impact of BASIC or Flash.

Today, there’s some talk of functional programming sweeping over the industry in the same way that object-orientation did in the early 1990s. I am not a functional programming True Believer, but I truly believe that functional programming has advantages. And it seems to me that languages such as F# on the CLR and Scala on the JVM have a “you can have it all” aspect (no-hassle availability of libraries, the ability to integrate with legacy code, object-functional hybrid type-systems) that at the very least make them appealing to some teams.

But, although perhaps not as broadly accessible as line numbers and GOTO, OOP has something of BASIC’s “learnability.” We can teach OOP to a lot of people, without a lot of preliminaries. And some will struggle through, and some will have a comfortable understanding, and some will have taken a step towards design and architecting large systems. With Functional Programming, it’s not as clear to me that there’s that same “muddle through” path. It’s hard for me to imagine a better introduction to functional ideas than the early chapters of Structure and Interpretation of Computer Programs, but I think of that as a text that weeds out, not one that expands the base. If you’re a natural-born programmer with a semester in front of you SICP is a great book. But if you “just” have potential or are a working developer with a “where does this help my day-to-day problems?” pragmatism, I don’t know what you should read.

Goto 10

BASIC was the first programming language for most of those in my generation. We sat in front of green- and amber-texted monitors or machines that spooled seemingly infinite reams of paper. We typed on chiclet keys and teletypes, punched papertape and cards and threaded magnetic reels. Compared to today’s machines we had indistinguishable-from-0 working memory or horsepower.

You have no idea how fun it was.

Reviewing Values for iOS UIViewContentMode with Xamarin and F#

Who can remember the scaling behavior of UIView.ContentMode? Not me!

So I wrote this quick little F# program to review them:

    namespace Simple
     
    open System
    open MonoTouch.UIKit
    open MonoTouch.Foundation
    open System.Drawing
     
    type ContentView ( color : UIColor ) as self = 
        inherit UIView ()
        do
            self.BackgroundColor < - color

    type ContentModeModel  () = 
         inherit UIPickerViewModel ()

         let T = typedefof<UIViewContentMode>

         let selectionChanged = Event<_>()

         member this.SelectionChanged = selectionChanged.Publish 

         override this.GetRowsInComponent(_, _) = Enum.GetNames(T).Length
           
         override this.GetTitle(_, row : int, _) = Enum.GetName(T, row)

         override this.GetComponentCount(_) = 1

         override this.Selected(_, row : int, _) = selectionChanged.Trigger(enum<UIViewContentMode>(row))
       
     
    type SimpleController ( ) =
        inherit UIViewController ()
     
        override this.ViewDidLoad () = 
            this.View < - new ContentView(UIColor.Blue)

            let imgView = new UIImageView(new RectangleF(20.0F, 80.0F, UIScreen.MainScreen.Bounds.Width - 40.0F, 100.0F))
            imgView.Image <- UIImage.FromFile("flower.png")
            imgView.ClipsToBounds <- true
            this.View.AddSubview(imgView)

            let picker = new UIPickerView(new RectangleF(20.0F, UIScreen.MainScreen.Bounds.Height - 180.0F, 250.0F, 140.0F))
            let model = new ContentModeModel()
            picker.Model <- model 

            model.SelectionChanged.Add <| fun newMode -> imgView.ContentMode < - newMode

            this.View.AddSubview(picker)
     
    [<Register ("AppDelegate")>]
    type AppDelegate () =
        inherit UIApplicationDelegate ()
     
        let window = new UIWindow (UIScreen.MainScreen.Bounds)
     
        // This method is invoked when the application is ready to run.
        override this.FinishedLaunching (app, options) =
            let viewController = new SimpleController()
            window.RootViewController < - viewController
            window.MakeKeyAndVisible ()
            true
     
    module Main =
        [<EntryPoint>]
        let main args =
            UIApplication.Main (args, null, "AppDelegate")
            0

No real interesting techniques, but another nice quick iOS app in Xamarin using F#.

contentview

Review of my Xamarin F# Event Code Leads To Improvements

Not at all surprisingly, it turns out that F# events need not be the crufty structures I showed in my previous post.

First, Xamarin‘s David Siegel suggested “Let the Event type be inferred, don’t define a delegate type, and send simple typed values rather than EventArgs:”


open System

type Control() =
let hello = Event<_>()

member this.Hello = hello.Publish
member this.Speak() = hello.Trigger "yo!"

let control = Control()

control.Hello.Add < | fun msg ->
printfn "Received '%s'" msg

control.Speak()

While Ryan Riley suggested a step further down the reactive line:

To remain consistent with your pipe forwards when using events, you can use the Observable module:
do myItem.FooEvent |> Observable.add (fun o args -> …)
or even
let disposable = myItem.FooEvent |> Observable.subscribe (fun o args -> …)
You can also expose an event as an IObservable rather than as an event if you like:
FooEvent.Publish :> IObservable


I also learned from @kemnet that List.choose id is the idiomatic way to transform a List<option> into a List of Some values.

Review of my first real F# program written in Xamarin

tl;dr: F# has a long learning curve (it takes a long time to master) but productivity happens quickly.


I recently wrote my first real application in F#. Although I’ve been using F# for many of my scripting needs for about a year and use F# to explore iOS APIs regularly, this application is the tool in which I’m going to live for the next several months. As such, I wanted to use a modicum of decent practices: separating UI from behavior and test-driven (or at least test-supported) development. On the other hand, every day I spent writing the app was a day I wasn’t doing the task it was meant to aid, so I needed my programming time to be primarily about implementation, not Functional Purity or pushing the corners of the envelope of my understanding of F#.

The actual project is proprietary, so I can’t be particularly specific nor share code, but it involves a lot of fiddly details surrounding the part that actually requires expertise. Without automation, the fiddly details end up not only taking a significant amount of time in themselves but they prevent me from achieving flow, which I think is an even greater problem for my overall productivity. (Note to self: Write blogpost titled “Work harder, not smarter,” about the importance of achieving flow.)


One of the major aspects of the task involves writing XML. As an example of the type of trade-off that I found easy to make, I mutate the XElements rather than using a Zipper or something like that.

On the other hand, it’s amazing how quickly and constantly mutability bites you in the ass. This is one aspect of functional programming that I do think is a legitimate surprise. Although I believe “prefer immutability to mutability” is just good programming and not a revelation brought down from the mountain by Haskell, when you write code in which most of your identifiers are assignment-only, it highlights how often your troubles rotate around those with a mutable modifier or values that depend on the order in which things are initialized.

On the other other hand, the stringly-typed nature of the world is not to be dismissed. My biggest bug, which lay there for 2 days being passed by my test suite, was an XPath mistake. I also have some regular expressions in the program; these happen to be pretty straightforward, but obviously regexes are another place where the advantages of strong typing are often undermined by convenience.

As Peter Norvig told me during a conversation about type systems and the Mars Climate Orbiter (the one lost due to using the wrong units of measure):

I don’t know of any language, no matter how type-strict, that forces you to tag the string “123.45″ in a file with the units of force (newtons vs foot-pounds), nor do I know of any language, no matter how type-loose, in which you could not impose such a convention if you wanted to.


I very much wanted to separate the domain logic from the interface. Since I’m going to be living in this tool for months, there is a definite advantage if I can run it on my iPhone and Nexus 7 as well as my desktop Mac (did I mention that I was writing this using mono?). Since one can write an F# iOS app in 39 lines of code and since cross-platform applications are easy to write with Xamarin, this is straightforward. On the other hand, I needed to make sure that I was correct that the, you know, functionality was worthwhile in the first place.

So I wanted my initial version to be a command-line app. It’s been awhile since I’ve written an input loop and I don’t know if I’ve ever done one with a Model-View-Controller architecture before!

Although I took the Coursera course on Reactive Programming, staying event-driven was another example of letting pragmatics override a learning opportunity (no actors, no reactive extensions… Erik Meijer would be so ashamed of me…). This is one of the few places where F# disappointed me a little. My events look like this:

type EventType = Foo | Bar | Bat

type ParamArgs< 'T>(value : 'T, change : EventType) = 
    inherit System.EventArgs

    member this.Change = change
    member this.Value = value

type ChangeDelegate< 'T> = delegate of obj * ParamArgs< 'T> -> unit

type MyType =
    let fooEvent = new Event<changedelegate <string>, ParamArgs<string>>()

    [<clievent>]
    member this.FooEvent = fooEvent.Publish

And on the receiving side:

do myItem.FooEvent.AddHandler(
    new ChangeDelegate<string>(
        fun sender args -> //handle the event
    )
)

Which, now that I type it out, doesn’t look all that bad. But given how spoiled you get about not spending your time finger-typing in F#, it feels crufty.

As an example of how F# generally spoils you, I offer the “forward pipe operator”:

let baz = foo |> bar |> bat 

Which should bring a nod from anyone familiar with the UNIX shell. It’s the equivalent of, say:

let baz = bat(bar(foo()))
//or
let fooResult = foo()
let barResult = bar(fooResult)
let baz = bat(barResult)

But it’s superior to both those forms. It’s just easier to read than the in-to-out, right-to-left nested function call (putting aside the parentheses, about which more later…). But it’s superior to the second in a more fundamental way. Phil Karlton tells us

There are only two hard things in Computer Science: cache invalidation and naming things. [And off-by-one errors.]

The really nice thing about piping is the way it ties together the expression without intermediate names. The pipes indicate

Here, foo, bar, and bat are logically connected: you can’t replace foo and bar without considering the effect on bat, the calculation of bat is not only tied up with the calculation of bar, it’s also tied up with the calculation of foo. BUT the result of foo and the result of bar aren’t important outside of the calculation of bat! The result of bat is not just used immediately: it has a name and therefore has some importance.

That’s a lot of context to get from a language operator! It’s not just a convenience or a way to avoid a keystroke or two. It’s a good thing that you miss as soon as you work in another language.

Regrettably, I don’t feel as positively about F#’s indentation rules. I’m not going to go into too much detail on this, because I think it’s just a matter of personal preference (I take the increasing ubiquity of Python in the science community as evidence that I’m in the minority…). I can imagine that my irritation might go away with better tooling and some more-understandable compiler errors.


In F#, as with several other functional languages, enclosing function arguments with parentheses is optional: one can say Foo a as opposed to Foo(a). I’m pretty resistant to that: I don’t find Foo a easier to read at all. But the pipe operators (there’s also a backwards pipe) make the “point-free style” of programming more palatable. You don’t say |> fun a -> Foo (a) |> fun b -> Bar (b), you just say Foo |> Bar and that’s that. Admittedly, this occasionally leads to code that strikes me as somewhat cryptic: optionList |> List.collect Option.toList converts a list of Options into a list of the values of the Somes (i.e., flatMap id).


Another structural thing that slowed me down a bit is F#’s many kinds of types (I would say that F# has a plethora of kinds of types). I’m a believer in Functional in the Small, Object-Oriented in the Large, so I like to hang both data and responsibilities on a type. But with F#, I have to decide between classes (class), records (type), and discriminated unions (type |) (and 14 other kinds). The good news is that in my limited experience you can start with a record and then, if you need to refactor it into a class, it’s trivial (I may be insanely wrong about that, having only needed a class rather than a record once).

This proliferation of somewhat-overlapping concepts is about ensuring compatibility the Common Language Runtime and 95% of the time, it’s not something that you have to think about.


With my events in place and having decided on records, programming went very well. It’s trivial to use NUnit with F# and I quickly had 3 projects up and iterating: the model project, the CLI view & controller project, and my test suite.

I also used Xamarin Studio’s F# Interactive console regularly.
screenshot.

All of which was very pleasant, but I wonder if one downside of the “small functions doing one precise thing” of the functional approach is that it becomes easy to just keep composing function calls on the results of previous function calls rather than trying to create a consistent and sufficient data structure / object model. The drive towards refactoring a concise, task-driven API doesn’t seem as dominant since you’re simultaneously valuing the “easy to compose” tiny functions.

With small, easy-to-compose functions and a lot of flexibility about scoping you immediately start circling the issues of coupling and cohesion. General-purpose functions are, by definition, not very cohesive: they happen to be composed together to deliver value. Hmmm….


Even in a small program such as this, the lack of robust refactoring tools jumps out. When you’re learning a language, you just plough away at small programs, but as soon as you start writing even a few-module program, organizational and refactoring instantly becomes concerns.


Speaking of “small programs,” this program (which is focused, but not entirely trivial) is under 1KLoC including its test suite. I use craploads of higher-order functions, but with LINQ, I could structure a C# program very similarly. I also use pattern matching in several places and that would take more lines of C# code. I use the Option type, so that eliminates lines of C# dedicated to null-checking.

But in general I think I could (and would) write a very similarly-structured C# program to solve the problem. I would have written it faster, but not that much faster (maybe 10-15% faster). And the C# program would have, I think, about 20% or maybe even 33% more LOC; not that many more expressions but some more and then quite a few lines dedicated to closing parentheses and blocks. (Regarding my previous snarky comments about parentheses and indenting, I quote Walt Whitman:

Do I contradict myself? Very well, then I contradict myself, I am large, I contain multitudes.

)


One thing that became clear is that I haven’t come even close to mastering F#, despite having used it semi-regularly for a year. It’s learning curve is longer and higher than most languages. For instance, it now seems to me that I could have used a custom computation expression (dangerously close to the M-word) in a way that would have allowed me a lot of flexibility in evolving the app. Even more, I think that type providers might be an enormously important facility, but it’s an area where I haven’t even explored.

But as I said, I don’t think my productivity suffered all that much relative to C#, a language I’ve worked with since it’s very first beta. In other words, while the road to F# mastery is long, productivity comes much faster. I paid some penalty relative to C# on this project, I’ll pay less penalty on the next, less on the next after that… And I can see in a few smallish projects such as this, getting to the point where my productivity is in my standard range.

Scala was my day-to-day language for 2 years and I’d choose Scala over Java without hesitation (and no, Java 8 doesn’t change my mind). Mastering Scala involves understanding a very sophisticated and complex type system and there are certainly advantages to that, but (for me) the mental effort to know that type system has limited practical benefits relative to a less-sophisticated system. But I see in some of these F# facilities (such as type providers) the potential for techniques that are not just O(n) relative to my C# approaches. The F# learning curve is high, but I think that the long road to mastery might have more of a transformative change in my approach to programming.

Nonetheless, programming is programming and programming is hard. As soon as I thought I was ready to go, I discovered that some important data came in a variety of shapes. So I had to spend time discovering those patterns and working with them. That type of work is much easier in a language with a good set of higher-order list processing functions and built-in pattern matching. And, I think, the smaller functions characteristic of FP made it easier to isolate the change, but nothing defeats this essential characteristic of programming, which is that it’s far more about exceptions and business rules and capricious “that’s just the way it is” aspects than it is about mathematical elegance.


As for the application, in the first three days of this week, I averaged 5x my “doing it manually” productivity. So take that, Randall.

div>