Mark Needham

Thoughts on Software Development

Coding: The Kestrel

with 4 comments

Reg Braithwaite has a cool series of posts where he covers the different combinators from Raymond Smullyan’s ‘To Mock a Mockingbird’ book and one of my favourites is the ‘Kestrel’ or ‘K Combinator’ which describes a function that returns a constant function.

It’s described like so:

Kxy = x

The Kestrel function would take in 2 arguments and return the value of the first one. The second argument would probably be a function that takes in the first argument and then performs some side effects with that value.

Braithwaite descirbes the ‘returning’ function from Rails as an example of this combinator whereby instead of writing code like this:

def registered_person(params = {})
  person = Person.new(params.merge(:registered => true))
  Registry.register(person)
  person.send_email_notification
  person
end

We can write this:

def registered_person(params = {})
  returning Person.new(params.merge(:registered => true)) do |person|
    Registry.register(person)
    person.send_email_notification
  end
end

i.e. we can group all the side effects together and it’s more obvious to the reader that we’re returning the value of ‘Person.new(…)’ from this method.

I’ve been writing a bit of code in F# to generate some test objects and I realised that I had code like this in a few places:

let build (t:Type) =
      let theType = Activator.CreateInstance(t)
      theType.GetType().GetProperties() |> Array.iter (fun p -> p.SetValue(t, createValueFor p, null))
      theType

We’re creating ‘theType’ and then mutating it straight away using reflection before returning the value.

We can implement a ‘returning’ function like so to simplify the code a little:

let returning t f = f(t); t
let build (t:Type) =
    returning (Activator.CreateInstance(t)) (fun t -> 
        t.GetType().GetProperties() |> Array.iter (fun p -> p.SetValue(t, createValueFor p, null)))

I think this is the same as what Martin Fowler refers to as a nested closure and it seems quite a neat way of encapsulating side effects and making the code a bit more expressive.

Be Sociable, Share!

Written by Mark Needham

May 3rd, 2010 at 12:28 am

Posted in Coding

Tagged with

  • Christian Blunden

    hmmm interesting… should be able to use this in Yadic 😉

  • Pingback: F#: The Kestrel Revisited at Mark Needham()

  • Pingback: Tweets that mention Coding: The Kestrel at Mark Needham -- Topsy.com()

  • I’m going to write something a bit controversial but we can also take advantage of the return values of the side effecting methods. They usually return void, why don’t they return something useful?

    Then you could imagine something like:

    def registered_person(params = {})
    Registry.register(Person.new(params.merge(:registered => true))).
    send_email_notification
    end

    This is more difficult to do with your second example but it can be argued that it’s a violation of data encapsulation when you take apart your Activator object properties to modify them. After a bit of encapsulation you can write:

    let build (t:Type) =
    Activator.CreateInstance(t).initializeProperties()

    or

    let build (t:Type) =
    Activator.CreateInstance(t).initializeProperties(
    (fun p -> p.SetValue(t, createValueFor p, null)))

    if you really need to pass a specific init function.

    Eric.