Is Specification Pattern Pointless? - c#

I'm just wondering if Specification pattern is pointless, given following example:
Say you want to check if a Customer has enough balance in his/her account, you would create a specification something like:
new CustomerHasEnoughMoneyInTheirAccount().IsSatisfiedBy(customer)
However, what I'm wondering is I can achieve the same "benefits" of Specification pattern (such as only needing to change the business rules in on place) by using Property getter in the Customer class like this:
public class Customer
{
public double Balance;
public bool HasEnoughMoney
{
get { return this.Balance > 0; }
}
}
From client code:
customer.HasEnoughMoney
So my question really is; what is the difference between using the property getter to wrap the business logic, and creating Specification class?
Thank you all in advance!

In the general sense, a Specification object is just a predicate wrapped up in an object. If a predicate is very commonly used with a class, it might make sense to Move Method the predicate into the class it applies to.
This pattern really comes into its own when you're building up something more complicated like this:
var spec = new All(new CustomerHasFunds(500.00m),
new CustomerAccountAgeAtLeast(TimeSpan.FromDays(180)),
new CustomerLocatedInState("NY"));
and passing it around or serializing it; it can make even more sense when you're providing some sort of "specification builder" UI.
That said, C# provides more idiomatic ways to express these sorts of things, such as extension methods and LINQ:
var cutoffDate = DateTime.UtcNow - TimeSpan.FromDays(180); // captured
Expression<Func<Customer, bool>> filter =
cust => (cust.AvailableFunds >= 500.00m &&
cust.AccountOpenDateTime >= cutoffDate &&
cust.Address.State == "NY");
I've been playing around with some experimental code that implements Specifications in terms of Expressions, with very simple static builder methods.
public partial class Customer
{
public static partial class Specification
{
public static Expression<Func<Customer, bool>> HasFunds(decimal amount)
{
return c => c.AvailableFunds >= amount;
}
public static Expression<Func<Customer, bool>> AccountAgedAtLeast(TimeSpan age)
{
return c => c.AccountOpenDateTime <= DateTime.UtcNow - age;
}
public static Expression<Func<Customer, bool>> LocatedInState(string state)
{
return c => c.Address.State == state;
}
}
}
That said, this is a whole load of boilerplate that doesn't add value! These Expressions only look at public properties, so one could just as easily use a plain old lambda! Now, if one of these Specifications needs to access non-public state, we really do need a builder method with access to non-public state. I'll use lastCreditScore as an example here.
public partial class Customer
{
private int lastCreditScore;
public static partial class Specification
{
public static Expression<Func<Customer, bool>> LastCreditScoreAtLeast(int score)
{
return c => c.lastCreditScore >= score;
}
}
}
We also need a way to make a composite of these Specifications - in this case, a composite that requires all children to be true:
public static partial class Specification
{
public static Expression<Func<T, bool>> All<T>(params Expression<Func<T, bool>>[] tail)
{
if (tail == null || tail.Length == 0) return _0 => true;
var param = Expression.Parameter(typeof(T), "_0");
var body = tail.Reverse()
.Skip(1)
.Aggregate((Expression)Expression.Invoke(tail.Last(), param),
(current, item) =>
Expression.AndAlso(Expression.Invoke(item, param),
current));
return Expression.Lambda<Func<T, bool>>(body, param);
}
}
I guess part of the downside to this is it can result in complicated Expression trees. For example, constructing this:
var spec = Specification.All(Customer.Specification.HasFunds(500.00m),
Customer.Specification.AccountAgedAtLeast(TimeSpan.FromDays(180)),
Customer.Specification.LocatedInState("NY"),
Customer.Specification.LastCreditScoreAtLeast(667));
produces an Expression tree that looks like this. (These are slightly formatted versions of what ToString() returns when called on the Expression - note that you wouldn't be able to see the structure of the expression at all if you had only a simple delegate! A couple of notes: a DisplayClass is a compiler-generated class that holds local variables captured in a closure, to deal with the upwards funarg problem; and the dumped Expression uses a single = sign to represent equality comparison, rather than C#'s typical ==.)
_0 => (Invoke(c => (c.AvailableFunds >= value(ExpressionExperiment.Customer+Specification+<>c__DisplayClass0).amount),_0)
&& (Invoke(c => (c.AccountOpenDateTime <= (DateTime.UtcNow - value(ExpressionExperiment.Customer+Specification+<>c__DisplayClass2).age)),_0)
&& (Invoke(c => (c.Address.State = value(ExpressionExperiment.Customer+Specification+<>c__DisplayClass4).state),_0)
&& Invoke(c => (c.lastCreditScore >= value(ExpressionExperiment.Customer+Specification+<>c__DisplayClass6).score),_0))))
Messy! Lots of invocation of immediate lambdas and retained references to the closures created in the builder methods. By substituting closure references with their captured values and β-reducing the nested lambdas (I also α-converted all parameter names to unique generated symbols as an intermediate step to simplify β-reduction), a much simpler Expression tree results:
_0 => ((_0.AvailableFunds >= 500.00)
&& ((_0.AccountOpenDateTime <= (DateTime.UtcNow - 180.00:00:00))
&& ((_0.Address.State = "NY")
&& (_0.lastCreditScore >= 667))))
These Expression trees can then be further combined, compiled into delegates, pretty-printed, edited, passed to LINQ interfaces that understand Expression trees (such as those provided by EF), or what have you.
On a side note, I built a silly little micro-benchmark and actually discovered that closure reference elimination had a remarkable performance impact on the speed of evaluation of the example Expression when compiled to a delegate - it cut the evaluation time nearly in half(!), from 134.1ns to 70.5ns per call on the machine I happen to be sitting in front of. On the other hand, β-reduction made no detectable difference, perhaps because compilation does that anyway. In any case, I doubt a conventional Specification class set could reach that kind of evaluation speed for a composite of four conditions; if such a conventional class set had to be built for other reasons such as the convenience of builder-UI code, I think it would be advisable to have the class set produce an Expression rather than directly evaluate, but first consider whether you need the pattern at all in C# - I've seen way too much Specification-overdosed code.

Yes, it is pointless.
The Wikipedia article criticises this pattern at length. But I see the biggest criticism being solely the Inner-Platform Effect. Why re-invent the AND operator? Please be sure to read the Wikipedia article for the complete picture.
Henry, you are correct to assume the Property Get is superior. Why eschew a simpler, well-understood OO concept, for an obscure "pattern" which in its conception doesn't answer your very question? It's an idea, but a bad one. It's an anti-pattern, a pattern that works against you, the coder.
You have asked what is the difference, but a more useful question is, when should a Specification Pattern be used?
Never use this pattern, is my general rule for this pattern.
First, you should realise this pattern isn't based on a scientific theory, it's only an arbitrary pattern someone imagined that uses a particular modeling of classes { Specification, AndSpecification, ...}. With the broader domain-driven theory in mind, you can abandon this pattern, and still have superior options that everyone is familiar with: for instance, well-named objects/methods/properties to model domain language and logic.
Jeffrey said:
a Specification object is just a predicate wrapped up in an object
That's true of domain-driven, but not the Specification Pattern specifically. Jeffrey, comprehensively describes a situation where one may want to dynamically build up an IQueryable expression, so it can efficiently execute on the data store (SQL Database). His final conclusion, is that you can't do that with the Specification Pattern as it's prescribed. Jeffrey's IQueryable expression trees are one alternative way to isolate logical rules and apply them in different composites. As you can see from his example code, it's verbose and very awkward to work with. I can't imagine any situation which would require such dynamic composites either. And if needed, there are many other techniques available which are simpler:-
We all know you should optimise performance last. Attempting here to achieve Bleeding edge with IQueryable expression trees, is a trap. Instead, start with the best tools, a simple and terse Property Getter first. Then test, evaluate and prioritise what work remains.
I am yet to experience a situation where this Specification Pattern is necessary/better. As I do come across supposed situations, I'll list them here and rebut them. If I come across a good situation, I'll revise this answer with a new section.
RE: zerkms answer
Because with the specification class you can create new criterias [sic]
without modification of the objects themselves.
C# already caters for such situations:
Inheritance (in General), where you then extend the inherited class (this is good when you don't own the namespace/library from whence the class comes)
Method Overriding in Inheritence
Partial - great when you have data-model classes. You can add [NotStored] properties alongside, and enjoy all the bliss of accessing the information you need directly off the object. When you press '.' IntelliSense tells you what members are available.
Extension Methods are great when Inheritance is not practical ( architecture doesn't support it ), or if the parent class is sealed.
And these are globally taught ideas that most programmers will already naturally understand and use.
In projects I take over from, I do encounter anti-patterns like Specification Pattern, and more. They're often in a separate Project/Library (over-fragmentation of Projects is another terrible practice) and everyone is too scared to extend objects.
RE: Jeffery Hanton
see https://stackoverflow.com/a/4446254/887092 [2023-01-23]
The use of Expression might be very suitable in many cases. I do still believe that simpler code will work just as well. There a chance it's a little messier, but I believe simplicity needs to come first. Don't confuse the new recruit, otherwise you lock the company needing to hire experts, which are normally in short supply for scaling.
This is his Specification Pattern example:
var spec = new All(new CustomerHasFunds(500.00m),
new CustomerAccountAgeAtLeast(TimeSpan.FromDays(180)),
new CustomerLocatedInState("NY"));
With plain code, it becomes
result = (CustomerSpec.HasFunds(500.0m) &&
CustomerSpec.AccountAgeAtLeast(TimeSpan.FromDays(180)) &&
CustomerSpec.LocatedInState);
If you ever need complexities, like multiple && and some () isolated ||. Then that's what you learn in Computer Science 101. It's also the same across all programming languages (except for syntax).

Because with the specification class you can create new criterias without modification of the objects themselves.

See zerkms answer, plus: a specification can also work on abstract types like interfaces or as a generic making it applicable to a whole range of objects.
Or the check that needs to be done on customer might depend on the context. For example a customer object might not be valid for the pay role system yet, but valid for saving it in the database in the middle of a process for further processing when the user logs in again. With specifications you can build groups of related checks in a centralised location and switch out the entire set depending on context. In this situation you'd combine it with a factory pattern for example.

Related

Functional programming in C#, how can I handle statements like logging, rendering ui, etc?

I read this article : https://learn.microsoft.com/en-us/archive/blogs/ericlippert/foreach-vs-foreach
and the article says:
The first reason is that doing so violates the functional programming principles that all the other sequence operators are based upon. Clearly the sole purpose of a call to this method is to cause side effects. The purpose of an expression is to compute a value, not to cause a side effect. The purpose of a statement is to cause a side effect. The call site of this thing would look an awful lot like an expression (though, admittedly, since the method is void-returning, the expression could only be used in a “statement expression” context.) It does not sit well with me to make the one and only sequence operator that is only useful for its side effects.
but I think I should executes statements (void-returning methods) like logging, rendering user UI, write into physical disk, etc...
cannot this job perform with 'functional' way?
var list = new List<SomeClass>();
var query = list.Where(...).. some 'functional'-feeling combined function chains;
foreach (var log in query)
Console.WriteLine(log); // this is the 'right' way?
query.MyForEach(log => Console.WriteLine(log)); // this works, but violates functional programming principles
To summarize, How can I handle jobs that causes side effects by functional programming principle?
As Simon Peyton Jones once quipped, if all you have is pure functions, the only observable effect of running them would be a hotter CPU, after which a student responded that a hotter CPU is also an observable side effect.
It's clear to everyone doing functional programming that some impure actions have to happen. You have to be able to repaint the screen, write to disk, send bits over the network, take user input, etc.
Functional programming is not about the elimination of impure actions, but it's an explicit goal to minimise them and control where they take place. A common architecture is functional core, imperative shell, which is typically like a sandwich: Gather data from impure sources, pass all the data to pure functions, and do something impure with the result.
In the code sketch given in the OP, you might split it up like this: You'd have a pure function that contains code like this:
var list = new List<SomeClass>();
var query = list.Where(/*...*/) //.. some 'functional'-feeling combined function chains;
Another part of the program - typically the entry point - would call the pure function and decide to do something with it:
foreach (var log in query)
Console.WriteLine(log);
In C# you might as well use foreach as Eric Lippert suggests, since that's the most idiomatic.
You could also use a ForEach extension method. Some people do that, but it makes no difference. Such an action is inherently impure, so it doesn't make it any more or less functional.
I'm not sure I completely agree with Eric Lippert's position, but I acknowledge the argument. Even though, a nice ForEach extension method can sometimes save a line of code.
It's not as though actions like that doesn't exist in Haskell, which has mapM_ and forM_ for exactly such purposes.
Historically, there's been a few failed attempts at figuring out how to best model impure actions in functional programming - particularly in statically typed languages - but for the last few decades, the general solution is to model effects with monads.
Often you can model things in simpler ways by thinking about things differently, but if all else fails, you can always model local state mutation with the State monad.
If you also need to perform I/O (and you always do), Haskell offers the opaque IO monad. You wouldn't use something like IO in C#, but it's interesting to think about what that would look like.
The short answer is 'monads'. The slightly longer answer is a little more nuanced. As another answer here highlights, in Haskell (a pure functional language), it uses the concept of the IO monad to 'push to the edges' any concept of interacting with the outside world.
You can see this in action in the equivalent of Main in Haskell:
main :: IO ()
main = ...
It forces IO on its main function, and so everything produces something (and not just heat).
If we take a step back and consider what 'interacting with the world' means. Let's imagine we had a single value that represented 'the world':
public record World(List<Tree> Trees, List<Cloud> Clouds, ...);
Then imagine that the passage of time is represented by events affecting the state of the World. So, we'd need a method that took an event and gave us a new World:
World OnEvent(World world, Event event);
We can then take a stream of events and model interaction with the World:
var newWorld = events.Aggregate(initialWorld, OnEvent);
This models causality and changes to a 'global' world. OnEvent would then be a method that would fire off lots of pure functions which would transform the old World into a new World.
Obviously unless you're building a world simulator, this is still just a heat generating exercise. But it's an interesting way to think about the IO monad.
The IO monad is effectively the manager of the real world state. It is the thing that's allowed to make changes to the real world - except it's not a World value, it's the actual world that we live in.
In C# we can build our own IO monad. So let's give that a go:
public delegate A IO<A>();
In Haskell, monads are used with do notation:
main :: IO ()
main = do
putStr "What is your name? "
name <- getLine
putStrLn ("Hello " ++ name)
In C# that might look like this:
static IO<Unit> MainIO() =>
from _1 in PutStr("What is your name? ")
from name in GetLine()
from _2 in PutStrLn("Hello " + name)
select default;
To make this work with the IO<A> delegate that we've created, we need to implement Select (aka functor map) and SelectMany (aka monadic bind)
public static class IO
{
// Allows us to lift pure values into the IO domain
public static IO<A> Pure<A>(A value) =>
() => value;
// Functor map
public static IO<B> Select<A, B>(this IO<A> ma, Func<A, B> f) =>
() => f(ma());
// Monadic bind
public static IO<B> SelectMany<A, B>(this IO<A> ma, Func<A, IO<B>> f) =>
() => f(ma())();
// Monadic bind + projection
public static IO<C> SelectMany<A, B, C>(
this IO<A> ma,
Func<A, IO<B>> bind,
Func<A, B, C> project) =>
ma.SelectMany(a => bind(a).Select(b => project(a, b)));
}
Also we need Unit, which is a type that has only one value:
public struct Unit {}
bool has two values: true and false
void has zero values
Unit is in-between with just one value - itself - it's the functional world's void
We can now make the PutStr, PutStrLn, and GetLine functions:
public static class ConsoleIO
{
public static IO<Unit> PutStr(string value) =>
() =>
{
Console.Write(value);
return default;
};
public static IO<Unit> PutStrLn(string value) =>
() =>
{
Console.WriteLine(value);
return default;
};
public static IO<string> GetLine(string value) =>
Console.ReadLine;
}
So, if we go back to our IO monad main function:
static IO<Unit> MainIO() =>
from _1 in ConsoleIO.PutStr("What is your name? ")
from name in ConsoleIO.GetLine()
from _2 in ConsoleIO.PutStrLn("Hello " + name)
select default;
Then we can run it like so:
// This doesn't run the IO
IO<Unit> computation = MainIO();
// This does
var result = computation();
So, running MainIO only produces a data-representation of your program: i.e. it's pure. A program that upon running only creates a data structure (and no other side-effects) must be pure.
The invocation of the computation runs the IO for real. This is why Haskell is called a pure language. Because it produces an IO computation which is then invoked by the runtime of Haskell.
This might seem like a sleight of hand, and to a certain extent it is. It is however true that your code just produces a data structure that is then used to run the real effects. But it is also true that Haskell and all pure functional languages do change the real world, having real world side-effects.
The critical aspect of this is that we now know that IO<Unit> MainIO() has a side-effect. It's there, writ large, in the prototype of the method. That's why in your example of foreach or ForEach is problematic: there's no declaration of any side-effect, it just happens, and we have no idea it happened. Did some logging happen? No idea. Were nuclear weapons launched? No idea.
In Haskell you can't invoke the IO delegate to get the value out (that's done in the runtime), so once you're in an IO context, you can't get out of it. That means a bit like async in C#, once you're in an IO context, it spreads. This is a good thing, as it forces declarative methods and functions throughout your code-base. It also makes mixing of different contexts harder - because it should be. If you're going to drop some IO in the middle of your lovely pure code, then feel the pain of that declaration explosion, and think to yourself: This is the blast radius of how far my single-line-of-code-change has gone. This is the code that I should consider to be affected/impacted. It certainly gives you a different perspective on the impact of what seems like minor changes.
Technically Haskell does allow you to get out of the IO monad using unsafePerformIO, but it's considered bad practice. It is the equivalent of us invoking the IO<A> delegate. We should only invoke it once, in our Main method.
So, what about logging? Or other side-effects. Well there's other types of monad that supports these things, and the different flavours of monad gives different capabilities.
For example, this is the Writer monad - that has an additional capability called Put that allows logging of values from within the expression:
public delegate (A Value, Seq<string> Output) Writer<A>();
public static class Writer
{
public static Writer<A> Pure<A>(A value) =>
() => (value, default);
public static Writer<Unit> Put(string value) =>
() => (default, Seq1(value));
public static Writer<B> Select<A, B>(this Writer<A> ma, Func<A, B> f) =>
() => ma() switch
{
var (value, output) => (f(value), output)
};
public static Writer<B> SelectMany<A, B>(this Writer<A> ma, Func<A, Writer<B>> f) =>
() => ma() switch
{
var (avalue, output1) =>
f(avalue)() switch
{
var (bvalue, output2) => (bvalue, output1 + output2)
}
};
public static Writer<C> SelectMany<A, B, C>(
this Writer<A> ma,
Func<A, Writer<B>> bind,
Func<A, B, C> project) =>
ma.SelectMany(x => bind(x).Select(y => project(x, y)));
}
I'm using Seq - an immutable list - from language-ext - a functional framework for C# (Disclaimer: I'm the author)
We can then do logging in the expression. There's no need to manually manage the log or anything, just call Put with a value and the monad does the rest.
var computation = from x in Writer.Pure(100)
from y in Writer.Pure(200)
from _ in Writer.Put($"The sum is: {x + y}")
select default(Unit);
We can then run the computation
var (value, output) = computation();
Which gives us the result of the expression (in this case Unit) and a Seq<string> of logged entries.
Now for the painful bit:
You can't mix monadic types in LINQ expressions
That doesn't mean you can never switch between monads, you can, but just not in the same LINQ expression - unless there's bespoke overrides for SelectMany
Therefore: you need to build a monad that captures all of the kinds of side-effects you expect to run in any one expression (IO, logging, etc.)
Haskell has a concept of monad-transformers (the ability to combine two monads of different flavours into something more powerful without doing lots of work). We can't do that in C#, although we can manually write extension methods to work with nested monadic types.
Personally I think it's worth the effort:
Your code instantly becomes more declarative
It's possible to bury messy things like state-management, configuration, dependency-injection, logging, IO, optional-values, error-handling, etc. into the monad's bind function (SelectMany) and then never worry about it again - it's true abstraction.
This also means you can change it easily in the future too
So, hopefully that makes it clear? We're not trying to never have side-effects, we're trying to declare side-effects (like we do with async) - and we're trying to make usage of them compositional. Some people really don't like this approach to engineering, especially in C# where it's not considered idiomatic. I happen to think it's the single greatest feature of C# (monad support via LINQ) - it's the closest you can get to pure-functional programming in a language that was never originally designed for it.
To do this style of pure functional programming in C# requires a bit of self-control to not cheat the system. Luckily my language-ext project has done all of the difficult stuff of building a functional framework that helps the inertia of your code go towards more of the pure functional paradigm, rather than the imperative one.
And the wiki has a section on how to deal with side-effects as well as how to think functionally.
And finally, there are some samples of the Eff monad (effect/IO monad), and Aff monad (asynchronous effect/IO monad) in action. They handle: configuration, environment, error-handling, dependency-injection and IO.

