Yes, Virginia, You Can Write HoloLens Apps in F#

This blog has moved; this piece now lives here.  Also, unfortunately, after this post was written I discovered incompatibilities which pretty much kill the idea of writing HoloLens applications in F#. See “No Virginia, You Can’t Actually Write Unity Apps for HoloLens in F#” for details.

F# fans who want to write applications for the Windows Store have been disconcerted by this thread on GitHub, which indicates that .NET native doesn’t support all the IL that F#’s compiler can generate. That seems to throw cold water those of us wanting to write HoloLens applications in F#, since applications for HoloLens have to be UWP apps for the Windows Store.

This is a big deal. The HoloLens platform is going to be a huge draw of new developers to the Microsoft community; people who want to be on the cutting edge want to use cutting-edge tools. In the most recent Stack Overflow poll of developers, F# came out the third most loved programming language, behind Rust and Swift. I can believe it. Programming in F# makes me happy.

I was overjoyed to discover that there is a fairly straightforward way to write 3D HoloLens applications in F#, as long as you’re using the Unity 3D game engine. Unity comes with two “scripting backends” that incorporate developers’ .NET code into a Unity3D app. One of these scripting backends is called “IL2CPP.” When it is used, the IL in .NET assemblies used by the Unity project — including F# assemblies — is translated into C++, which is then compiled to .NET native code. Unity has said that IL2CPP is the future of scripting in Unity.

To use IL2CPP for Windows Store apps, you have to be using Unity on Windows, and you have to have the IL2CPP scripting back end installed. (It’s one of the options when you install Unity). Then, in Build Settings > Player Settings choose the Settings for Windows Store tab and look under Other Settings > Configuration > Scripting Backend and select IL2CPP.

To code in F# for Unity, the basic idea is that you compile your F# code into a DLL (targeting .NET 3.5), and then have a post-build step copy the DLL and the FSharp.Core DLL into the Assets\Plugins folder in the Unity project. The classes inside the DLL show up in the project window and can be dragged onto Unity components just like scripts. (For more details, see Jackson Dunstan’s tutorial.)

The GitHub thread mentioned above says that one of the blocks to getting F# support for UWP is that tail call optimization isn’t supported by .NET Native. What happens when we instead translate the IL to C++ using IL2CPP? I tested this tail call to see what would happen:

 let rec callTailRecursiveFunction index =
       if index  callTailRecursiveFunction

IL2CPP turns it into this:

extern "C" void MyClass_callTailRecursiveFunction_m1362434375 (MyClass_t1938649317 * __this, int32_t ___index0, const MethodInfo* method)
  {
  IL_0000:
    {
       int32_t L_0 = ___index0;
       if ((((int32_t)L_0) > ((int32_t)0)))
       {
         goto IL_0006;
       }
     }
     {
       return;
     }

  IL_0006:
     {
       int32_t L_1 = ___index0;
       ___index0 = ((int32_t)((int32_t)L_1-(int32_t)1));
       __this = __this;
       goto IL_0000;
     }
   }

Which seems to indicate that, in this case at least, tail calls are optimized.

I haven’t done exhaustive testing so there may be other aspects of F# IL that IL2CPP has trouble with. But I have been able to get a small demo app running with the scripts all in F#.

Hopefully full UWP support for F# is not far off. But it’s great that the Unity folks have made it possible for us to be writing HoloLens apps in F# right now.

Advertisements

9 thoughts on “Yes, Virginia, You Can Write HoloLens Apps in F#

  1. The IL form of callTailRecursiveFunction will not contain tail calls. In the IL there will be loop similar to the C++ fragment shown. To get the real tail call in F#, you should call different function in the tail position while tail call optimization enabled in the compiler, and as far as I know, neither of these functions needs to be recursive.

    Like

    1. I was following you until the end — my understanding is that a tail call is a type of recursive call, and even if you have mutually recursive calls in F# you need to label them with the rec keyword. Could you explain what you mean by calling a different function in the tail position being a tail call?

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s