Los Techies : Blogs about software and anything tech!

Functionally dynamic?


I was just playing with this tonight, but I don’t know it’s worth anything.  I thought of it after some conversations with Matt Podwysocki back at KaizenConf on how do apply some functional ideas in C#.  First, I started with a simple class:

public class OriginalProduct
{
    public decimal Price { get; set; }
    public decimal Cost { get; set; }

    public decimal CalculateProfit()
    {
        return Price - Cost;
    }
}

To do anything interesting, functional-wise, like swapping implementations or doing things like decorators is annoying or impossible.  But if I went this (albeit weird) direction:

public class Product
{
    public decimal Price { get; set; }
    public decimal Cost { get; set; }

    public Product()
    {
        CalculateProfit = calculateProfit;
    }

    public Func<decimal> CalculateProfit { get; set; }

    private decimal calculateProfit()
    {
        Console.WriteLine("Calculating profit");
        return Cost == 0 ? 0m : Price - Cost;
    }
}

Yes, weird.  But tests look rather normal, except a function is a property:

[Test]
public void No_change()
{
    var product = new Product {Price = 11, Cost = 10};

    product.CalculateProfit().ShouldEqual(1m);
}

Because you can invoke delegate instances directly, it looks like I’m calling a function on the type.  I can do some interesting things with some simple decorator extensions:

public static class DelegateExtensions
{
    public static Func<T> Before<T>(this Func<T> func, Action before)
    {
        return () =>
                   {
                       before();
                       return func();
                   };
    }
    public static Func<T> After<T>(this Func<T> func, Action after)
    {
        return () =>
                   {
                       T value = func();
                       after();
                       return value;
                   };
    }
}

And now I can decorate my the functions at will:

[Test]
public void Decorator_fun()
{
    var product = new Product { Price = 11, Cost = 10 };

    product.CalculateProfit =
        product.CalculateProfit
                .Before(() => Console.WriteLine("Before"))
                .After(() => Console.Write("After"));

    product.CalculateProfit().ShouldEqual(1m);
}

This outputs:

Before
Calculating profit
After
1 passed, 0 failed, 0 skipped, took 1.05 seconds.

That’s just some simple decorator implementation.  Finally, I can swap out implementations at runtime:

[Test]
public void Straight_up_replacement()
{
    var product = new Product { Price = 11, Cost = 10 };

    product.CalculateProfit = () => 1500;

    product.CalculateProfit().ShouldEqual(1500m);
}

It’s still not dynamic typing, as I can’t add new members at runtime.  I have no idea if this is useful or not, as the structure is rather weird, and you’d need to do some interesting things to get polymorphism in play.  But, it might have some interesting applications in some strange scenario.

Kick It on DotNetKicks.com
Posted Nov 19 2008, 09:41 PM by bogardj
Filed under:

Comments

DotNetKicks.com wrote Functionally Dynamic?
on 11-20-2008 2:50 AM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Tobin Harris wrote re: Functionally dynamic?
on 11-20-2008 3:25 AM

The first thing I thought when I saw this was "stragety". I can see me using that as simple way of implementing the strategy pattern in .NET.

The syntax is a bit weird, so perhaps you could separate the Func<> get/set and still have a CalculateCost() method that delegates to the strategy.

Dew Drop - November 20, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - November 20, 2008 | Alvin Ashcraft's Morning Dew
on 11-20-2008 9:09 AM

Pingback from  Dew Drop - November 20, 2008 | Alvin Ashcraft's Morning Dew

derick.bailey wrote re: Functionally dynamic?
on 11-20-2008 9:41 AM

Wow - that's pretty darn cool, Jimmy. Nice combination of features in C#.

You should have posted this as a PTOM post for the Decorator pattern, though. :)

Steve Burman wrote re: Functionally dynamic?
on 11-20-2008 4:31 PM

OT

Los Techies has 58,393,000 subscribers!! Really?!?

*stats by Feedburner

bogardj wrote re: Functionally dynamic?
on 11-20-2008 5:40 PM

@Steve

Ha! No way! LT doesn't have the clout!

I, on the other hand, do have the clout.  That's my fake feedcount.  I need the daily ego boost.

Reflective Perspective - Chris Alcock » The Morning Brew #228 wrote Reflective Perspective - Chris Alcock &raquo; The Morning Brew #228
on 11-21-2008 2:29 AM

Pingback from  Reflective Perspective - Chris Alcock  » The Morning Brew #228

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:
Copyright Los Techies 2008, 2009. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems