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.
Related
In Unity, here's a category in c#,
public static class HandyExtensions
{
public static IEnumerator Tweeng( this System.Action<float> v, float d )
{
while (..)
{
..
v( 13f*t );
yield return null;
}
v(13f);
}
Compiles fine!
But if you try to use it,
yield return StartCoroutine(
( (x)=>laser=x ).Tweeng(3.141f)
);
this saddening error appears:
Assets/scripts/...cs(116,34): error CS0023: The .' operator cannot be applied to operand of typeanonymous method'
I have tears about this.
How could c# let us down?
Surely there's a way to call "on" a lambda like that, for an extension?
BTW the workaround is to go 3.14f.Tweeng((x)=>laser=x) but it's not as cool.
I'm sorry this saddens you, but this choice was made deliberately by the language design team. The code which evaluates whether a given extension method is valid requires that the receiver have a clear type, and lambda expressions do not have a type.
There was some debate on this point, but ultimately it was decided that (1) the proposed feature is potentially confusing or error-prone if typeless expressions like lambdas, method groups and null literals get to be receivers of extension methods, and (2) the proposed feature is not at all necessary to make LINQ work. We were very constrained in our schedules when implementing C# 3 and anything that was not necessary to make LINQ work was cut. It was much easier to design, implement and test the feature of "don't allow lambdas as receivers" than to have to consider all the potentially odd cases where a lambda, method group or null was being used as the receiver.
As others have said, you can simply cast the lambda, or put it in a variable and then use the variable as the receiver.
Alternatively, as you note, you could consider using the float as the receiver in your specific example.
Quell your tears fair Joe, let not despair drive you from your dream! If you explicitly cast it, it should work.
Try:
yield return StartCoroutine(
((System.Action<float>)( (x)=>laser=x )).Tweeng(3.141f)
);
I'm looking to give a talk about LINQ, and wanted to mention how querying collections used to work. Back in .Net 1.1, I seem to remember there being a method (Find() maybe?) where you would pass the address of another method which would interrogate each item in the collection and determine whether it should be included in the filtered collection.
Am I completely misremembering this? It stuck with me, as the syntax was unusual for the time.
I thought it was something like:
public bool ContainsFoo(string term){
if(term.contains("Foo"){
return true;
}
return false;
}
And you could call it like:
filteredCollection = collection.Find(ContainsFoo);
I seem to remember a lot of people commenting on how LINQ was so much faster to code because developers could now write functions in-line. How were we writing functions "out-line" previously?
Before LINQ you were just limited to all the built-in List/List<T> methods, and yes Find is one of them (still is). The difference is it expects a Predicate<T> as opposed to a Func<Boolean, T> which you can still do inline e.g.
var found = list.Find(delegate(Item item) { return item != null; });
Or as you demonstrated by using a named method.
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.
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);
}
}
I have recently had the need to write a fluent interface for C# that will essentially mirror SQL. Yes, I am aware of LINQ to SQL, but I'm interesting in getting "closer to the metal"--having something that essentially provides nothing more than an Intellisensified SQL shim within C#.
E.g.,
var fq = new FluentQuery();
Expression<Action> =
() => fq.SELECT.DISTINCT(Foo.ID).FROM(Foo).WHERE(Foo.Age > 22);
Now, I was thinking that this concept could be generalised--that is, how about a general EBNF to fluent interface generator? Does anyone know if such a beast exists?
I like it, but you have to make sure to return types like HasFromAndSelect or something like that so you don't end up with fq.SELECT(Foo.ID).SELECT(Foo.Age).WHERE(Foo.Age > 22) or fq.WHERE(Foo.Age > 22).SELECT(Foo.ID), etc.
There's much more thought that needs to go into this, including the fact that the CAPS LOCK MODE is hurting my eyes :)