Useless Realizations

Saturday, April 18, 2009

I was writing a compiler, for my own "fun", and had the realization that C# v3.5 can be very succinct. I had built out my lexer and was roughing out a target lisp-like syntax when I realized it was just like the C# I was writing.

private static Token GetToken(char p, IEnumerable validTokens)
{
return validTokens.FirstOrDefault(item => item.Value.Contains(p));
}

(define GetToken [p validTokens]
(first validTokens (define [item] (contains (value item) p)))
)

I have not decided if this is proof I have lost my imagination or C#'s progress as a language.

IOC Containers - Part 3

Saturday, November 15, 2008

A little thinking after the last post lead me to the idea of persisting objects beyond the scope of a running program, a super singleton. Because an IOC container abstracts the source, and in some ways the lifespan, of an object, there is nothing stopping me from persisting the object and using it between application instances or other systems. The code would never have to know.

I used db4o in my code because of the simplicity, and native object storage. If you have never used db4o, I suggest it.

Also, this provider required explicit disposal, so I went back and implemented IDisposable on the Repository and the SingleServiceProvider.

Usage:

var r = new Repository();

r.RegisterServiceProvider(new SingleServiceProvider());

r.Register<IObjectContainer, SingleServiceProvider>(() => Db4oFactory.OpenFile("test.db"));
r.RegisterServiceProvider(new DB4OSingleServiceProvider(r.GetInstance<IObjectContainer>()));

r.Register<IMyClass, DB4OSingleServiceProvider>(() => new MyClass("a"));

IMyClass m = r.GetInstance<IMyClass>();

r.Dispose();

Code:

public class DB4OSingleServiceProvider : IRepositoryServiceProvider, IDisposable
{
private readonly Dictionary<Type, object> objects = new Dictionary<Type, object>();
private readonly IObjectContainer container;

public DB4OSingleServiceProvider(IObjectContainer container)
{
this.container = container;
}

~DB4OSingleServiceProvider() { this.Dispose(false); }

public void Remove(Type targetType)
{
var resultSet = this.container.Query(targetType);
while (resultSet.HasNext())
{
this.container.Delete(resultSet.Next());
}
this.container.Commit();
}

public void Update(object o)
{
this.container.Store(o);
}

#region IRepositoryServiceProvider Members

public void RegisterService(Type targetType, FactoryDelegate factoryMethod)
{
var resultSet = this.container.Query(targetType);
if (resultSet.Count < 1)
{
this.container.Store(factoryMethod());
}
}

#endregion

#region IServiceProvider Members

public object GetService(Type serviceType)
{
return this.container.Query(serviceType).Next();
}

#endregion

[ IDisposable Members … ]
}

I have not resolved how to handle events when the object has not been re-hydrated or dealing with multiple applications touching the same object database. Perhaps I will think about that some other time.

The biggest thing I have learned from this is that building something myself helps me understand. Now I am going to to try Autofac.

IOC Containers - Part 2

My initial IOC container was an automatic factory. When GetInstance was called it executed the stored factory method and returned. You could technically put anything you wanted into the factory method, including a singleton instance or a database call, but it is no better than a standard factory method.

While looking at some of the IOC containers listed in my last post, I noticed the user could select the lifespan of each type. So, I went back to the workbench.



I have abstracted out the lifespan from the repository, through the IRepositoryServiceProvider interface. This change also opens up the possibility for creating custom lifespans.

Usage:

var r = new Repository();
r.RegisterServiceProvider(new FactoryServiceProvider());
r.Register<IMyClass, FactoryServiceProvider>(() => new MyClass("a"));
IMyClass m = r.GetInstance<IMyClass>();

Code:

public delegate object FactoryDelegate();
public delegate T FactoryDelegate<T>();

public interface IRepositoryServiceProvider : IServiceProvider
{
void RegisterService(Type targetType, FactoryDelegate factoryMethod);
}

public class RepositoryPlusOne
{
private readonly Dictionary<Type, IRepositoryServiceProvider> providers =
new Dictionary<Type, IRepositoryServiceProvider>();
private readonly Dictionary<Type, IRepositoryServiceProvider> types =
new Dictionary<Type, IRepositoryServiceProvider>();

public void Register<T, U>(FactoryDelegate<T> factoryMethod)
where T : class
where U : IRepositoryServiceProvider
{
Type u = typeof(U);
Type t = typeof(T);

if (!providers.ContainsKey(u)) throw new ArgumentException("Unregistered Provider", "U");

providers[u].RegisterService(t, () => factoryMethod());
types.Add(t, providers[u]);
}

public void RegisterServiceProvider(IRepositoryServiceProvider provider)
{
providers.Add(provider.GetType(), provider);
}

public TService GetInstance<TService>() where TService : class
{
Type t = typeof(TService);
if (!this.factories.ContainsKey(t)) return default(TService);
return this.factories[t]() as TService;
}
}

