fun-ny Faces : Face-based Augmented Reality with F# and the iPhone X

fun-ny Faces : Face-based Augmented Reality with F# and the iPhone X

Each year, the F# programming community creates an advent calendar of blog posts, coordinated by Sergey Tihon on his blog. This is my attempt to battle Impostor Syndrome and share something that might be of interest to the community, or at least amusing…

I was an Augmented Reality (AR) skeptic until I began experimenting with iOS 11’s ARKit framework. There’s something very compelling about seeing computer-generated imagery mapped into your physical space.

A feature of the iPhone X is the face-tracking sensors on the front side of the phone. While the primary use-case for these sensors is unlocking the phone, they additionally expose the facial geometry (2,304 triangles) to developers. This geometry can be used to create AR apps that place computer-generated geometry on top of the facial geometry at up to 60FPS.

Getting Started

In Visual Studio for Mac, choose “New solution…” and “Single-View App” for F#:

The resulting solution is a minimal iOS app, with an entry point defined in Main.fs, a UIApplicationDelegate in AppDelegate.fs, and a UIViewController in ViewController.fs. The iOS programming model is not only object-oriented but essentially a Smalltalk-style architecture, with a classic Model-View-Controller approach (complete with frustratingly little emphasis on the “Model” part) and a delegate-object pattern for customizing object life-cycles.

Although ARKit supports low-level access, by far the easiest way to program AR is to use an ARSCNView, which automatically handles the combination of camera and computer-generated imagery. The following code creates an ARSCNView, makes it full-screen (arsceneview.Frame ← this.View.Frame) and assigns it’s Delegate property to an instance of type ARDelegate (discussed later). When the view is about to appear, we specify that AR session should use an ARFaceTrackingConfiguration and that it should Run:

[<register ("ViewController")>]
type ViewController (handle:IntPtr) =
    inherit UIViewController (handle)

    let mutable arsceneview : ARSCNView = new ARSCNView()

    let ConfigureAR() = 
       let cfg = new ARFaceTrackingConfiguration()
       cfg.LightEstimationEnabled < - true
       cfg

    override this.DidReceiveMemoryWarning () =
      base.DidReceiveMemoryWarning ()

    override this.ViewDidLoad () =
      base.ViewDidLoad ()

      match ARFaceTrackingConfiguration.IsSupported with
      | false -> raise < | new NotImplementedException() 
      | true -> 
        arsceneview.Frame < - this.View.Frame
        arsceneview.Delegate <- new ARDelegate (ARSCNFaceGeometry.CreateFaceGeometry(arsceneview.Device, false))
        //arsceneview.DebugOptions <- ARSCNDebugOptions.ShowFeaturePoints + ARSCNDebugOptions.ShowWorldOrigin

        this.View.AddSubview arsceneview

    override this.ViewWillAppear willAnimate = 
        base.ViewWillAppear willAnimate

        // Configure ARKit 
        let configuration = new ARFaceTrackingConfiguration()

        // This method is called subsequent to `ViewDidLoad` so we know arsceneview is instantiated
        arsceneview.Session.Run (configuration , ARSessionRunOptions.ResetTracking ||| ARSessionRunOptions.RemoveExistingAnchors)


Once the AR session is running, it adds, removes, and modifies ARSCNNode objects that bridge the 3D scene-graph architecture of iOS’s SceneKit with real-world imagery. As it does so, it calls various methods of the ARSCNViewDelegate class, which we subclass in the previously-mentioned ARDelegate class:

// Delegate object for AR: called on adding and updating nodes
type ARDelegate(faceGeometry : ARSCNFaceGeometry) =
   inherit ARSCNViewDelegate()

   // The geometry to overlay on top of the ARFaceAnchor (recognized face)
   let faceNode = new Mask(faceGeometry)

   override this.DidAddNode (renderer, node, anchor) = 
      match anchor <> null && anchor :? ARFaceAnchor with 
      | true -> node.AddChildNode faceNode
      | false -> ignore()   

   override this.DidUpdateNode (renderer, node, anchor) = 

      match anchor <> null && anchor :? ARFaceAnchor with 
      | true -> faceNode.Update (anchor :?> ARFaceAnchor)
      | false -> ignore()


As you can see in DidAddNode and DidUpdateNode, we’re only interested when an ARFaceAnchor is added or updated. (This would be a good place for an active pattern if things got more complex.) As it’s name implies, an ARFaceAnchor relates the AR subsystems’ belief of a face’s real-world location and geometry with SceneKit values.