What is this kind of chaining in C# called?

Can you please tell me what kind of construct in C# is this.
Code Golf: Numeric equivalent of an Excel column name
C.WriteLine(C.ReadLine()
.Reverse()
.Select((c, i) => (c - 64) * System.Math.Pow(26, i))
.Sum());
Though I am new to C# (only two months exp so far), but since the time I have joined a C# team, I have never seen this kind of chaining. It really attracted me and I want to learn more about it.
Please give some insight about this.
Method chaining like this is often called a fluent interface.
You can make your own fluent interface by implementing functions that return the object they were called on.
For a trivial example:
class Foo
{
private int bar;
public Foo AddBar(int b)
{
bar += b;
return this;
}
}
Which can be used like:
Foo f = new Foo().AddBar(1).AddBar(2);
You could also implement a fluent interface using extension methods.
For example:
class Foo
{
public int Bar { get; set; }
}
static class FooExtensions
{
public static Foo AddBar(this Foo foo, int b)
{
foo.Bar += b;
return foo;
}
}
etc.
Here is a more complex example. Finally, Autofac and CuttingEdge.Conditons are two examples of open-source libraries that have very nice fluent interfaces.
It's little more than a chain of function calls with some indentation, where C calls ReadLine(), whose result is used for Reverse, whose result is used for Select, etc. The functions themselves are part of LINQ, the ones that get used after translating the syntactic sugar. Here's a list of LINQ query functions, along with samples on their use, and here's a tutorial for LINQ.
(In case you're interested: Reverse() returns an IEnumerable that goes from back to front of the given IEnumerable, Select() returns an IEnumerable listing all elements, after applying the given lambda expression, and Sum() simply returns the sum of all the elements of the given IEnumerable.)
There's nothing special about most of the expression, but the select method makes use of lambda expressions, a key component of Language Integrated Query - LINQ, for short.
.NET Language-Integrated Query defines
a set of general purpose standard
query operators that allow traversal,
filter, and projection operations to
be expressed in a direct yet
declarative way in any .NET-based
programming language.
LINQ, and the lambda expressions they use, are a way to write complicated query and manipulation expressions succinctly and readably. It was added to the .NET Framework in 3.5. Here's some more information from MSDN.
The chaining pattern can be called a Fluent Interface. It occurs when an interface's function (or extension method) returns the same interface. In this case, it is IEnumerable.
You also have some LINQ thrown in there with the Select and Sum functions

More fluent C# / .NET

A co-worker of mine came up with this and I wonder what others think? Personally, I find it interesting but wonder if it is too big a departure? Code examples below. Extension methods at the bottom.
General thoughts please. Other extension methods that could be added?
var ddl = Page.FindControl("LocationDropDownList") as DropDownList;
ddl.Visible = true;
ddl.SelectedValue = "123";
if(isAdmin)
ddl .SelectedValue = "111";
Becomes:
Page.FindControl("LocationDropDownList")
.CastAs<DropDownList>()
.With(d => d.Visible = true)
.With(d => d.SelectedValue = "123")
.WithIf(isAdmin, d => d.Items.Add(new ListItem("Admin", "1")));
Or:
Page.FindControl("LocationDropDownList")
.CastAs<DropDownList>()
.With(d =>
{
d.Visible = true;
d.SelectedValue = "123";
})
.WithIf(isAdmin, d => d.SelectedValue = "111");
Extension methods:
public static TResult CastAs<TResult>(this object obj) where TResult : class
{
return obj as TResult;
}
public static T With<T>(this T t, Action<T> action)
{
if (action == null)
throw new ArgumentNullException("action");
action(t);
return t;
}
public static T WithIf<T>(this T t, bool condition, Action<T> action)
{
if (action == null)
throw new ArgumentNullException("action");
if (condition)
action(t);
return t;
}
Amongst my rules of thumb for writing clear code is: put all side effects in statements; non-statement expressions should have no side effects.
Your first version of the program clearly follows this rule. The second version clearly violates it.
An additional thought: if I were to read code like the code you've displayed, I would naturally assume that the purpose of the code was to build up a lazily-evaluated structure which represented those operations -- this is exactly why query comprehensions in C# 3 are built in this way. The result of the query expression is an object representing the deferred application of the query.
If your intention is to capture the notion of "execute these side effects in a deferred manner at a later moment of my choosing", then this is a sensible approach. Essentially what you're building up is a side-effecting monad. If your intention is merely to provide a different syntax for the eagerly executed code, then this is just confusing, verbose and unnecessary.
I see no advantage to this besides being confusing to the reader. With respect to my fellow answerer, I would like to know on what planet this is more readable. As far as I can tell, the first version has more or less perfect readability, whereas this is fairly readable, but makes the reader wonder whether there's some strange magic happening within With and WithIf.
Compared to the first version, it's longer, harder to type, less obvious, and less performant.
I guess I fail to see what the new versions get you. The original is pretty clear and is less wordy. I would guess that it would be faster as well. I would avoid using (abusing?) language features like this unless there is a clear benefit.
One more vote for "not useful". The With extension method doesn't do anything except wrap up sequenced statements with a method. C# already already has a built-in function for sequencing statements, its called ;.
Similarly, the WithIf wraps an if-statement without any modification to the control flow. From my point of view, you're only inviting yourself to methods like:
public static T For<T>(
this T t, int start, Func<int, bool> cond, Action<T, int> f)
{
for(int i = start; cond(i); i++)
{
f(t, i);
}
return t;
}
The original is more readable.
The simplest API change would be to make the object returned by FindControl() a Builder-esque thing (where all the set methods return 'this'):
Page.FindControl("LocationDropDownList")
.setVisible(true)
.setSelectedValue(isAdmin ? "111" : "123");
That is some extension method abuse if I ever saw it!
It's an interesting use of extensions, and I appreciate it on that merit alone. I'm not sure I'd use it, but if your team likes it, then by all means, use it.
They're just different coding styles, what do you mean by "too big a departure"? Departure from what? From what you're used to? Only you can decide that. I will say that VB's With block has done more harm than good to code readability, and I would not try to replicate the behavior in C#, but that's just my preference.
I pretty much always use this for FindControl (yeah, strongly typed to RepeaterItem, it doesn't have to be, but that's the only thing I ever use it for anyway):
public static T FindControl<T>(this RepeaterItem item, string id)
{
return item.FindControl(id) as T;
}
And invoke it like so:
Literal myLiteral = e.Item.FindControl<Literal>("myLiteral");
I am more comfortable with the first version. It takes less time to read and understand. I agree that the extension methods are also fine if you are familiar with it and also familiar with the With method, but what’s the benefit of it in this case?
Minor note. From personal experience, I'd change:
if(isAdmin)
ddl.SelectedValue = "111";
to
if(isAdmin) {
ddl.SelectedValue = "111";
}
or
if(isAdmin)
{
ddl.SelectedValue = "111";
}
This will save you time in debugging sooner or later.
If this was a language feature:
With(Page.FindControl("LocationDropDownList") as DropDownList)
{
Visible = true;
SelectedValue = "123";
if(isAdmin)
Add(new ListItem( "111"));
}
You would win something:
avoid redundancy of the mutated object
all language features available in the "With" block
Above tries to emulate the style without reaping the benefits. Cargo Cult.
(Note: I do understand the various arguments against it, but It'd still be nice)
Incidentally, some of my C++ Win32 UI Helpers contain setters that use chaining similar what you want to achieve:
LVItem(m_lc, idx).SetText(_T("Hello")).SetImg(12).SetLParam(id);
In that case, I least win the "no redundancy", but that's because I don't have properties.
I predict the whole "fluent interface" fad will be the "hungarian notation" of the 2000's. I personally think it doesn't look very clean and it runs the risk of becoming very inconsistent if you have multiple developers each with their own preference.
Looks like your co worker is a Lambda Junkie.
I think the question of readability is subjective and I personally have no issue with what you've done. I would consider using it if your organization "approved" it.
I think the concept is sound and if you changed "With" to "Let" it would be more "functional" or "F#-ish". Personal opinion.
Page.FindControl("LocationDropDownList")
.CastAs<DropDownList>()
.Let(d => d.Visible = true)
.Let(d => d.SelectedValue = "123");
My 2 cents: It looks fine, my only comment is that "With" kind of implies something like "Where" or "Having" when you are actually setting a property. I'd suggest a method name of something like "Do", "Execute" or "Set" but maybe thats just my odd world view.
How about:
Page.WithControl<DropDownList>("LocationDropDownList")
.Do(d => d.Visible = true)
.Do(d => d.SelectedValue = "123")
.DoIf(isAdmin, d => d.Items.Add(new ListItem("Admin", "1")));
I'd say stick with the first version. What you've posted is too clever to be immediately useful to someone reading the code.
You could even go a step further and do away with that "var":
DropDownList ddl = (DropDownList) Page.FindControl("ddlName");
This is a perfect learning case on how to make something more complicated than it needs to be.
The first version is clear and requires no extra knowledge beyond normal language contructs.
I say stick with the first version without the extension methods or lamba expressions. These are relatively new concepts so not many developers will have a handle on them yet outside their use in data retrieval/manipulation from a database. If you use them you may have a hit on maintenance cost. It is nice to say "read up if this is Greek to you"; but in real-life that may be the best approach.
Regarding a "Fluent Interface" C# already has a great syntax for initializers which is (IMHO) better that trying to use the fluent style. Of course, in your example you are not initializing an new object, you are changing an existing one. My whole expertise with Fluent interfaces comes from a 30 second scan of wikipedia, but I think that JeeBee's answer is more in the spirit of Fluent programming, though I might change things slightly:
Page.FindDropDownList("LocationDropDownList")
.setVisible(true)
.setAdminSelectedValue("111")
.setSelectedValue("123")
One could argue that this is more readable, especially for a language without Properties, but I still think it doesn't make sense in C#.
In certain circumstances thoughtfully constructed fluent interfaces can be very useful. First, because the developer is presented with a limited number of options they are (typically) easy to use correctly and difficult to use incorrectly. Second, because of the sentence like structure they can be a nice clean way to declare your intentions, especially when building complex objects.
I have found fluent interfaces to be very useful when developing test code in which it is often necessary to build lots of domain objects with slight variations. I have also used them successfully as a way to introduce the decorator pattern and to eliminate excessive method overloading.
If anyone is interested in learning more about fluent interfaces, I suggest checking out this work in progress by Martin Fowler.
Good rule of thumb:
If your first impression of your code is "This is clever" - it's probably not a good idea.
Good code should be simple, readable, and only "clever" if absolutely necessary.

What fluent interfaces have you made or seen in C# that were very valuable? What was so great about them?

"Fluent interfaces" is a fairly hot topic these days. C# 3.0 has some nice features (particularly extension methods) that help you make them.
FYI, a fluent API means that each method call returns something useful, often the same object you called the method on, so you can keep chaining things. Martin Fowler discusses it with a Java example here. The concept kooks something like this:
var myListOfPeople = new List<Person>();
var person = new Person();
person.SetFirstName("Douglas").SetLastName("Adams").SetAge(42).AddToList(myListOfPeople);
I have seen some incredibly useful fluent interfaces in C# (one example is the fluent approach for validating parameters found in an earlier StackOverflow question I had asked. It blew me away. It was able to give highly readable syntax for expressing parameter validation rules, and also, if there were no exceptions, it was able to avoid instantiating any objects! So for the "normal case", there was very little overhead. This one tidbit taught me a huge amount in a short time. I want to find more things like that).
So, I'd like to learn more by looking at and discussing some excellent examples. So, what are some excellent fluent interfaces you've made or seen in C#, and what made them so valuable?
Thanks.
This is actually the first time I've heard the term "fluent interface." But the two examples that come to mind are LINQ and immutable collections.
Under the covers LINQ is a series of methods, most of which are extension methods, which take at least one IEnumerable and return another IEnumerable. This allows for very powerful method chaining
var query = someCollection.Where(x => !x.IsBad).Select(x => x.Property1);
Immutable types, and more specifically collections have a very similar pattern. Immutable Collections return a new collection for what would be normally a mutating operation. So building up a collection often turns into a series of chained method calls.
var array = ImmutableCollection<int>.Empty.Add(42).Add(13).Add(12);
Kudos for the method parameter validation, you've given me a new idea for our fluent APIs. I've hated our precondition checks anyways...
I've built a extensibility system for a new product in development, where you can fluently describe the commands available, the user interface elements and more. This runs on top of StructureMap and FluentNHibernate, which are nice APIs too.
MenuBarController mb;
// ...
mb.Add(Resources.FileMenu, x =>
{
x.Executes(CommandNames.File);
x.Menu
.AddButton(Resources.FileNewCommandImage, Resources.FileNew, Resources.FileNewTip, y => y.Executes(CommandNames.FileNew))
.AddButton(null, Resources.FileOpen, Resources.FileOpenTip, y =>
{
y.Executes(CommandNames.FileOpen);
y.Menu
.AddButton(Resources.FileOpenFileCommandImage, Resources.OpenFromFile, Resources.OpenFromFileTop, z => z.Executes(CommandNames.FileOpenFile))
.AddButton(Resources.FileOpenRecordCommandImage, Resources.OpenRecord, Resources.OpenRecordTip, z => z.Executes(CommandNames.FileOpenRecord));
})
.AddSeperator()
.AddButton(null, Resources.FileClose, Resources.FileCloseTip, y => y.Executes(CommandNames.FileClose))
.AddSeperator();
// ...
});
And you can configure all commands available like this:
Command(CommandNames.File)
.Is<DummyCommand>()
.AlwaysEnabled();
Command(CommandNames.FileNew)
.Bind(Shortcut.CtrlN)
.Is<FileNewCommand>()
.Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);
Command(CommandNames.FileSave)
.Bind(Shortcut.CtrlS)
.Enable(WorkspaceStatusProviderNames.DocumentOpen)
.Is<FileSaveCommand>();
Command(CommandNames.FileSaveAs)
.Bind(Shortcut.CtrlShiftS)
.Enable(WorkspaceStatusProviderNames.DocumentOpen)
.Is<FileSaveAsCommand>();
Command(CommandNames.FileOpen)
.Is<FileOpenCommand>()
.Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);
Command(CommandNames.FileOpenFile)
.Bind(Shortcut.CtrlO)
.Is<FileOpenFileCommand>()
.Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);
Command(CommandNames.FileOpenRecord)
.Bind(Shortcut.CtrlShiftO)
.Is<FileOpenRecordCommand>()
.Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);
Our view configure their controls for the standard edit menu commands using a service given to them by the workspace, where they just tell it to observe them:
Workspace
.Observe(control1)
.Observe(control2)
If the user tabs to the controls, the workspace automatically gets an appropriate adapter for the control and provides undo/redo and clipboard operations.
It has helped us reduce the setup code dramatically and make it even more readable.
I forgot to tell about a library we're using in our WinForms MVP model presenters to validate the views: FluentValidation. Really easy, really testable, really nice!
I love the fluent interface in CuttingEdge.Conditions.
From their sample:
// Check all preconditions:
id.Requires("id")
.IsNotNull() // throws ArgumentNullException on failure
.IsInRange(1, 999) // ArgumentOutOfRangeException on failure
.IsNotEqualTo(128); // throws ArgumentException on failure
I've found that it is a lot easier to read, and makes me much more effective at checking my preconditions (and post conditions) in methods than when I have 50 if statements to handle the same checks.
Here's one I made just yesterday. Further thought may lead me to change the approach, but even if so, the "fluent" approach let me accomplish something I otherwise could not have.
First, some background. I recently learned (here on StackOverflow) a way to pass a value to a method such that the method would be able to determine both the name and the value. For example, one common use is for parameter validation. For example:
public void SomeMethod(Invoice lastMonthsInvoice)
{
Helper.MustNotBeNull( ()=> lastMonthsInvoice);
}
Note there's no string containing "lastMonthsInvoice", which is good because strings suck for refactoring. However, the error message can say something like "The parameter 'lastMonthsInvoice' must not be null." Here's the post that explains why this works and points to the guy's blog post.
But that is just background. I'm using the same concept, but in a different way. I am writing some unit tests, and I want to dump certain property values out to the console so they show up in the unit test output. I got tired of writing this:
Console.WriteLine("The property 'lastMonthsInvoice' has the value: " + lastMonthsInvoice.ToString());
... because I have to name the property as a string and then refer to it. So I made it where I could type this:
ConsoleHelper.WriteProperty( ()=> lastMonthsInvoice );
And get this output:
Property [lastMonthsInvoice] is: <whatever ToString from Invoice
produces>
Now, here's where a fluent approach allowed me to do something I otherwise couldn't do.
I wanted to make ConsoleHelper.WriteProperty take a params array, so it could dump many such property values to the console. To do that, its signature would look like this:
public static void WriteProperty<T>(params Expression<Func<T>>[] expr)
So I could do this:
ConsoleHelper.WriteProperty( ()=> lastMonthsInvoice, ()=> firstName, ()=> lastName );
However, that doesn't work due to type inference. In other words, all of these expressions do not return the same type. lastMonthsInvoice is an Invoice. firstName and lastName are strings. They cannot be used in the same call to WriteProperty, because T is not the same across all of them.
This is where the fluent approach came to the rescue. I made WriteProperty() return something. The type it returned is something I can call And() on. This gives me this syntax:
ConsoleHelper.WriteProperty( ()=> lastMonthsInvoice)
.And( ()=> firstName)
.And( ()=> lastName);
This is a case where the fluent approach allowed something that otherwise would not have been possible (or at least not convenient).
Here's the full implementation. As I said, I wrote it yesterday. You'll probably see room for improvement or maybe even better approaches. I welcome that.
public static class ConsoleHelper
{
// code where idea came from ...
//public static void IsNotNull<T>(Expression<Func<T>> expr)
//{
// // expression value != default of T
// if (!expr.Compile()().Equals(default(T)))
// return;
// var param = (MemberExpression)expr.Body;
// throw new ArgumentNullException(param.Member.Name);
//}
public static PropertyWriter WriteProperty<T>(Expression<Func<T>> expr)
{
var param = (MemberExpression)expr.Body;
Console.WriteLine("Property [" + param.Member.Name + "] = " + expr.Compile()());
return null;
}
public static PropertyWriter And<T>(this PropertyWriter ignored, Expression<Func<T>> expr)
{
ConsoleHelper.WriteProperty(expr);
return null;
}
public static void Blank(this PropertyWriter ignored)
{
Console.WriteLine();
}
}
public class PropertyWriter
{
/// <summary>
/// It is not even possible to instantiate this class. It exists solely for hanging extension methods off.
/// </summary>
private PropertyWriter() { }
}
In addition to the ones specified here, the popuplar RhinoMocks unit test mock framework uses fluent syntax to specify expectations on mock objects:
// Expect mock.FooBar method to be called with any paramter and have it invoke some method
Expect.Call(() => mock.FooBar(null))
.IgnoreArguments()
.WhenCalled(someCallbackHere);
// Tell mock.Baz property to return 5:
SetupResult.For(mock.Baz).Return(5);
Method Naming
Fluent interfaces lend themselves to readability as long as the method names are chosen sensibly.
With that in mind, I'd like to nominate this particular API as "anti-fluent":
System.Type.IsInstanceOfType
It's a member of System.Type and takes an object, and returns true if the object is an instance of the type. Unfortunately, you naturally tend to read it from left to right like this:
o.IsInstanceOfType(t); // wrong
When it's actually the other way:
t.IsInstanceOfType(o); // right, but counter-intuitive
But not all methods could possibly be named (or positioned in the BCL) to anticipate how they might appear in "pseudo-English" code, so this isn't really a criticism. I'm just pointing out another aspect of fluent interfaces - the choosing of method names in order to cause the least surprise.
Object Initializers
With many of the examples given here, the only reason a fluent interface is being used is so that several properties of a newly allocated object can be initialized within a single expression.
But C# has a language feature that very often makes this unnecessary - object initializer syntax:
var myObj = new MyClass
{
SomeProperty = 5,
Another = true,
Complain = str => MessageBox.Show(str),
};
This perhaps would explain why expert C# users are less familiar with the term "fluent interface" for chaining calls on the same object - it isn't needed quite so often in C#.
As properties can have hand-coded setters, this is an opportunity to call several methods on the newly constructed object, without having to make each method return the same object.
The limitations are:
A property setter can only accept one argument
A property setter cannot be generic
I would like it if we could call methods and enlist in events, as well as assign to properties, inside an object initializer block.
var myObj = new MyClass
{
SomeProperty = 5,
Another = true,
Complain = str => MessageBox.Show(str),
DoSomething()
Click += (se, ev) => MessageBox.Show("Clicked!"),
};
And why should such a block of modifications only be applicable immediately after construction? We could have:
myObj with
{
SomeProperty = 5,
Another = true,
Complain = str => MessageBox.Show(str),
DoSomething(),
Click += (se, ev) => MessageBox.Show("Clicked!"),
}
The with would be a new keyword that operates on an object of some type and produces the same object and type - note that this would be an expression, not a statement. So it would exactly capture the idea of chaining in a "fluent interface".
So you could use initializer-style syntax regardless of whether you'd got the object from a new expression or from an IOC or factory method, etc.
In fact you could use with after a complete new and it would be equivalent to the current style of object initializer:
var myObj = new MyClass() with
{
SomeProperty = 5,
Another = true,
Complain = str => MessageBox.Show(str),
DoSomething(),
Click += (se, ev) => MessageBox.Show("Clicked!"),
};
And as Charlie points out in the comments:
public static T With(this T with, Action<T> action)
{
if (with != null)
action(with);
return with;
}
The above wrapper simply forces a non-returning action to return something, and hey presto - anything can be "fluent" in that sense.
Equivalent of initializer, but with event enlisting:
var myObj = new MyClass().With(w =>
{
w.SomeProperty = 5;
w.Another = true;
w.Click += (se, ev) => MessageBox.Show("Clicked!");
};
And on a factory method instead of a new:
var myObj = Factory.Alloc().With(w =>
{
w.SomeProperty = 5;
w.Another = true;
w.Click += (se, ev) => MessageBox.Show("Clicked!");
};
I couldn't resist giving it the "maybe monad"-style check for null as well, so if you have something that might return null, you can still apply With to it and then check it for null-ness.
SubSonic 2.1 has a decent one for the query API:
DB.Select()
.From<User>()
.Where(User.UserIdColumn).IsEqualTo(1)
.ExecuteSingle<User>();
tweetsharp makes extensive use of a fluent API too:
var twitter = FluentTwitter.CreateRequest()
.Configuration.CacheUntil(2.Minutes().FromNow())
.Statuses().OnPublicTimeline().AsJson();
And Fluent NHibernate is all the rage lately:
public class CatMap : ClassMap<Cat>
{
public CatMap()
{
Id(x => x.Id);
Map(x => x.Name)
.WithLengthOf(16)
.Not.Nullable();
Map(x => x.Sex);
References(x => x.Mate);
HasMany(x => x.Kittens);
}
}
Ninject uses them too, but I couldn't find an example quickly.
I wrote a little fluent wrapper for System.Net.Mail which I find makes it email code much more readable (and easier to remember the syntax).
var email = Email
.From("john#email.com")
.To("bob#email.com", "bob")
.Subject("hows it going bob")
.Body("yo dawg, sup?");
//send normally
email.Send();
//send asynchronously
email.SendAsync(MailDeliveredCallback);
http://lukencode.com/2010/04/11/fluent-email-in-net/
The Criteria API in NHibernate has a nice fluent interface which allows you to do cool stuff like this:
Session.CreateCriteria(typeof(Entity))
.Add(Restrictions.Eq("EntityId", entityId))
.CreateAlias("Address", "Address")
.Add(Restrictions.Le("Address.StartDate", effectiveDate))
.Add(Restrictions.Disjunction()
.Add(Restrictions.IsNull("Address.EndDate"))
.Add(Restrictions.Ge("Address.EndDate", effectiveDate)))
.UniqueResult<Entity>();
The new HttpClient of the WCF REST Starter Kit Preview 2 is a great fluent API. see my blog post for a sample http://bendewey.wordpress.com/2009/03/14/connecting-to-live-search-using-the-httpclient/
As #John Sheehan mentioned, Ninject uses this type of API to specify bindings. Here are some example code from their user guide:
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf();
Bind<Shogun>().ToSelf().Using<SingletonBehavior>();

In C#, What is a monad?

There is a lot of talk about monads these days. I have read a few articles / blog posts, but I can't go far enough with their examples to fully grasp the concept. The reason is that monads are a functional language concept, and thus the examples are in languages I haven't worked with (since I haven't used a functional language in depth). I can't grasp the syntax deeply enough to follow the articles fully ... but I can tell there's something worth understanding there.
However, I know C# pretty well, including lambda expressions and other functional features. I know C# only has a subset of functional features, and so maybe monads can't be expressed in C#.
However, surely it is possible to convey the concept? At least I hope so. Maybe you can present a C# example as a foundation, and then describe what a C# developer would wish he could do from there but can't because the language lacks functional programming features. This would be fantastic, because it would convey the intent and benefits of monads. So here's my question: What is the best explanation you can give of monads to a C# 3 developer?
Thanks!
(EDIT: By the way, I know there are at least 3 "what is a monad" questions already on SO. However, I face the same problem with them ... so this question is needed imo, because of the C#-developer focus. Thanks.)
Most of what you do in programming all day is combining some functions together to build bigger functions from them. Usually you have not only functions in your toolbox but also other things like operators, variable assignments and the like, but generally your program combines together lots of "computations" to bigger computations that will be combined together further.
A monad is some way to do this "combining of computations".
Usually your most basic "operator" to combine two computations together is ;:
a; b
When you say this you mean "first do a, then do b". The result a; b is basically again a computation that can be combined together with more stuff.
This is a simple monad, it is a way of combing small computations to bigger ones. The ; says "do the thing on the left, then do the thing on the right".
Another thing that can be seen as a monad in object oriented languages is the .. Often you find things like this:
a.b().c().d()
The . basically means "evaluate the computation on the left, and then call the method on the right on the result of that". It is another way to combine functions/computations together, a little more complicated than ;. And the concept of chaining things together with . is a monad, since it's a way of combining two computations together to a new computation.
Another fairly common monad, that has no special syntax, is this pattern:
rv = socket.bind(address, port);
if (rv == -1)
return -1;
rv = socket.connect(...);
if (rv == -1)
return -1;
rv = socket.send(...);
if (rv == -1)
return -1;
A return value of -1 indicates failure, but there is no real way to abstract out this error checking, even if you have lots of API-calls that you need to combine in this fashion. This is basically just another monad that combines the function calls by the rule "if the function on the left returned -1, do return -1 ourselves, otherwise call the function on the right". If we had an operator >>= that did this thing we could simply write:
socket.bind(...) >>= socket.connect(...) >>= socket.send(...)
It would make things more readable and help to abstract out our special way of combining functions, so that we don't need to repeat ourselves over and over again.
And there are many more ways to combine functions/computations that are useful as a general pattern and can be abstracted in a monad, enabling the user of the monad to write much more concise and clear code, since all the book-keeping and management of the used functions is done in the monad.
For example the above >>= could be extended to "do the error checking and then call the right side on the socket that we got as input", so that we don't need to explicitly specify socket lots of times:
new socket() >>= bind(...) >>= connect(...) >>= send(...);
The formal definition is a bit more complicated since you have to worry about how to get the result of one function as an input to the next one, if that function needs that input and since you want to make sure that the functions you combine fit into the way you try to combine them in your monad. But the basic concept is just that you formalize different ways to combine functions together.
It has been a year since I posted this question. After posting it, I delved into Haskell for a couple of months. I enjoyed it tremendously, but I placed it aside just as I was ready to delve into Monads. I went back to work and focused on the technologies my project required.
And last night, I came and re-read these responses. Most importantly, I re-read the specific C# example in the text comments of the Brian Beckman video someone mentions above. It was so completely clear and illuminating that I’ve decided to post it directly here.
Because of this comment, not only do I feel like I understand exactly what Monads are … I realize I’ve actually written some things in C# that are Monads … or at least very close, and striving to solve the same problems.
So, here’s the comment – this is all a direct quote from the comment here by sylvan:
This is pretty cool. It's a bit abstract though. I can imagine people
who don't know what monads are already get confused due to the lack of
real examples.
So let me try to comply, and just to be really clear I'll do an
example in C#, even though it will look ugly. I'll add the equivalent
Haskell at the end and show you the cool Haskell syntactic sugar which
is where, IMO, monads really start getting useful.
Okay, so one of the easiest Monads is called the "Maybe monad" in
Haskell. In C# the Maybe type is called Nullable<T>. It's basically
a tiny class that just encapsulates the concept of a value that is
either valid and has a value, or is "null" and has no value.
A useful thing to stick inside a monad for combining values of this
type is the notion of failure. I.e. we want to be able to look at
multiple nullable values and return null as soon as any one of them
is null. This could be useful if you, for example, look up lots of
keys in a dictionary or something, and at the end you want to process
all of the results and combine them somehow, but if any of the keys
are not in the dictionary, you want to return null for the whole
thing. It would be tedious to manually have to check each lookup for
null and return, so we can hide this checking inside the bind
operator (which is sort of the point of monads, we hide book-keeping
in the bind operator which makes the code easier to use since we can
forget about the details).
Here's the program that motivates the whole thing (I'll define the
Bind later, this is just to show you why it's nice).
class Program
{
static Nullable<int> f(){ return 4; }
static Nullable<int> g(){ return 7; }
static Nullable<int> h(){ return 9; }
static void Main(string[] args)
{
Nullable<int> z =
f().Bind( fval =>
g().Bind( gval =>
h().Bind( hval =>
new Nullable<int>( fval + gval + hval ))));
Console.WriteLine(
"z = {0}", z.HasValue ? z.Value.ToString() : "null" );
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
Now, ignore for a moment that there already is support for doing this
for Nullable in C# (you can add nullable ints together and you get
null if either is null). Let's pretend that there is no such feature,
and it's just a user-defined class with no special magic. The point is
that we can use the Bind function to bind a variable to the contents
of our Nullable value and then pretend that there's nothing strange
going on, and use them like normal ints and just add them together. We
wrap the result in a nullable at the end, and that nullable will
either be null (if any of f, g or h returns null) or it will be
the result of summing f, g, and h together. (this is analogous
of how we can bind a row in a database to a variable in LINQ, and do
stuff with it, safe in the knowledge that the Bind operator will
make sure that the variable will only ever be passed valid row
values).
You can play with this and change any of f, g, and h to return
null and you will see that the whole thing will return null.
So clearly the bind operator has to do this checking for us, and bail
out returning null if it encounters a null value, and otherwise pass
along the value inside the Nullable structure into the lambda.
Here's the Bind operator:
public static Nullable<B> Bind<A,B>( this Nullable<A> a, Func<A,Nullable<B>> f )
where B : struct
where A : struct
{
return a.HasValue ? f(a.Value) : null;
}
The types here are just like in the video. It takes an M a
(Nullable<A> in C# syntax for this case), and a function from a to
M b (Func<A, Nullable<B>> in C# syntax), and it returns an M b
(Nullable<B>).
The code simply checks if the nullable contains a value and if so
extracts it and passes it onto the function, else it just returns
null. This means that the Bind operator will handle all the
null-checking logic for us. If and only if the value that we call
Bind on is non-null then that value will be "passed along" to the
lambda function, else we bail out early and the whole expression is
null. This allows the code that we write using the monad to be
entirely free of this null-checking behaviour, we just use Bind and
get a variable bound to the value inside the monadic value (fval,
gval and hval in the example code) and we can use them safe in the
knowledge that Bind will take care of checking them for null before
passing them along.
There are other examples of things you can do with a monad. For
example you can make the Bind operator take care of an input stream
of characters, and use it to write parser combinators. Each parser
combinator can then be completely oblivious to things like
back-tracking, parser failures etc., and just combine smaller parsers
together as if things would never go wrong, safe in the knowledge that
a clever implementation of Bind sorts out all the logic behind the
difficult bits. Then later on maybe someone adds logging to the monad,
but the code using the monad doesn't change, because all the magic
happens in the definition of the Bind operator, the rest of the code
is unchanged.
Finally, here's the implementation of the same code in Haskell (--
begins a comment line).
-- Here's the data type, it's either nothing, or "Just" a value
-- this is in the standard library
data Maybe a = Nothing | Just a
-- The bind operator for Nothing
Nothing >>= f = Nothing
-- The bind operator for Just x
Just x >>= f = f x
-- the "unit", called "return"
return = Just
-- The sample code using the lambda syntax
-- that Brian showed
z = f >>= ( \fval ->
g >>= ( \gval ->
h >>= ( \hval -> return (fval+gval+hval ) ) ) )
-- The following is exactly the same as the three lines above
z2 = do
fval <- f
gval <- g
hval <- h
return (fval+gval+hval)
As you can see the nice do notation at the end makes it look like
straight imperative code. And indeed this is by design. Monads can be
used to encapsulate all the useful stuff in imperative programming
(mutable state, IO etc.) and used using this nice imperative-like
syntax, but behind the curtains, it's all just monads and a clever
implementation of the bind operator! The cool thing is that you can
implement your own monads by implementing >>= and return. And if
you do so those monads will also be able to use the do notation,
which means you can basically write your own little languages by just
defining two functions!
A monad is essentially deferred processing. If you are trying to write code that has side effects (e.g. I/O) in a language that does not permit them, and only allows pure computation, one dodge is to say, "Ok, I know you won't do side effects for me, but can you please compute what would happen if you did?"
It's sort of cheating.
Now, that explanation will help you understand the big picture intent of monads, but the devil is in the details. How exactly do you compute the consequences? Sometimes, it isn't pretty.
The best way to give an overview of the how for someone used to imperative programming is to say that it puts you in a DSL wherein operations that look syntactically like what you are used to outside the monad are used instead to build a function that would do what you want if you could (for example) write to an output file. Almost (but not really) as if you were building code in a string to later be eval'd.
You can think of a monad as a C# interface that classes have to implement. This is a pragmatic answer that ignores all the category theoretical math behind why you'd want to choose to have these declarations in your interface and ignores all the reasons why you'd want to have monads in a language that tries to avoid side effects, but I found it to be a good start as someone who understands (C#) interfaces.
See my answer to "What is a monad?"
It begins with a motivating example, works through the example, derives an example of a monad, and formally defines "monad".
It assumes no knowledge of functional programming and it uses pseudocode with function(argument) := expression syntax with the simplest possible expressions.
This C# program is an implementation of the pseudocode monad. (For reference: M is the type constructor, feed is the "bind" operation, and wrap is the "return" operation.)
using System.IO;
using System;
class Program
{
public class M<A>
{
public A val;
public string messages;
}
public static M<B> feed<A, B>(Func<A, M<B>> f, M<A> x)
{
M<B> m = f(x.val);
m.messages = x.messages + m.messages;
return m;
}
public static M<A> wrap<A>(A x)
{
M<A> m = new M<A>();
m.val = x;
m.messages = "";
return m;
}
public class T {};
public class U {};
public class V {};
public static M<U> g(V x)
{
M<U> m = new M<U>();
m.messages = "called g.\n";
return m;
}
public static M<T> f(U x)
{
M<T> m = new M<T>();
m.messages = "called f.\n";
return m;
}
static void Main()
{
V x = new V();
M<T> m = feed<U, T>(f, feed(g, wrap<V>(x)));
Console.Write(m.messages);
}
}

Categories