public class FactoryServiceProvider : IRepositoryServiceProvider
{
private readonly Dictionary<Type, FactoryDelegate> factories =
new Dictionary<Type, FactoryDelegate>();

#region IRepositoryServiceProvider Members

public void RegisterService(Type targetType, FactoryDelegate factoryMethod)
{
factories.Add(targetType, factoryMethod);
}

#endregion

#region IServiceProvider Members

public object GetService(Type serviceType)
{
return (factories.ContainsKey(serviceType)) ? factories[serviceType]() : null;
}

#endregion
}

public class SingleServiceProvider : IRepositoryServiceProvider
{
private readonly Dictionary<Type, object> objects =
new Dictionary<Type, object>();

#region IRepositoryServiceProvider Members

public void RegisterService(Type targetType, FactoryDelegate factoryMethod)
{
objects.Add(targetType, factoryMethod());
}

#endregion

#region IServiceProvider Members

public object GetService(Type serviceType)
{
return (objects.ContainsKey(serviceType)) ? objects[serviceType] : null;
}

#endregion
}

IOC Containers

Friday, November 14, 2008

Inversion of control is an interesting pattern, but it has a flaw. When building a system following the IOC pattern, the code bloat seems to bubble up to the top. The higher level objects start creating and managing all the required parts. This starts to fall down when you scale it up beyond a small number of objects. The accepted solution is to move most of the object creation into an IOC container, like Windsor, StructureMap, Autofac, etc.

You register a type, and dependencies, with the IOC container and then just ask for it when you need it. That is great, except I don't know how or why they work the way they do. Most people have responded to my questions with the classic open source creed, “you can look at the source.” Reading the source is like reading a scientific research paper. So, I tried building one myself.

public delegate object FactoryDelegate();
public delegate T FactoryDelegate<T>();

public class Repository
{
private readonly Dictionary<Type, FactoryDelegate> factories =
new Dictionary<Type, FactoryDelegate>();

public void Register<T>(FactoryDelegate<T> factoryMethod) where T : class
{
this.factories.Add(typeof(T), () => factoryMethod());
}

public TService GetInstance<TService>() where TService : class
{
Type t = typeof(TService);
if (!this.factories.ContainsKey(t)) return default(TService);
return this.factories[t]() as TService;
}
}

After a few hours of tinkering, my basic IOC container is 16 lines, including error handling.

Usage:

var r = new Repository();
r.Register<IMyClass>(() => new MyClass("a"));
IMyClass m = r.GetInstance<IMyClass>();

A factory method is registered for each type you want the Repository to handle. Each time the GetInstance method is called, it retrieves the stored factory method, executes it, and returns a strongly typed result. I think I will explore this a little more.

Musicals and Theater

Saturday, July 19, 2008

The theater production and the musical are not dead. But I do think they are making themselves inaccessible. Doctor Horrible's Sing-Along Blog shows a promising path.

I would watch more theater and musicals if it was as accessible as a music video on YouTube.

I will welcome the day this bandwagon comes.

The Role of Web Browsers

Friday, July 11, 2008

I found an old blog post from a greggles. I don't know who he is, or what he does, but he has a good point. The web application inside the browser is ideal for simple applications, but starts to suffer with higher complexities. Now, you could argue, any number of client side frameworks(AIR, Silverlight 2, Gears, etc) would solve this problem, but it still raises a question on the role of web browsers as a whole.

History Lesson:
The web browser was designed as a document viewer for files on a remote server. Every browser and standard was built to support that. With time, people grew tired of bread and water. So, now we have a "rich" ecosystem of web applications hosted at every point on the globe.

Analysis:
If you generalize enough, the browser, as it stands today, is a platform for developers to write applications that are compatible with multiple OSes, have built in deployment, change management, and sandboxing,
and are ubiquitous. As a programmer, I know all the features listed are surmountable with existing programming techniques and focused effort.

My Question:
Should the web browser continue to take on this role as programming platform?

My Conclusion:
The logical path is to have the web browser evolve into a pure data format viewer component and run applications inside an isolated virtual machine. With an automated system for synchronizing code and data, all the points from above can be solved while allowing for the full use of libraries, tools, and languages available to system programmers.

Now I just have to figure out how to make it easy to use and build it for free.

[Edit] (2008.07.20) I just read the wikipedia entry for application virtualization expressing a better point. Oops. Next time I will think about researching something first.

Virtual Development Environments

Sunday, June 01, 2008

Summary: If you have the VM hardware extensions, just develop inside a VM. I suggest VirtualBox.

