How would you like to use the following way to configure dependencies in MEF? A fluent interface with POCO support (no attributes necessary)? Yup.
var resolver = new FluentResolver();
resolver.Register<HelloWorld>().
And<HelloGreeting>().As<IGreeting>().
And<ConsoleOutputter>().As<IOutputter>();
var domain = new CompositionContainer(resolver);
// HelloWorld has dependencies on IGreeting and IOutputter
var helloWorld = domain.Resolve<HelloWorld>();
helloWorld.SaySomething();
Lately I've been digging more and more into the first CTP of the Managed Extensibility Framework (MEF) coming out of Krzysztof Cwalina's team here at Microsoft. By default, a developer needs to sprinkle Export and Import attributes in their classes at the point they are needing something to be injected, or on classes that need to be exported in order to be injected into other classes. However, if you don't like this behavior, MEF provides several extension points you can use to provide a different interface into MEF.
In my "ideal" Dependency Injection interface for MEF, there are several requirements that I would like:
- No Export/Import attributes necessary; hence, support for POCOs (Plain Ol' CLR Objects)
- Registration of types with container, not registration of object instances (where I would have to create the object myself before adding it's type to the container).
- Simply ask container to resolve a type into an instance for me. Other than the container and resolver, none of my "domain objects" should be "new"-ed up by me.
- No need to tell the CompositionContainer to Bind(). It should know about all the types necessary.
- For "ease of use", I want to configure dependencies via a Fluent Interface.
I'm on a little bit of a Fluent Interface kick right now. I admit it. My name is Jason Olson and I'm a Fluent Interface junkie. If I could type emails via a Fluent Interface in code (rather than Outlook), I probably would. My addiction is just... that... bad.
Before we dig into how we will leverage MEF's extension points, let's just take a quick peek at the classes we are wanting to wire up via the interface shown above:
class HelloWorld
{
public IGreeting Greeting { get; set; }
public IOutputter Outputter { get; set; }
public void SaySomething()
{
// Our dependencies above determine where the output
// is written to, and what the greeting will be.
Outputter.WriteLine(Greeting.Greet());
}
}
interface IGreeting
{
string Greet();
}
class HelloGreeting : IGreeting
{
public string Greet()
{
return "Hello Fluent Interface!";
}
}
interface IOutputter
{
void WriteLine(string message);
}
class ConsoleOutputter : IOutputter
{
public void WriteLine(string message)
{
Console.WriteLine(message);
}
}
So how do we enable this new behavior? There are two primary MEF extension points we will use, a custom ComponentBinder and a custom ValueResolver. According to the CTP documentation (emphasis mine):
"The role of the ComponentBinder is to create a collection of primitives associated with its component. There is only one ComponentBinder per component. The CompositionContainer will use the collection of binders during the bind operation to determine how components need to be wired-up."
In this case, "collection of primitives" essentially means the export and imports of the component it is bound to. One of the interesting points to note is that the CompositionContainer uses these ComponentBinders to determine how various components need to be created. So for MEF to determine what the various imports and exports are for wiring up components, it can use our custom ComponentBinder to do so. So while the default ReflectionBinder will generate this information via attribute declarations on the components in question, we can change this behavior if we wish.
The other extension point we will use is a custom ValueResolver. Once again, according to the CTP documentation (emphasis mine):
"A ValueResolver allows the composition container to retrieve components from some sort of repository. The composition container’s bind operation has the single goal of satisfying all imports for all components that were explicitly added to it. During a bind operation, the composition container can query the ValueResolver for exports if it deems it necessary (e.g. no exports currently in the composition container satisfy a specific import, an import is requesting a collection of all available exports, etc.)."
To implement these two extension points, we will need two custom classes: FluentResolver and FluentBinder. Our FluentResolver is what we use to build up a map of our dependencies via the fluent interface shown above. When the FluentResolver is then passed into a CompositionContainer, we will go through our dependency map and crank out a bunch of FluentBinders that MEF can then use when needing to create various objects the user is asking for.
First, our FluentResolver. FluentResolver contains the methods that make up our fluent interface and that will hold the dependency map we are building up. And then we our FluentResolver is hooked up to a CompositionContainer, we will use this "dependency map" in order to build up all the FluentBinder instances that MEF will use to wire up all our dependencies.
class FluentResolver : ValueResolver, IRegisterChainer
{
private Type lastRegisteredType;
private IDictionary<Type, IList<Type>> exportTypes = new Dictionary<Type, IList<Type>>();
private IList<Type> registeredTypes = new List<Type>();
// The following three methods define our fluent interface
// (Register<T>, And<T>, and As<T>).
public IRegisterChainer Register<T>() where T : class, new()
{
if (!exportTypes.ContainsKey(typeof(T)))
{
exportTypes.Add(typeof(T), new List<Type>());
}
exportTypes[typeof(T)].Add(typeof(T));
registeredTypes.Add(typeof(T));
lastRegisteredType = typeof(T);
return this;
}
public IRegisterChainer As<T>() where T: class
{
// Add exported type to last registered type (the call right
// before .As<T>() in the fluent interface). This is used
// to register a type as an interface, rather than the
// concrete type.
exportTypes[lastRegisteredType].Add(typeof(T));
return this;
}
public IRegisterChainer And<T>() where T : class, new()
{
// Just a different way to register so that the fluent
// interface is easily readable.
return Register<T>();
}
// This is where the "magic" happens. When our container is set (like
// when we are passed into the constructor of a container), we will
// create all of our custom binders that MEF will then use to wire-up
// dependencies.
protected override void OnContainerSet()
{
base.OnContainerSet();
foreach (var type in registeredTypes)
{
// An "Import" (read: injected dependency) is defined as any property whose
// type is a type that is "exported" from any other registered type
var imports = (from pi in type.GetProperties()
from export in exportTypes
where export.Value.Contains(pi.PropertyType)
select pi).Distinct();
// Export all types our specific type has been asked to export and all the
// properties from above that are dependencies we need to inject.
Container.AddBinder(new FluentBinder(type, exportTypes[type], imports.ToList()));
}
// Since all the dependencies are known from our fluent interface,
// automatically bind the container so that the user doesn't have to
// call Bind() themselves.
Container.Bind();
}
public override CompositionResult<IImportInfo> TryResolveToValue(string name, IEnumerable<string> requiredMetadata)
{
// Same as TryResolveToValues below, except we just return a
// single value, rather than a collection of values.
var result = TryResolveToValues(name, requiredMetadata);
return new CompositionResult<IImportInfo>(result.Succeeded,
result.Issues,
result.Value.First());
}
public override CompositionResult<ImportInfoCollection> TryResolveToValues(string name, IEnumerable<string> requiredMetadata)
{
// Based on all the custom binders we have created, have
// the container get the various dependent components for us.
return TryGetContainerLocalImportInfos(name, requiredMetadata);
}
}
IRegisterChainer is simply an interface our three fluent methods (Register<T>, And<T>, As<T>) return (and that FluentResolver implements) that allows us to keep on chaining our method calls one after the other, hence enabling our fluent interface.
interface IRegisterChainer
{
// Allows registering another dependency into our resolver
IRegisterChainer And<T>() where T : class, new();
// Enables registering a depedency as a specific type (like
// an interface) on top of the concrete type it directly implements
IRegisterChainer As<T>() where T : class;
}
And now on to our FluentBinder:
class FluentBinder : ComponentBinder
{
// An instance of the type we are the binder for
private object instance;
// The types we export (could be our concrete type, interfaces, etc.)
private IList<Type> exports;
// Our properties that are dependencies needing resolving
private IList<PropertyInfo> imports;
public FluentBinder(Type type, IList<Type> exports, IList<PropertyInfo> imports)
{
this.exports = exports;
this.imports = imports;
// In the future, we could use constructor injection here. For now,
// just use the default constructor and property injection.
instance = type.GetConstructor(new Type[] {}).Invoke(new object[] {});
}
public override IEnumerable<string> ExportNames
{
// Return the name of the Types we are Exporting
get { return exports.Select(t => t.ToString()); }
}
public override CompositionResult Export()
{
// Add our object instance into the container for every type
// that we are exporting.
foreach (var type in exports)
{
AddValueToContainer(type.ToString(), instance);
}
return new CompositionResult(true, new List<CompositionIssue>());
}
public override IEnumerable<string> ImportNames
{
// Return the name of the Types we need Imported
get { return imports.Select(pi => pi.PropertyType.ToString()); }
}
public override CompositionResult Import(IEnumerable<string> changedValueNames)
{
// Import every property we have that is a dependency
foreach(var propertyInfo in imports)
{
// Inject an instance of the type of our property from the container
var component = Container.TryGetBoundValue(propertyInfo.PropertyType.ToString(),
propertyInfo.PropertyType);
propertyInfo.SetValue(instance, component.Value, null);
}
return new CompositionResult(true, new List<CompositionIssue>());
}
}
This FluentBinder is essentially the heart of the our behavior. We use the the results from our FluentResolver that are passed in to our binder to let MEF know what types we need to import and what types we are exporting from the type FluentBinder is bound to.
The final thing we need to enable our desired API from above is an extension method to CompositionContainer called Resolve<T>() which we just give the type that we would like an instance of. I just happen to think this thin wrapper around TryGetBoundValue<T>() is easier to use and better to read.
static class CompositionContainerExtensions
{
public static T Resolve<T>(this CompositionContainer domain)
{
return domain.TryGetBoundValue<T>().Value;
}
}
And now we can combine all the pieces together to build our sample application:
class Program
{
static void Main(string[] args)
{
// Declare dependencies via a fluent interface.
// No need for attributes, XML config, or
// registration of instances of objects.
var resolver = new FluentResolver();
resolver.Register<HelloWorld>().
And<HelloGreeting>().As<IGreeting>().
And<ConsoleOutputter>().As<IOutputter>();
// Pass in our custom resolver and have it help
// take care of the binding process.
var domain = new CompositionContainer(resolver);
// Ask the container for an instance of a type.
var helloWorld = domain.Resolve<HelloWorld>();
helloWorld.SaySomething();
Console.ReadKey(true);
}
}
While the fluent interface might be seen as a potential "big departure" from the way MEF works out-of-the-box, you can see that it is very possible (and not too difficult) to change how dependencies are configured with MEF. You might want your configuration in an XML file, in a DSL defined in a map.txt file, in a database (no I don't know why you'd want that :P), etc. And no matter how you want it done, it is possible for you to do so with just a little coding.
Until next time, Happy Coding!
Obviously, this is just a sample prototype and doesn't have several features necessary in DI containers. So, more reason for me to write some more code :). Also, remember this is built on the first CTP of MEF, so the odds are that it will become out-of-date at a later time.
As developers get up to speed with the CCR, they quickly come across the (ab)use of iterators to achieve "concurrency." Okay, "(ab)use" may have been a bit of a low-blow. I call it an abuse as it is a totally unorthodox use of what iterators are usually used for, and I've came across my fair share of developers who find this unorthodox usage highly confusing. Not only is it confusing, but it's not what I would consider true concurrent code. In a concurrent environment, if I create twenty different tasks that need to be executed, I expect several of those tasks to be executed at the exact same time (depending on the number of processors I have on my system). As a side effect of this concurrent execution of tasks, the order in which those tasks are executed is not guaranteed. If you don't have several tasks executing concurrently, and order of processing is indeed guaranteed, that's about as close you can get to being normal sequential code. Look at this sample (example 18) from MSDN. If you execute and step through this code, you will find that the method actually executes sequentially. The code posts a number, processes the number, posts another number, processes that number, etc. This is highly sequential. One could argue this is simply not the best sample for CCR iterators. However, after using CCR when developing robots using Robotics Studio, you will find that this "sequential but not" pattern is a very frequent pattern that is used when using CCR iterators. There's also the impact of having a method that essentially never exits due to the "while (true)" nature of the iterator-based method that is determining what tasks need to execute (leading to a highly coupled, monolithic application). This doesn't mean that the CCR itself isn't useful though. You just need to know how to leverage the framework while avoiding some of these "rough spots". So let's take a look at an example of how to use CCR to achieve "true" concurrency with the CCR without the use of iterators (for you VB fans, the great part of this approach is that it is entirely possible with VB like I show here). Dim myPort As New Port(Of Integer)
At the heart of the message-based infrastructure in the CCR is a Port. A Port is where messages are posted to, and pulled from when tasks are actually executed. As seen above, Ports are strongly typed through the use of generics, and so they support posting/pulling of largely any POCO (Plain Ole CLR Object) you wish. In the case of this very simple demo we just use integers, but in a real system this might be self-defined types like StockQuoteRequestMessage, FoodOrderMessage, etc.
Sub Main()
Dim taskDispatcher As New Dispatcher(4, "Sample Dispatcher")
Dim taskQueue As New DispatcherQueue("Sample Tasks", taskDispatcher)
In the CCR, a DispatcherQueue contains a list of tasks to be executed, while a Dispatcher controls the execution of those tasks. Here we force our dispatcher to run four tasks concurrently even if we are on a single processor machine just so we can see the concurrency in action. Then we simply pass our dispatcher to the queue that contains the tasks that will be managed.
' Create the task that will handle our work
Dim workReceiver = Arbiter.Receive(Of Integer)(True, _
myPort, _
Function(i) ProcessValue(i))
' Register the task with the CCR task queue
Arbiter.Activate(taskQueue, workReceiver)
' Post some work to do
For i = 0 To 9
myPort.Post(i)
Next
When we create our workReceiver, we are essentially telling the CCR that we want a persistent task (one that will last across the processing lifetime of many messages, possibly until the application exits), and that when a message comes in on our Port, we will process that message with our function ProcessValue (defined below). Once the receiver is created, we simply hook it up to the task queue, and we're off to the races.
Finally, all we need to do is wait until all values have been processed and exit the application.
' Wait until all tasks are finished
While myPort.ItemCount > 0
Thread.Sleep(TimeSpan.FromMilliseconds(200))
End While
taskQueue.Dispose()
taskDispatcher.Dispose()
Console.Write("Press any key to exit...")
Console.ReadKey(True)
End Sub
So when a message is posted to our port, CCR will call our function ProcessValue in order to process the message (as specified when we created the task to process messages). In our process function, we are simply going to write to the console at the beginning and at the end as well as sleeping our thread in the middle to simulate some work being done in the function.
Function ProcessValue(ByVal value As Integer)
Console.WriteLine("Begin " + value.ToString())
Thread.Sleep(TimeSpan.FromMilliseconds(200))
Console.WriteLine("End " + value.ToString())
Return Nothing
End Function
When I actually execute this sample, you can see the parallel nature of the execution by viewing the output (your output may differ as it can differ upon every execution thanks to the non-deterministic nature of concurrency):
Begin 0 Begin 1 Begin 3 Begin 2 End 2 Begin 4 End 1 Begin 5 End 0 Begin 6 End 3 Begin 7 End 4 Begin 8 End 5 End 6 Begin 9 End 7 End 8 End 9 Press any key to exit...
And that's all we need to do in order to use CCR to process incoming messages in parallel (and in a "true" concurrent fashion). Just as a recap, here's the entire sample in one place:
Dim myPort As New Port(Of Integer)
Sub Main()
Dim taskDispatcher As New Dispatcher(4, "Sample Dispatcher")
Dim taskQueue As New DispatcherQueue("Sample Tasks", taskDispatcher)
' Create the task that will handle our work
Dim workReceiver = Arbiter.Receive(Of Integer)(True, _
myPort, _
Function(i) ProcessValue(i))
' Register the task with the CCR task queue
Arbiter.Activate(taskQueue, workReceiver)
' Post some work to do
For i = 0 To 9
myPort.Post(i)
Next
' Wait until all tasks are finished
While myPort.ItemCount > 0
Thread.Sleep(TimeSpan.FromMilliseconds(200))
End While
taskQueue.Dispose()
taskDispatcher.Dispose()
Console.Write("Press any key to exit...")
Console.ReadKey(True)
End Sub
Function ProcessValue(ByVal value As Integer)
Console.WriteLine("Begin " + value.ToString())
Thread.Sleep(TimeSpan.FromMilliseconds(200))
Console.WriteLine("End " + value.ToString())
Return Nothing
End Function
As a "hello world" sample for using the CCR, this is a very simple demo. But it shows that it is very easy to actually achieve concurrent applications with the CCR without having to use CCR iterators. At the same time, avoiding the use of CCR iterators enable us to write a message-oriented application that can be properly modularized by "separating concerns" into independent message processors through the use of Ports.
Of course, an added benefit of taking a "non-iterator" approach when using the CCR is that languages that don't have direct support for iterators (like VB.NET) can also develop CCR-based applications to achieve highly-parallel solutions.
One realization I have come to when talking with many other developers is that there is a good number of developers that don't realize that inheritance introduces dependencies directly into your classes. Your derived class is now dependant upon the interface and behavior of your base class. Worded another way, your derived class is now strongly coupled to your base class. I've met a number of developers that are very passionate about managing their dependencies via inversion of control, dependency injection, etc. and yet they implement solutions that have a class hierarchy 5+ layers deep. This strong coupling can become problematic if you need to change either the interface or behavior of my base class. For instance, if I need to add another abstract method I didn't originally think of, every single class that derives from that base class now must change in order to implement that behavior. Or, if I change the behavior of one of the methods in my base class, I can find myself in a situation where one of my derived classes will break because they were relying on that base class behavior to act a given way (even more confusing when the change doesn't impact any other of the derived classes). Over-using (read: abusing) inheritance in your code can very easily lead to brittle classes that prevent you from being as agile as you need to be. While it is easy for developers to look at dependencies as other external classes your class is dependant upon, you have to keep in mind that your class is also strongly dependant on its base class as well. The beautiful thing is that with some of the functionality introduced into .NET in both 2.0 and 3.5, you can avoid developing these brittle classes by using Generic programming. "Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters. This permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication." I know this description can be a bit confusing at first. Let's learn about Generic programming by example. And as an example, let's take a look at possible implementations of the Command pattern. "In object-oriented programming, the Command pattern is a design pattern in which objects are used to represent actions. A command object encapsulates an action and its parameters." In these examples, we are going to look at a home automation system. Specifically, let's look at the code it takes to automate lights using the Command pattern. In order to do this, we of course need a Light that we are actually automating (automation code removed for readability purposes): class Light
{
public void TurnOn()
{
Console.WriteLine("Light Turned On");
}
public void TurnOff()
{
Console.WriteLine("Light Turned Off");
}
}
So, let's dive right in.
In the "typical" way of implementing the Command pattern, you have an abstract base class Command that your detailed commands inherit from, overriding a virtual method to actually execute the command (this could also be an interface ICommand as well, instead of an abstract base class).
abstract class Command
{
public abstract void Execute();
}
class LightOnCommand : Command
{
private Light _light;
public LightOnCommand(Light theLight)
{
_light = theLight;
}
public override void Execute()
{
_light.TurnOn();
}
}
class LightOffCommand : Command
{
private Light _light;
public LightOffCommand(Light theLight)
{
_light = theLight;
}
public override void Execute()
{
_light.TurnOff();
}
}
Let's take another look at that definition of the Command pattern: "the Command pattern is a design pattern in which objects are used to represent actions". In our case, each action (turning a light on, turning a light off) is represented by an object (LightOnCommand, LightOffCommand).
Now to use these classes, all we need to do is instantiate new instances of our two commands (LightOnCommand and LightOffCommand) and execute them. Pretty simple. And because of leveraging a common base class, we can use polymorphism to reuse this code even more (like having a list of commands that we can execute in a script or elsewhere).
var livingRoomLight = new Light();
var lightOn = new LightOnCommand(livingRoomLight);
var lightOff = new LightOffCommand(livingRoomLight);
lightOn.Execute();
lightOff.Execute();
This classic approach doesn't come without it's drawbacks though. First of all, for every home device that we wish to turn on and off, we would be introducing two new classes into our code. While this may not be that bad for a couple of devices, it can quickly get out of hand when the number of devices start to grow.
Also, the "common behavior" we get out of our base class isn't very flexible. If we change our Execute() method in our base class from abstract to virtual in order to introduce common behavior, how do you guarantee that the base method is called when it should be? In a derived class, should you call the base method before your own execution code, or after? What if I want common code in my base class that will be executed both before and after the behavior in my derived classes? While .NET has ways of achieving this, it quickly becomes complex and just introduces more code that obfuscates what the true purpose of our code is.
Not as flexible as we first though, eh?
So what has .NET done lately to make this job easier? Well, with the introduction of Generics and Lambdas, we can do a form of Generic programming that helps us write "one Command class to rule them all." By writing more generic code, you get down to the essence of what your code needs to do, and allows you to write code that is more flexible and not as dependant on other classes as before (since we are not directly leveraging inheritance like we were before).
What might a generic solution to the Command pattern look like?
class GenericCommand<TReceiver>
{
private TReceiver _receiver;
private Action<TReceiver> _commandToExecute;
public GenericCommand(TReceiver theReceiver, Action<TReceiver> theCommandToExecute)
{
_receiver = theReceiver;
_commandToExecute = theCommandToExecute;
}
public void Execute()
{
_commandToExecute(_receiver);
}
}
Let's look back at that description for Generic programming: "This permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication." That's all we are doing here. We have written a common type in which only the types on which it operates differs when used.
When we use this generic type is when we actually dictate what type it operates upon. In the case of our home automation system, we are going to create an instance of our GenericCommand that operates on a Light fixture. Then, we will specify what action needs to be taken when the command is execute by leveraging lambda expressions:
var livingRoomLight = new Light();
var genericLightOn = new GenericCommand<Light>(livingRoomLight, theLight => theLight.TurnOn());
var genericLightOff = new GenericCommand<Light>(livingRoomLight, theLight => theLight.TurnOff());
Pretty simple, for our light on command we turn the light on, and for our light off command we turn the light off. And in both cases, we are using the exact same common type (GenericCommand<TReceiver>) when declaring our command.
Now let's say we want to start automating our Garage as well. The class we might be given to do this automating might look like the following (with all the automation code removed again):
class Garage
{
public void TurnLightOn()
{
Console.WriteLine("Garage Light Turned On");
}
public void TurnLightOff()
{
Console.WriteLine("Garage Light Turned Off");
}
public void OpenDoor()
{
Console.WriteLine("Garage Door Opened");
}
public void CloseDoor()
{
Console.WriteLine("Garage Door Closed");
}
}
Using the prior inheritance-based way, we would need to introduce two more command classes for this new Garage automation. And as stated before, when having to introduce two more command classes for every new piece of home automation, we quickly have a blow-up in the number of classes we have to maintain. However, using the generic programming-based approach that leverages Generics and Lambdas, we actually don't have to introduce any new classes as our meta-class GenericCommand<T> can handle those situations already.
Here's how we might consume the new Garage with our GenericCommand<T>:
var genericOpenGarage = new GenericCommand<Garage>(myGarage, theGarage =>
{
theGarage.TurnLightOn();
theGarage.OpenDoor();
});
var genericCloseGarage = new GenericCommand<Garage>(myGarage, theGarage =>
{
theGarage.CloseDoor();
theGarage.TurnLightOff();
});
genericOpenGarage.Execute();
genericCloseGarage.Execute();
Very simple. Once again, we are using the exact same type (GenericCommand<TReceiver>) to implement the automation commands for our Garage as we were using with our Light. So, the same common type that, when used, only differs by the types it operates on. Which is exactly the definition of Generic programming we discussed before. It's not as scary as it sounds!
Now if we need to introduce logging or any other common functionality into our command class, we can introduce it in one place and have it applied to all our consuming code. Unlike the polymorphic approach outlined above, we now have the flexibility in this approach to execute any common code in relation to our command, whenever we want, however we want. It doesn't matter if that common code is before, or after, or before and after.
If you are still reading this (in which case I thank you), you should realize that you are already familiar with a pattern used to achieve parallelism in the new Parallel Extensions to the .NET Framework CTP that has been released. The programming model used when dealing with Tasks and Futures are essentially the exact same thing as the generic command pattern used above. So if you grok the GenericCommand above, you'll settle right into using Tasks and Futures within the Parallel Extensions.
In closing, by using a Generic programming approach when implementing our Command pattern, we now have just the base functionality that is absolutely needed to implement our commands. And, we avoid the explosion in the number of classes and dependencies that taking an inheritance-based approach would introduce, all made possible by the introduction of Generics (in 2.0) and Lambdas (in 3.5) in .NET.
I hope you enjoyed this walk down the "applying generics and lambdas" road. Until next time, Happy Coding!
Posted in C# | Programming
In this post I want to discuss with you the importance of realizing how lambdas work (and why you should care). Let's dive right in with some code. Given the following code snippet, what would you expect the output to be (no cheating :P)? var actions = new List<Action>();
for (int i = 0; i < 10; i++)
{
actions.Add(() => Console.WriteLine(i));
}
foreach (var action in actions)
{
action();
}
Would you believe me if I told you this is the output you get?
10 10 10 10 10 10 10 10 10 10
At first glance, one might expect this output:
0 1 2 3 4 5 6 7 8 9
But all tens are output instead. Why does this happen? Let's crank open Reflector and find out why...
The first thing you'll notice is that the compiler has created a helper class to enable the closure we have. This helper class created by the compiler contains a local variable that we use to iterate over and a method that our delegate is contained within. This helper class is especially interesting because it is where the magic happens.
[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
// Fields
public int i;
// Methods
public void <Main>b__0()
{
Console.WriteLine(this.i);
}
}
Rather than diving into MSIL, let's look at some pseudo-code of what the compiler _actually_ executes with the original code above (based on the generated MSIL):
var actions = new List<Action>();
<>c__DisplayClass2 localFrame = new <>c__DisplayClass2();
for (localFrame.i = 0; localFrame.i < 10; localFrame.i++)
{
actions.Add(localFrame.<Main>b__0);
}
foreach (var action in actions)
{
action();
}
Perhaps now you can see where the problem is. The "problem" in our original code exists because of the scope that our closures are defined. The local index from our for loop is now stored in our helper class <>c__DisplayClass2. And the code that is executed by the action is contained within the compiler generated <Main>b__0() method now. So the Console.WriteLine() method now uses the local variable from <>c__DisplayClass2 when it is executed.
So while we are looping through building all our actions, we are also incrementing the property i in localFrame (an instance of <>c__DisplayClass2). Then at the end when we are actually executing the actions, the <Main>b__0() is called and uses the local i property (which by this time, has already been incremented to 10 from our loop). And that's why every action we execute prints "10" instead of the 0 through 9 like we expected.
So, why do you need to know how these work? Take the following code that outputs items from an array of strings:
var actions = new List<Action>();
string[] urls =
{
"http://www.url.com",
"http://www.someurl.com",
"http://www.someotherurl.com",
"http://www.yetanotherurl.com"
};
for (int i = 0; i < urls.Length; i++)
{
actions.Add(() => Console.WriteLine(urls[i]));
}
foreach (var action in actions)
{
action();
}
This code looks pretty innocuous. Our bounds are protected, and we just index into our array to output a string. But, is that what we're really doing? Remember how closures work from above. The actual thing that happens when I run this code is this:
Interesting. Even though our index variable should only even be less than the length of our url array, an exception is thrown because the index variable is actually equal to the length of our url array (and hence outside of the bounds thanks to 0-based indices).
Well, that wasn't what we were probably expecting. But now that we are having this "problem", what is the easiest way to resolve it? Remember that the problem is happening because of the scope of the variable within our closure. So to fix this, we can essentially declare a temporary variable that is unique in scope to this specific iteration through our array:
for (int i = 0; i < urls.Length; i++)
{
string localUrl = urls[i];
actions.Add(() => Console.WriteLine(localUrl));
}
And now the code is fixed.
Understanding how lambdas work is especially important when you start developing with a library that leverages lambdas heavily like LINQ does, or Parallel Extensions to the .NET Framework. And don't worry, even those people that know how lambdas work occasionally get bitten by this behavior.
Enjoy the coding, folks!
Posted in C# | Programming
What a great week to be a developer. First, the latest Parallel Extensions CTP was released to the net, and now the first Managed Extensibility Framework CTP has been released onto Code Gallery. So what is the Managed Extensibility Framework? From the announcement: "The Managed Extensibility Framework (MEF) provides developers with a tool to easily add extensibility to their applications and with minimal impact on existing code. The application developer can define extension points according to the functionality required of an extension, while the extension developer uses those points to interact with the application. MEF enables this extensibility to take place without creating a hard dependency in either direction. Applications can be extended at run time without recompilation, and extensions can be used by multiple applications sharing the same extension requirements. MEF also allows an application to delay the loading of an extension while still examining its metadata, enabling efficient traversal of large catalogs of extensions." To make a medium-size story even shorter, the Managed Extensibility Framework (MEF) is essentially a framework for dependency inversion/inversion of control. If you are a CTP junkie and like to play around with all the latest bits like I do, you have some downloading to do :P. Enjoy!
In "Facet Mapping with LINQ, Part 1", we discussed how to add Facet Mapping to your .NET application using an attribute-based solution. This solution just doesn't leave me very excited. As we recounted, there are some problems with using an attribute-based approach: - Littering domain models with presentation layer-specific attributes
- Doesn't support existing POCOs (that perhaps can't change)
- Can't support combinations of members (without create a new method property that actually does the combining (read: ugly)).
I personally only want one area of code to change if I alter my facet mapping. Having to change my POCOs when I want to change facet maps "smells" to me (and is itself a violation of the Single Responsibility Principle). Let's look at another way we can implement facet mapping in .NET via some more LINQ-goodness. In a previous post, I talked about my new-found love for Fluent Languages in .NET (ala Moq or NInject). With attributes out of the way for facet mapping, I wanted to develop a library for facet mapping that was easy to use and could be used with existing code. Here are some of the "requirements" for the new facet mapping code (read: "requirements" means arbitrary features that I think are good and that I would like to see :P): - Usable with an existing set of POCOs (without having to change a single line of code in those objects)
- Easily support combination of properties/methods or any arbitrary code that a person would want to create a facet on
- Readable and easy to use (read: my own reason to try to a fluent language interface :P)
Let's take a look at the proposed API (taken straight from my unit tests): // Given our list of cars
List<Car> cars = new List<Car>() {
new Car { Make = "Toyota", Model = "Corola", Price = 20000, Year = 2001 },
new Car { Make = "Toyota", Model = "Corola", Price = 30000, Year = 2002 }
};
// Generate a facet map (list of Facets) that we can use
var facets = FacetMap<Car>.Create()
.AddFacetOn(c => c.Make)
.AddFacetOn(c => c.Model)
.GenerateFrom(cars)
.ToList();
We can also define an arbitrary expression that we want to generate a facet on:
var facets = FacetMap<Car>.Create()
.AddFacetOn("MakeAndModel", c => c.Make + " " + c.Model)
.GenerateFrom(cars)
.InParallel()
.ToList();
With FacetMap being a generic class, we can use it to generate facets on any existing CLR class we wish to. And with the use of lambda expressions to specify what we are creating facets on, our code can be refactored a bunch and not break our facet mapping.
Implementing FacetMap isn't actually all that difficult. Since all our operations can chain be chained together with each other, all of them actually return the same interface (our IFacetMap that the FacetMap class implements).
The first thing you notice is that we are creating a generic class so that our facet maps can be used with any POCO that exists out there (theoretically). And, we are hiding the constructor so that we can use a factory method (I happen to think it reads better, could just be my personal opinion though).
public class FacetMap<TResource> : IFacetMap<TResource>
{
/// <summary>
/// Constructor is hidden as we are using a factory method
/// </summary>
private FacetMap()
{
facetGenerators = new Dictionary<string, Delegate>();
}
/// <summary>
/// Factory Method to create a new Facet Map
/// </summary>
/// <returns>New FacetMap</returns>
public static IFacetMap<TResource> Create()
{
return new FacetMap<TResource>();
}
...
}
Our class implemented our IFacetMap interface so that external code using our FacetMap is relying on abstractions outside of our Factory Method. And as you can see, all our methods return this interface so that we can chain all the methods together to form the fluent language shown above (the one exception being our Generate() method where we just return our list of Facets that were generated):
public interface IFacetMap<TResource>
{
IFacetMap<TResource> AddFacetOn<TResult>(Expression<Func<TResource, TResult>> facetValue);
IFacetMap<TResource> AddFacetOn<TResult>(string facetName, Expression<Func<TResource, TResult>> facetValue);
IEnumerable<Facet<TResource>> GenerateFrom(IEnumerable<TResource> resources);
}
Why the "Expression<Func<X, Y>>" instead of just "Func<X, Y>". This is more a matter of convenience for the end-user. The end-user can write the code as if it was a normal Func<X, Y>, but we can do some fun things with the lambda expression like automatically generating the name of the facet based on the property or method the user passes in (notice that in the case of a more complex lambda expression, the user must specify the facet name since there is no way to generate a guaranteed user-friendly name for the lambda expression).
Internally, we are using a Dictionary<string, Delegate> to store all the passed in lambda expressions that are going to be used to generate our facets with. In the case where a facet name isn't explicitly stated, we automatically use the name of the Property or Method (depending on which type of expression was passed in):
private Dictionary<string, Delegate> facetGenerators;
public IFacetMap<TResource> AddFacetOn<TResult>(Expression<Func<TResource, TResult>> facetValue)
{
string facetName;
if (facetValue.Body.NodeType == ExpressionType.MemberAccess)
{
MemberExpression expression = (MemberExpression)facetValue.Body;
facetName = expression.Member.Name;
}
else if (facetValue.Body.NodeType == ExpressionType.Call)
{
MethodCallExpression expression = (MethodCallExpression)facetValue.Body;
facetName = expression.Method.Name;
}
else
{
throw new InvalidHeadingExpressionException();
}
AddFacetOn(facetName, facetValue);
return this;
}
public IFacetMap<TResource> AddFacetOn<TResult>(string facetName, Expression<Func<TResource, TResult>> facetValue)
{
if (!facetGenerators.ContainsKey(facetName))
{
facetGenerators.Add(facetName, facetValue.Compile());
}
else
{
throw new NonUniqueFacetAddedException();
}
return this;
}
The last thing we need to do is implement our Generate() method. Here, we are largely going to reuse the LINQ statement from our last post (check it out), the difference being that instead of pulling facets from properties decorated with our attribute we will use out internal dictionary that is built from our AddFacetOn methods.
public IEnumerable<Facet<TResource>> GenerateFrom(IEnumerable<TResource> resources)
{
return from facet in facetGenerators
select new Facet<TResource>
{
Name = facet.Key,
Headings = (from resource in resources
let value = facet.Value.DynamicInvoke(resource)
orderby value
group resource by value into g
select new Heading<TResource>
{
Value = g.Key.ToString(),
MatchCount = g.Count(),
Filter = BuildFilter(facet.Value, g.Key.ToString())
}).ToList()
};
}
private Func<TResource, bool> BuildFilter(Delegate facetValue, string headingValue)
{
return (resource) => facetValue.DynamicInvoke(resource).ToString() == headingValue;
}
And finally, that for every header we generate, we also generate a Filter (shown above). This Filter is of type Func<TResource, bool> so that it can be used in a Where() method to filter our existing list of resources at a later time based on the header that was chosen.
As you can see, there is some cool stuff you can do with LINQ around fluent languages very easily. And not only that, you can add some cool navigational techniques to your application using Facet Mapping that is quite easy to implement using the new features in LINQ.
The first time I saw some talk about this "movement", it was Martin Fowler discussing "Fluent Interfaces". An example Martin gives is the idea of time intervals. Here's how one might declare an interval today (in Java): TimePoint fiveOClock, sixOClock;
...
TimeInterval meetingTime = new TimeInterval(fiveOClock, sixOClock);
Here's how one might to do the same with a fluent interface (anybody who writes Ruby code should recognize this type of programming):
TimeInterval meetingTime = fiveOClock.until(sixOClock);
Like Jeff Atwood, I haven't exactly been a fan of fluent languages in the past (pre-LINQ). I honestly never saw the point in them (and I thought all the object syntax got in the way of what was being done). My mind has definitely changed though. As of late, you could say I'm on a bit of a "fluent languages kick."
LINQ, of course, had a play in this, as did the introduction of lambda expressions. But, it was really seeing two specific libraries that started to get me excited about fluent languages: Moq and NInject. When you compare fluent languages to Regular Expressions and SQL, I can imagine how it's hard to understand the benefit. But when you have a library that reads wonderfully out loud and "fits" an existing problem in order to make it easier to understand, I think it's A Great Thing.
Mocking is a topic I've been pretty passionate about in the past. Even with that passion, there was one thing I didn't like about the libraries back then: breaking changes when refactoring. A lot of mocking frameworks in the pre-.NET 2.0 days were string based. If you wanted to mock an aspect about a method, you put the name of the method in a string and pass that somewhere. Well, the second I renamed that method, BAM!, my unit test would stop passing (of course). Yes, the unit test caught it, but it was still highly annoying. Enter Moq.
Moq leverages lambda expressions to be able to determine what should be mocked. I think the solution Daniel Cazzulino has used is awesome. Let's look at some Moq code to mock some code:
var mock = new Mock<ILoveThisFramework>();
// WOW! No record/reply weirdness?! :)
mock.Expect(framework => framework.ShouldDownload(It.IsAny<Version>()))
.Callback((Version version) =>
Console.WriteLine("Someone wanted version {0}!!!", version))
.Returns(true)
.AtMostOnce();
I love how this reads. I think the trick behind groking fluent languages is reading them aloud. Go ahead, go back and read that out loud (just ignore the laughing coworkers, we'll get back at them later :P). Not only does this read very well, but if I refactor/rename the "ShouldDownload" method in Visual Studio, the use of that method in my mocking code will be updated as well.
The other fluent language that got me excited was the work Nate Kohari is doing on NInject. Assuming you are familiar with Dependency Injection, the best way to understand NInject is to drive write into code:
class Samurai {
private IWeapon _weapon;
[Inject]
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
public void Attack(string target) {
_weapon.Hit(target);
}
}
So I have my injection point defined in my Samurai class. My Samurai is going to need an IWeapon. So how do we bind these two together with NInject?
Bind<IWeapon>().To<Sword>();
Once again, read this out loud. It literally reads like "Bind IWeapon to Sword". I just love that (your mileage may vary :P).
One of the things that bothered me about fluent languages in the past was that people would say "they're so great, they read just like our own language". Well, we've been down that route before, and I definitely wouldn't consider myself a fan of COBOL! So why the love for fluent languages?
One of the problems with spoken languages when it comes to programming is that spoken languages are very ambiguous and allow many meanings for a single word or phrase. In order to avoid that problem, I think COBOL became too obtuse. To be exact enough for a programming language while being solely "written language"-esque, syntax becomes annoyingly long.
The reason I like this new trend of fluent languages in .NET is that it introduces the readability of spoken languages while avoiding the obtrusiveness of languages like COBOL. To me, it's like having my cake and eating it too.
Geek Fact of the Day: Do you know the origin of the term "grok"? The term comes from Robert A. Heinlein's book Stranger In A Strange Land.
The latest CTP for Parallel Extensions to the .NET Framework was released out to the intarw3bs today (Go Digg It on Digg and Kick It on DotNetKicks). This is the second major CTP for the Parallel Extensions. If you're the kind of person who likes to just get the latest install and play around, you can find it here. If, however, you are a person who would like to read some resources about the new CTP first, there's a bunch of links for you as well: Here are some of the reactions (or re-announcements) from other bloggers: I think a very important quote from Joe is (emphasis mine): "I'm really excited to see our entire stack finally shipping as one cohesive unit: the data structures we use throughout the implementation exposed publicly (what we now call CDS), a new scheduler built from the ground up, TPL and PLINQ better together, and lots more." I find this release very exciting, especially the "cohesive unit" part. As Ed mentions in the new features post, PLINQ is now running directly on top of TPL, rather than using the ThreadPool like it did before. The data structures used internally are now exposed as CDS. TPL with many improvements to the scheduler. This is a very great CTP for the Parallel Extensions Team. So congratulations to the team! If you want to play around with concurrent programming in .NET, Parallel Extensions to the .NET Framework is the place to be. The team really wants your feedback and, through this feedback, you can help shape the future of concurrent programming in .NET. How exciting is that?!? So go grab the bits, install them, and enjoy! And if you're a Parallel Extensions fan, be sure to Digg It and Kick It!
As I've been digging more into all the C# 3.0 goodness, I've been learning a lot more about lambda expressions, expression trees, query expressions, and all sorts of other things LINQ. One of the cool scenarios I think LINQ-To-Objects enables is the concept of facet mapping. From the facet mapping website: "First, a quick definition of terms (our glossary has more complete definitions). A resource is one of the objects you want to find by navigating a facet map. In this case, the resources are bottles of wine -- specifically, bottles of wine pirated from wine.com and compiled into a sample dataset for this demo. A facet is a certain classifiable characteristic of the resource -- a way to classify something. Here we have "Varietal", "Region", and "Price", which are different ways for different people to classify wines. The different facets allow each of those people to focus on what they want. A heading is an attribute that each bottle of wine might have. Varietals, e.g. Merlot or Champagne, are headings here, as are such appellations as Tuscany or Sonoma Valley. Plenty of other attributes could be headings, like "12% alcohol", or "medium-bodied", or "wine I drank in high school", but we'd have to define more facets to support them. " Undoubtedly, you've seen facet mapping in action on many websites already, whether you are browsing computer hardware at http://www.newegg.com, or searching for cars on http://www.autobase.com. Facet Mapping is a very useful navigation technique. Not only that, it is a very simple technique to implement as well. Defining Facets The first thing we need to do is define our facet headings that we are going to generate pivot points for. Perhaps the easiest way to accomplish this is through the application of attributes. By decorating our POCO's (Plain Ol' CLR Object's) properties with an attribute, it becomes very easy for our facet mapping code to determine what headings it needs to calculate, and how to calculate them. Let's use the context of Cars to discuss facet mapping. A car may have a Make, a Model, and possibly a Year associated with it. Any of these can be facet headings as we will see later. For the sake of this demo, the code is very bare-bones (as you'll see). public class Car
{
public string Make { get; set; }
public string Model { get; set; }
public string Year { get; set; }
}
First, we need some classes that will help us build the results of our facet mapping efforts:
public class Facet
{
public string Name { get; set; }
public IList<Heading> Headings { get; set; }
}
public class Heading
{
public string Name { get; set; }
public int Count { get; set; }
}
In the case of our Car (to put this into context), we may have a Facet for "Make" with a list of the headings that make up our Facet. In the case of a Make Facet, we may have a Heading of "Ford" with a Count of 2, a Heading of "Toyota" with a Count of 5, and a Heading of "Cadillac" with a Count of 8. This data would be used by our UI to generate navigational links that may look like "Ford (2), Toyota (5), Cadillac (8)".
Finally, we need to find what properties of our Car are the ones we will be using to generate a Facet Map from. As mentioned above, in this example we are going to use an Attribute to identify the properties that we will generate our Facets from (again, this is _very_ bare-bones :P).
public class FacetAttribute : Attribute { }
Then, we just need to apply the attribute to our Car class.
public class Car
{
[Facet()]
public string Make { get; set; }
[Facet()]
public string Model { get; set; }
[Facet()]
public string Year { get; set; }
}
In Walks LINQ
This is the point where I start to get really excited. One of the things I love about LINQ, is that you can focus much more on telling the computer what you want done, rather than how it gets done. Instead of working with loops, conditional statements, logic on how to generate counts of values, you can express your intentions a lot easier by using query expressions.
The first thing we need to is get the list of properties that we need to generate our headings for.
var facetList = from p in typeof(Car).GetProperties()
where p.GetCustomAttributes(typeof(FacetAttribute), true).Count() > 0
This will loop through all the property definitions of our Car, and grab only the properties that have been decorated. To complete the LINQ query expression, we now need to get all the unique values for each property and return the number of cars that have that value for that property. This is also where the fun really starts. To do this we are going to use an embedded query expression as follows (lines 3-14)
var facetList = from p in typeof(Car).GetProperties()
where p.GetCustomAttributes(typeof(FacetAttribute), true).Count() > 0
select new Facet
{
Name = p.Name,
Headings = (from c in cars
orderby p.GetValue(c, null)
group c by p.GetValue(c, null) into g
select new Heading
{
Name = g.Key.ToString(),
Count = g.Count()
}).ToList()
};
The "magic" happens on line 6 where we use the embedded query expression to generate a list of Headings for each property. This is also where I think the use of LINQ really starts to shine. For each property we are generating headings for, we are grouping that property by the values of that property. Then we return the values of the property in the grouping and the number of cars that contain each specific value in our list of cars.
You could obviously write your typical pre-LINQ imperative code to generate these Facets, but it sure wouldn't be nearly as fun or easy. And when you're largely treating your objects as data that you need to "query" for information, I think LINQ is the perfect tool to have in your arsenal. Your mileage may vary, but I find this code much easier to read than a bunch of imperative code in loops and conditionals to try to generate the number of cars with each specific value for each specific property.
The Downsides
While the Attribute-based approach is certainly easy to start with, it has many downsides. When dealing with only plain, vanilla, string-based headings, it's not the most extensible approach. Adding numeric ranges to our facet mapping is not the easiest addition, and the attribute-based approach starts to becomes more constrictive the further we try to push it.
In my personal opinion, "implementation difficulty" isn't the most important downside to consider. I personally sense several different "smells" when looking at this code, mostly around design violations when writing object-oriented code. First of all (and probably one of my biggest concerns), our POCOs are not littered with attributes that are meant specifically for the presentation layer. And I don't know about you, but I'm not sure I like my potential domain objects littered with details for the UI. Not only does this smell to me, but if somebody else wants to use my objects and they don't care about facet mapping, they are essentially SOL.
There's also the constraints that happen when trying to extend this model. What happens if I want to facet map around values returned from method calls. I could certainly apply the attribute to the method as well, and then add some more code to our query expression to return properties and method definitions that have the attribute applied to them. But even then, we are start to stretch the readability of the code. And then there is the concern of trying to do facet mapping on values that aren't a specific property or method. For instance, what if I want to generate a Facet on a value that is a combination of two properties? Or a property and a method call? This is obviously not the most flexible solution we could come up with.
Using Attributes also means that our classes are now dependent upon a concrete implementation rather than a more abstract type. If the attribute has a reason to change, our class will potentially have to change as well. Combined with the previous drawback, it seems rather awkward to me that a domain object would potentially be changing because of a modification made to a presentation technique.
Well, if I'm taking about all sorts of downsides to this approach, why discuss this topic at all? Because it's a great learning experience, and gives us a common ground of understanding when we dive into a more C#-3.0-esque approach.
A Different Approach
In the next post in this series, we will talk about a different approach we can to doing facet mapping with LINQ that also happens to be much more sexy and just drips with C# 3.0 goodness. Not only that, but it just so happens to be a fluent interface as well (very fun)! So until then, I hope you enjoyed this trip down LINQ lane.
Don't get me wrong, I absolutely love Technical Evangelism and enjoyed my first role here at Microsoft doing evangelism around Windows Server 2008. But now that I've transitioned back into evangelism of .NET technologies, I feel like I'm "home again." Before joining Microsoft, I was very passionate about design, pragmatic programming, unit testing, etc. Essentially, all those tools and processes you see actively coined with the term "ALT.NET" now. Even though the term wasn't coined yet, I consider myself a long-time ALT.NET-er. With my first role here at MS though, I took a deeper dive into native technologies and more lower-level development. It was a lot of fun (as I love understanding the internals of systems and how operating systems work). I guess I didn't realize how much I missed my fellow pragmatic .NET developers until I was away from them. Cheesy, I know. But true. So, with all that said, I have one thing to say in closing: it's good to be back home!
Hello, everybody, I have released the first version of a rudimentary managed wrapper around Transactional NTFS to Code Gallery on MSDN: http://code.msdn.microsoft.com/txfmanaged.
The wrapper in its current form is very basic but should give developers a good idea on how simple it is to use Transactional NTFS from managed code. Feel free to go grab it, play around with it (there are some sample screencasts using the wrapper on the Developer Meet Server Show), and feel free to use it any way you wish.
Enjoy!
In my previous post, I talked about why I personally love C++/CLI as a solution for managed and native interop. With the launch of Visual Studio 2008, and the include of the new marshalling library, there is on part of the equation missing, I believe. On the C# side of the interop equation, you have http://www.pinvoke.net. When I'm wanting to interop with a given Windows API, there is a very (very) good chance that the wrappers have already been posted onto pinvoke.net. While the marshal_as<> construct of the marshalling library in VC++ 2008 is quite extensible through the use of templates, there is no community site for me to go to in order to retrieve an existing piece of the interop puzzle. That is, until now. With the help of Kate Gregory, there is now a new website for those C++/CLI users out there: http://www.marshal-as.net. If that link doesn't work for you, give it a day or two as this is a new website and DNS is still propagating for it. I have already sent Kate a couple of samples that I had done for my own interop work with Visual C++ 2008 (have I mentioned yet how easy my life is now that I'm using C++/CLI in Visual C++ 2008?). You should pop over and check it out. If you have your own samples that you want to submit, feel free to use the contact form (the email icon) at the website and email your sample to the website. Enjoy!
Lately, I've been getting a lot more serious about cutting out some time to learn a functional or dynamic language. After watching several Channel 9 videos while traveling today (and listening to several podcasts), I've realized that I've started to grow not only "complacent", but a bit frustrated as well with static languages (currently VB and C#).
It came to mean when I was defining a class. I was working on the properties of that class, of course using encapsulation (read: public properties backed by private fields). Property, after property, after property. Yes, there are some shortcuts by using code snippets. But still, that's a HECK OF A LOT of typing merely for "infrastructure" code. It takes quite a while to get _through_ that infrastructure until I can actually start writing the good stuff.
Now, I realize I could cut those frustrations by just having public fields and the like, but that's not the point. Besides, I think that leads to ugly code that's harder to maintain and just has stronger coupling to dependencies than their needs to be.
This is where I think I would like working with a dynamic language (I remember doing some of this stuff in Python). Instead of going and defining a property in a class, I just use it elsewhere, without having to define it elsewhere. From then on out, it's available to everyone. This way, I could be writing "The Good Code" from the start. Not of this infrastructure stuff. Of course if I went this way, I would certainly have to be doing a lot more unit testing than I do today when I write code to catch those errors you get at compile time in a static language.
Perhaps I will look at writing some XNA code via IronPython, that might be fun.
Another type of language I want to learn are purely functional languages. I want to get into things like High-Order Functions (currently, I like to think I'm somewhat bright, but the idea of a Function that accepts two or more functions as _parameters_, and _returns_ a function on top of that makes my head want to explode).
Regardless, of all this, I feel that I have a lot to learn to become a better programmer. As a programmer, I was practically born-and-raised on C#. Granted, lately I've one back, learned, and program(med) in C and C++ (and I will so in the future as well when I start digging away at future concurrency technologies coming from Microsoft). I think to make the next step as a developer, I need to get away from statically-typed, imperative, object-oriented languages and diversify.
Have any of you (my readers (well, those readers that aren't my family and write code (if there are ANY of you out there :P))) experienced this feeling as well? Do you currently use a dynamic or functional language? What do you like about it over a language like C# or Java?
Well, another day, more work done, more lessons learned, and some new and exciting discoveries and announcements made as well. First of all, Soma |