The Mask class is the last piece of the puzzle. We define it as a subtype of SCNNode, which means that it can hold geometry, textures, have animations, and so forth. It’s passed an ARSCNFaceGeometry which was ultimately instantiated back in the ViewController (new ARDelegate (ARSCNFaceGeometry.CreateFaceGeometry(arsceneview.Device, false)). As the AR subsystem recognizes face movement and changes (blinking eyes, the mouth opening and closing, etc.), calls to ARDelegate.DidUpdateNode are passed to Mask.Update, which updates the geometry with the latest values from the camera and AR subsystem:

member this.Update(anchor : ARFaceAnchor) =
    let faceGeometry = this.Geometry :?> ARSCNFaceGeometry

    faceGeometry.Update anchor.Geometry

While SceneKit geometries can have multiple SCNMaterial objects and every SCNMaterial multiple SCNMaterialProperty values, we can make a simple red mask with :

let mat = geometry.FirstMaterial
mat.Diffuse.ContentColor <- UIColor.Red // Basic: single-color mask

Or we can engage in virtual soccer-hooligan face painting with mat.Diffuse.ContentImage ← UIImage.FromFile "fsharp512.png" :

facepaint

The real opportunity here is undoubtedly for makeup, “face-swap,” and plastic surgery apps, but everyone also loves a superhero. The best mask in comics, I think, is that of Watchmen’s Rorschach, which presented ambiguous patterns matching the black-and-white morality of its wearer, Walter Kovacs.

We can set our face geometry’s material to an arbitrary SKScene SpriteKit animation with mat.Diffuse.ContentScene ← faceFun // Arbitrary SpriteKit scene.

I’ll admit that so far I have been stymied in my attempt to procedurally-generate a proper Rorschach mask. The closest I have gotten is a function that uses 3D Improved Perlin Noise that draws black if the texture is negative and white if positive. That looks like this:

Which is admittedly more Let That Be Your Last Battlefield than Watchmen.

Other things I’ve considered for face functions are: cellular automata, scrolling green code (you know, like the hackers in movies!), and the video feed from the back-facing camera. Ultimately though, all of that is just warm-up for the big challenge: deformation of the facial geometry mesh. If you get that working, I’d love to see the code!

All of my code is available on Github.

Tracking Apple Pencil angles and pressure with Xamarin

Rumor has it that Apple will support the Apple Pencil in the forthcoming iPad. If so, more developers will want to use the new features of UITouch — force, angle, and elevation — supported by the incredibly-precise stylus.

Basically, it’s trivial:

— Force is UITouch.Force;
— Angle is UITouch.GetAzimuthAngle(UIView); and
— Angle above horizontal is UITouch.AltitudeAngle

(The UIView objects are there, I think, to make it easier to create a custom angular transform that is more natural to the task at hand — i.e., an artist could “rotate” the page slightly to accommodate the angle with which they like to work. I think.)

Anyhow, here’s some code:

[code lang=”fsharp”]

namespace UITouch0

open System
open UIKit
open Foundation
open System.Drawing
open CoreGraphics

type ContentView(color : UIColor) as this =
inherit UIView()
do this.BackgroundColor <- color

let MaxRadius = 200.0
let MaxStrokeWidth = nfloat 10.0

//Mutable!
member val Circle : (CGPoint * nfloat * nfloat * nfloat ) option = None with get, set

member this.DrawTouch (touch : UITouch) =
let radius = (1.0 – (float touch.AltitudeAngle) / (Math.PI / 2.0)) * MaxRadius |> nfloat
this.Circle <- Some (touch.LocationInView(this), radius, touch.GetAzimuthAngle(this), touch.Force)
this.SetNeedsDisplay()

override this.Draw rect =

match this.Circle with
| Some (location, radius, angle, force) ->
let rectUL = new CGPoint(location.X – radius, location.Y – radius)
let rectSize = new CGSize(radius * (nfloat 2.0), radius * (nfloat 2.0))
use g = UIGraphics.GetCurrentContext()
let strokeWidth = force * MaxStrokeWidth
g.SetLineWidth(strokeWidth)
let hue = angle / nfloat (Math.PI * 2.0)
let color = UIColor.FromHSB(hue, nfloat 1.0, nfloat 1.0)
g.SetStrokeColor(color.CGColor)
g.AddEllipseInRect <| new CGRect(rectUL, rectSize)
g.MoveTo (location.X, location.Y)
let endX = location.X + nfloat (cos(float angle)) * radius
let endY = location.Y + nfloat (sin(float angle)) * radius
g.AddLineToPoint (endX, endY)
g.StrokePath()
| None -> ignore()

type SimpleController() =
inherit UIViewController()
override this.ViewDidLoad() =
this.View <- new ContentView(UIColor.Blue)

override this.TouchesBegan(touches, evt) =
let cv = this.View :?> ContentView

touches |> Seq.map (fun o -> o :?> UITouch) |> Seq.iter cv.DrawTouch

override this.TouchesMoved(touches, evt) =
let cv = this.View :?> ContentView
touches |> Seq.map (fun o -> o :?> UITouch) |> Seq.iter cv.DrawTouch

[<Register("AppDelegate")>]
type AppDelegate() =
inherit UIApplicationDelegate()
let window = new UIWindow(UIScreen.MainScreen.Bounds)

override this.FinishedLaunching(app, options) =
let viewController = new SimpleController()
viewController.Title <- "F# Rocks"
let navController = new UINavigationController(viewController)
window.RootViewController <- navController
window.MakeKeyAndVisible()
true

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

[/code]

And it looks like this:

TideMonkey: Development Diary 0

I am publicly committing to developing “TideMonkey,” a tide-prediction application that will run on (at least) iOS and watchOS.

TideMonkey will be based on Xtide, an excellent piece of software developed by David Flater. At the moment, my hope is that it will be a very loose port, or what Flater refers to as a “non-port” that reuses the harmonics files of Xtide but is otherwise only loosely based on the source code. On the other hand, I know virtually nothing about the domain, so it is likely that I will have to hew pretty closely to Xtide’s algorithms, at least initially. Ideally I would like to be able to plugin different algorithms and compare their results with the canonical Xtide. Neural nets are a particular interest of mine and one would think that a harmonic series would be the type of thing that one could successfully train (if this ever happens, it won’t be for months and months and months).

I am battling the urge to dive right into coding. Instead, I know that I will be happy by investing in:

  • automation, and
  • testing, and
  • continuous integration

All of which argues for me to begin my journey by getting Xtide, which is written in C++, up and running in a CI server. For no particular reason (but it’s free for personal use) I’ve chosen to use TeamCity for my CI server.


Hmm…

There are several Xtide ports on Github to iOS or Android. The first one I tried was last updated in 2013 and doesn’t run on iOS 9 (it looks like a simple permissions issue, but it doesn’t run “straight from the cloud” and I don’t know if I want to deal with a port rather than just go with the original “straight from the horse’s mouth” Xtide source.

At the moment, I think I’ll work all inside the single “TideMonkey” Github repo. I’ll have to check license restrictions on that, and I don’t know how it will work out once the project structure starts to become more complicated, with testing and mobile development as part of it.

Still,

Creating TideMonkey Github report

MIT License

TideMonkey repo

Programming WatchKit with F#

Disclaimer: This is just a hack. I’m not in any position to make announcements about stuff, but Xamarin loves F# and I’m sure that better solutions than this are forthcoming. But this was fun to get running, so…

Xamarin just released it’s Preview of Watch Kit support and naturally, I had to see if it was possible to use F# to program the forthcoming Apple Watch. Yes, it is.

As always with Watch Kit Apps, the Xamarin solution consists of three projects:

  1. A Parent app that is a normal iOS app;
  2. An Extension that runs on a connected iPhone and executes the program logic; and
  3. A Watch App that runs on the Watch and is essentially a remote display for the Extension App

You can read much more about this at Xamarin’s Watch Kit Documentation site.

To create an F# Watch solution, first create an F#-based Parent App. Then, add the Extension project to that app, an F#-based Custom Keyboard Extension. Finally, add a Watch App from the C#/iOS/Unified/Apple Watch solution template.

The Watch App consists only of a storyboard and resources. It doesn’t actually have any C# (or F#) code in it.

Follow these instructions to [set project references and identifiers].

Switching the Extension from Custom Keyboard to Watch Kit

You will have to manually edit the info.plist of the Watch Extension:

  • In NSExtension, switch the NSExtensionPointIdentifier to com.apple.watchkit; and
  • Under NSExtensionAttributes, add a WKAppBundleIdentifier key to the identifier of your Watch App (e.g., com.xamarin.FWatch1.watchkitapp)

Screenshot 2015-01-21 15.02.07

Now you can get rid of the template F# code and replace it with something like this:

[code lang=”fsharp”]
namespace WatchX

open System
open UIKit
open Foundation
open WatchKit

type InterfaceController(ip : IntPtr) =
inherit WKInterfaceController(ip)

override this.Awake (context) =
System.Console.WriteLine("Hello F#")
this.myLabel.SetText("F# |> I ♡")
[/code]

Again, this is covered in much more detail in Xamarin’s docs, but every scene in the Watch App’s storyboard is backed by a subtype of WKInterfaceController. Since it’s loaded from a Storyboard, it uses the constructor that takes an IntPtr. The Awake method is called when the controller is instantiated.

The Hacky Part

Xamarin has not yet released designer support for Watch Kit, so for now, you need to edit your Watch App’s Storyboard in XCode Interface Builder.

That’s not the hacky part.

Once you’ve designed your UI, you have to hand-edit the Storyboard XML, adding connections elements that define your outlets (properties) and actions (event-handlers). You have to set the destination attribute to refer to the id of the associated control:

Screenshot 2015-01-21 15.37.52

But really, that’s the only ugly part! ;-)

Back in your Extension app, you now have to use attributes to link up your F# code with elements within the Storyboard. The RegisterAttribute on your WKInterfaceController links to the customClass attribute of the controller element, and the name of your OutletAttribute properties must correspond to the property attribute of the outlet elements. Finally, the selector attribute of your action elements must have a corresponding ActionAttribute :

[code lang=”fsharp”]
namespace WatchX

open System
open UIKit
open Foundation
open WatchKit

[<register ("InterfaceController")>]
type InterfaceController(ip : IntPtr) =
inherit WKInterfaceController(ip)

let mutable label : WKInterfaceLabel = null
let mutable button : WKInterfaceButton = null

let mutable clickCount = 0

[<outlet>]
member this.myLabel with get() = label
member this.myLabel with set(v) = label < – v

[<Outlet>]
member this.myButton with get() = button
member this.myButton with set(v) = button < – v

[<Action("OnButtonPress")>]
member this.OnButtonPush () =
clickCount < – clickCount + 1
sprintf "Pressed %d times" clickCount
|> this.myLabel.SetText

override this.Awake (context) =
System.Console.WriteLine("Hello F#")
this.myLabel.SetText("F# |> I ♡")

[/code]

And that’s really all there is to putting F# on your wrist!

Github project

Xamarin.Forms Programming in F#

Things are kind of busy what with Evolve being only 40 days away and iOS 8 coming down the pipe, but I thought I’d share the easy hack that allows you to program Xamarin.Forms with F#.

(Of course, Xamarin loves F# and official support and templates and documentation and all that sort of stuff is forthcoming. This is just something you can do for the moment to begin exploring Xamarin.Forms with F#.)

tl;dr: Use the beta PCL 78 F# Core and link to the facade assemblies for monotouch

OK, so assuming that was a bit too brief…

In Xamarin.Studio create a “New solution…” of type F#/iOS/iPhone/Empty Project…

Open the “References” folder and delete the existing reference to Fsharp.core.dll.

Right-click the solution and select “Add Packages…”

Screenshot 2014-08-27 15.42.39

 

In the NuGet dialog, select “Show pre-release packages” and type FSharp.Core into the search box. This should allow you to add the “FSharp.Core Mono delay signed” package.

Screenshot 2014-08-27 15.25.05Also, add the Xamarin.Forms package:

Screenshot 2014-08-27 15.46.26

And now the tricky part!  You have to add references to the System.ObjectModel.dll and System.Runtime.dlls from the monotouch facade assemblies by hand.

Right-click on the References folder, Select “Edit…”, and select “.NET Assembly”. Add references to System.ObjectModel.dll and System.Runtime.dll from, in my case:

/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/Facades/

Your path may be a little different.

Write a Xamarin.Forms app in 36 lines of code :

[code lang=”csharp”]

namespace FSXF1

open System
open MonoTouch.UIKit
open MonoTouch.Foundation
open Xamarin.Forms

type App = class
static member GetMainPage =
let lbl = new Label()
lbl.Text <- "Hello, F# Xam.Forms!"
lbl.VerticalOptions <- LayoutOptions.CenterAndExpand
lbl.HorizontalOptions <- LayoutOptions.CenterAndExpand

let cp = new ContentPage()
cp.Content <- lbl
cp
end

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

member val Window = null with get, set

// This method is invoked when the application is ready to run.
override this.FinishedLaunching(app, options) =
this.Window <- new UIWindow(UIScreen.MainScreen.Bounds)
Forms.Init()
this.Window.RootViewController <- App.GetMainPage.CreateViewController()
this.Window.MakeKeyAndVisible()
true

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

And you’re good to go!

Screenshot 2014-08-25 10.16.14

 

P.S. If it helps: https://github.com/lobrien/HelloXamarinFormsFSharp

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:

[code lang=”fsharp”]
#if run_with_bin_sh
exec fsharpi –exec $0 $*
#endif
printfn "%A" fsi.CommandLineArgs
[/code]

To add references, use #r:

[code lang=”fsharp”]
#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…
[/code]

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:

[code lang=”fsharp”]
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

[/code]

IMG_0272

photo

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:

[code lang=”fsharp”]
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
[/code]

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

contentview