Through curiosity, and work, I encounter more programming stacks than one machine can handle. My home machine previously contained Android, Python, PHP, .Net, Flex, Ruby, and other stacks resulting in a slow machine and configuration rivaling a game of Pickup Sticks. It also made moving between machines a big pain point.

My work machine started to feel the same strain with a WAMP and an ASP.Net stack when, while fixing a coworker's laptop, I found other people had the same problem. Their specific machine was running three different web servers and four different databases, not to mention the two IDEs and a smattering of smaller tools. At that moment I realized a VM was more than an instant server. It solves the "spew" problem, when software throws-up dependencies all over your machine for its own benefit. Your "spew" factor increases with the number of programs installed, and it can get messy very quickly.

From that point on I have developed my projects in a VM. I have one VM per programming stack and a base image to quickly copy when I need a new one. I should note that I use VirtualBox in seamless mode with the VM hardware extensions (VT-x / AMD-V).

Tips:
1. Get more RAM and a faster hard drive.
2. Skip Vista unless you need it.
3. Ditch both Microsoft Virtual PC and Microsoft Virtual Server.
4. Defrag the host OS more often.
5. Choose a different theme for your guest OS.

3D Printing

Saturday, September 29, 2007

I like the idea of 3D printers. You have a device that can repeatable produce low volume, highly customizable items. This won't change the Henry Ford assembly line approach. The assembly line is great at producing large quantities of exact copies.

So, it stands to reason the best initial application for 3D printing would be clothing. Clothing has very high variety (style, color, shape, size, etc), and thus low volume. (With the assumption that the current size system is a generalization to help mass production.)

Use Case:
You walk into a store full of samples, and find something you like. Step into the 3D scanner for measurements (already exists, and in limited use). The printer then prints a tailored shirt, shorts, etc.

The new "Old Navy" would maintain its standing by using different materials, machines, designs, and public image. Thus duplicating the current model.

The scanner would not be required for clothing production, you could save your last scan and provide it to the store.

It could also be applied to online shopping. You order a pattern and take it to be printed at a store's printer. Of course, you would suddenly get piracy and DRM problems just like other industries that cannot cope without exclusivity.

Lightning Makes the Economy Go Round

Monday, September 03, 2007

A few days ago, I arrived home to a clock flashing 12:00, a dead modem, damaged router, and no sound from my computer. After replacing all the dead components, I turned to my router.

The WAN port was the only part damaged in the strike. So, I felt I could save my router. During a previous failure I flashed my router with the DD-WRT firmware, thus making it, in my opinion, fully configurable. A few hours of searching yielded an architecture diagram. (Note: I have a Linksys WRT54GL v1.1. Other Linksys routers might have a different structure.) I combined it with the instructions on http://www.dd-wrt.com/wiki/index.php/WAN_Port and http://www.dd-wrt.com/wiki/index.php/VLAN_Bridging_WAN_and_a_LAN_port, and moved one of the LAN ports to VLAN1. One router saved by Linux. Go Linux.

The future of mystery meat

Monday, March 19, 2007

I love watching the old “Home of the future” films and thinking about the ideas they came up with. Sometimes, I am pleasantly relieved.

Many of the “Future Interfaces” I have seen are flashy mash-ups of current metaphors mixed thoroughly with mystery meat (to add mystery). http://en.wikipedia.org/wiki/Mystery_Meat_Navigation

http://honeybrown.ca/Pubs/BumpTop.html
My PC already organizes my files better than I organize my desk. I guess everyone forgets the time before Align to Grid was added in Windows. The only plus I see is the addition of physics to the computing experience.

http://www.tactile3d.com/tac.php?opt=overview&subopt=docs
Where did I put that bash script to close the Velociraptor cages?

http://asktog.com/starfire/
Sorry Tog, but Starfire also fits into this category. I admire many things about the Starfire concept. It has the document centric approach, complete integration with all systems, interoperability of programs, big honkin’ screens, and much more. But, where are the giant lists of verbal commands available to the user? Where is the letter “I" on that keyboard? This system would require as much training as a jet aircraft. (That might not be a bad thing.)
I still would advise anyone interested in feeling depressed about where we are in mainstream computing to watch it and read Alchemi’s blog entry afterwards (http://alchemi.co.uk/archives/hum/2_past_projecti.html).

But, don’t take my word for it. (Geordi La Forge)

http://video.google.com/videoplay?docid=4750948381745911864
MSR TaskGallery

http://video.google.com/videoplay?docid=455297590267492017
interactive desktop 3D handelprojector handeled projector

http://video.google.com/videoplay?docid=-8100222800051574872
2010 vision

http://video.google.com/videoplay?docid=-2711786759085611061
Andy Wilson @ Microsoft Research

http://video.google.com/videoplay?docid=-3304682858126153303
Linux XGL

http://www.msdewey.com/
No explanation necessary.