My blog has moved! Redirecting...

You should be automatically redirected. If not, visit http://ripper234.com and update your bookmarks.

03 September 2007

Practical Database in C#

Today I took Eli's challenge (whether he intended it as such or not not :).

Among other things, he mentioned on his blog his opinion that LISP is a more powerful programming language than C#. He offered Practical as an example of LISP's power. Practical is a very simple database built using very few lines of codes.

The challenge I took on myself is to code Practical in C# and compare the implementation with the one given in LISP.

It took me 2-3 hours to read the link on Practical and code it in C#, and I wrote a great deal more lines of code than what I saw in the LISP code. So in a simple contest, C# (or just me as a coder) lost.

However, here are my thoughts:


  1. About 80% of the code I wrote is general purpose. It simulates abilities already existing in LISP. General-purpose classes I wrote are:

    • ConsoleReader - Reading any class from the Console.
    • DefaultFormatter> and ListFormatter - Pretty-print any object or list.
    • Functors - Functors in C# are called delegates. I didn't find (nor looked too hard) for functions to combine, negate and manipulate delegates - so I wrote some.
    • MoreXmlSerializer - As a naming convention, I like to name MoreFoo any class that contains methods that I believe should have been in Foo from the start, where Foo is some class supplied by the framework. Starting at C# 3.0, the ability to add methods to existing classes is supported, so I could adjust the naming convention accordingly.
    • StringConverter - Convert a string to to a given (dynamic) type.


    Besides this code, the actual Practical C# code is very small and concise.
  2. The C# code is type safe. I'm not aware of type-safety in LISP, though as I said I'm not a LISP pro.
  3. The code I wrote is in C# 2.0. Some new features in C# 3.0 should help make it a bit more concise (especially lambda expressions and LINQ).


I think this experiment didn't change my opinion greatly. Yes, functional programming is good. It exists in C# as well as in LISP. Yes, LISP handles lists very well. But, not everything is life (or in programming) should be represented as a list.

I'm attaching my code here. If you have suggestions or comments, please let me know. Also, once I install Visual Studio 2008 (I'll probably wait for the final release), I might try coding this in C# 3.0 and see how it helps the cause.

5 comments:

ripper234 said...

P.S.

Another useful features in C# 3.0 that will help is Automatic Properties (saves you the trouble of declaring private variables for simple properties).

Also, while looking for C# I came across this article that had a nice implementation of Select.

Eli said...

First of all let me say that your post proves my point - people who learned at least some Lisp earned a valuable way to look at programming problems and apply powerful paradigms to solving problems.

Now, it's really cool that C# has all these functional features, and that in version 3.0 they're adding even more. The dynamic scripting languages like Perl and Ruby have these features for almost 10 years now. In fact, the only thing that's really missing in them from being "a Lisp" is the uniform syntax. But uniform syntax is what allows Lisp macros - and this is a big difference.

Compare your implementation of select and where vs. the Lisp one. While in Lisp the statement:

(select (where :title "Give Us a Break" :ripped t))

Looks like a normal Lisp statement, in C# it's much less natural - you have to create several "where" selections and then explicitly combine them. In the Lisp solution, the "where" macro already does that. Not only that the macro allows for more flexible coding - by code generation - but also it looks much more like just a new part of the language. This is what makes Lisp the best language for writing domain specific languages.

Anyway, I'm not trying to say you can't do everything in C#. You can, it's actually quite a powerful language that is being constantly improved. It also enjoys the support of the best IDE in the world (IMHO, and apologies to all Emacs diehards). My point is that learning advanced functional techniques makes C# programmers better C# programmers.

P.S. Note that in the book the DB isn't actually named "Practical", rather, it's one of the "Practical" chapters which show hands-on examples. There are several other Practical chapters as you can see in the book's table of contents:
http://www.gigamonkeys.com/book/

P.P.S. The MoreFoo naming convention exists in the Win32 API, where it is done as FooEx (i.e. CreateWindow and CreateWindowEx). The goal is the same as yours. Personally I prefer the Ex subscript, because as a subscript it leaves the more important part of the name - the class name itself - first.

ripper234 said...

In C# as well, you can very easily, create a where() method with a variable number of arguments, and parse them to supply the same user interface as the LISP version. I was just too lazy for that :)

Anonymous said...

the notion of turning C# into LISP is ill-conceived at best.
And Eli is a pompous fart.

ripper234 said...

Nobody's trying to turn C# into LISP.

And it's cowardly to call other people by names but sign as anonymous yourself.