Friday, October 17, 2008
Hatin' on GOTO
There are a myriad of evil uses for the GOTO statement, in any language, it's true. My early days of programming were riddled with spaghetti code issues, especially once any of my far-too-ambitious projects attained a sort of critical mass. I remember in my early days of QuickBasic getting to around 15k lines of code (all in one huge Sub) being absolutely mystified as to why I could never finish anything...
I eventually grew up a bit, and as I encountered Visual Basic (at around version 3) I came to much the same conclusion as Mr. Dijkstra did; that the GOTO statement was the single greatest cause of error and confusion in software programming.
Looking back now, however, that might have been an error.
The problem isn't necessarily with the GOTO statement in and of itself, but rather with the willingness of the programmer to use the GOTO statement as a quick-fix way to get out of a sticky situation. In my QB days I indulged in this particular sin with impunity, only to wonder why my projects self-destructed not even a third of the way in.
The crime I committed was not in using GOTO, but rather in using GOTO incorrectly, and for incorrect uses. GOTO for me was a hammer, and all my program logic flow problems were nails - I wasn't shy in applying my tool - however to place the blame for my failings on the GOTO statement is a deception.
GOTO is a tool. It is a useful tool, sharp, though perhaps diminished in this age of WHILEs, DOs, FOREACHes, and the like, but still useful nonetheless. Be aware of its danger, however, in that it allows you to fall into your own traps. But should it be abolished because it is such a sharp tool?
square root function update and code coloring
Second, thanks to Guy Burstein for the new code syntax highlighting add-in I'm using for the blog. I was using a javascript syntax colorer, but it wasn't working correctly in RSS readers, and it was clunky to use. This new add-in I'm using allows me to copy my source as HTML, preserving the colors as seen in Visual Studio and allowing me to stick with my darker colorings - I'd have had to mess with CSS to get the old javascript colorer to match my settings, and I just didn't have the patience. Also this works properly with C#, F#, XML, HTML - anything VS displays and colorizes. You see it exactly as I see it. =)
Here's a little code sample to demonstrate. This is a little F# function showing off units of measure to calculate the speed at which a body will hit the Earth from a given height in meters, assuming the Earth has no atmosphere... Not terribly useful perhaps but here it is:
1 #light
2
3 open System
4
5 let out p = Console.WriteLine(p:string)
6 let inp = Console.ReadLine
7
8 let prompt p = out p; inp()
9
10 [<Measure>] type meter
11 [<Measure>] type feet
12 [<Measure>] type mile
13 [<Measure>] type second
14 [<Measure>] type hour
15
16 let gAcc = 9.2<meter/second^2>
17 let feetPerMeter = 3.28084<feet/meter>
18 let secondPerHour = 3600.0<second/hour>
19 let feetPerMile = 5280.0<feet/mile>
20
21 let _ =
22 let i = prompt "Enter a value"
23 let v = ((float i) * 1.0<feet> / feetPerMeter)
24 let spd = sqrt (2.0 * gAcc * v)
25 let spdMpH = ((spd * feetPerMeter) * secondPerHour) / feetPerMile
26 out ("from " ^ (string (Math.Round(float v, 4))) ^ " meters: ")
27 out (string (Math.Round(float spd, 4)) ^ " meters/second")
28 out (string (Math.Round(float spdMpH, 4)) ^ " miles/hour")
29 ignore(prompt "Press enter to end")
So, enjoy!
Friday, October 10, 2008
F# square root approximation function
The idea is simple - starting with your number, and a guess at the square root of the number, iteratively refine the guess using simple arithmetic until you've decided that your guess is close enough.
Here's my implementation, in C#:
1 static decimal mySqrt(decimal number, int iterations) {
2 Func<decimal, int, decimal> rec = null; rec = (guess, iter) =>
3 {
4 if (iter == 0) return guess;
5 return rec((guess + (number / guess)) / 2, iter - 1);
6 };
7
8 return rec(number / 2, iterations);
9 }
This implementation uses a recursive lambda function. I could have stuck with a for-loop which would have been more efficient in C#, but my ultimate goal was to use this problem to help me understand F# better. Here's the same function in F#:
1 #light
2
3 let fsqrt n i =
4 let rec guess g i =
5 match i with
6 | 0 -> g
7 | _ -> guess ((g + (n / g)) / 2M) (i - 1)
8 guess (n / 2M) i;;
In both of these functions I'm allowing the caller to specify how many refining iterations to perform. I'm considering writing a method that will determine the fitness of a guess.
I'd like to compare this solution against the official .NET implementation of Math.Sqrt, but unfortunately that function is a stub - it's implemented in MSVCRT by calling the 'fsqrt' opcode, as answered in my StackOverflow question on the subject. If anyone has any more insight into how this works on the processor, please post an answer there - I *really* want to know how it works...
Thursday, October 9, 2008
F#, C#, and games programming
I'll go into details when I have something concrete to show - but for now, suffice it to say that making this game will teach me a great deal about F#, physics algorithms, DirectX, WPF, and C# -> F# interop. I plan on writing everything from scratch - I don't want to use any existing physics libraries, for example - because I want to do some actual learning.
Tuesday, September 30, 2008
x86 assembler in .NET?
I'm one step closer today, thanks to Alex Lyman (whose blog is still under construction - I'll update later with a link) who answered my StackOverflow.com question with his X86Writer library.
Now I can write code like this:
1 byte[] bytes;
2
3 using (MemoryStream ms = new MemoryStream()) {
4 X86Writer writer = new X86Writer(ms, new IntPtr(0x00400a00));
5
6 var start = writer.CreateLabel();
7 var func = writer.CreateLabel(new IntPtr(0x01000000));
8
9 start.Mark(); // start:
10
11 writer.Inc32(X86Register32.EAX); // inc eax
12 writer.Cmp32(X86Register32.EAX, 5); // cmp eax 05
13 writer.Jmp(X86ConditionCode.NotEqual, start); // jne start
14 writer.Call(func); // call 01000000
15
16 bytes = ms.ToArray();
17 }
Really great stuff! I'd still like to be able to pass in a string, though - but this gives me a great platform on which to build!
Notice the support for labels - this really is the start of a powerful library, I think. Oh - and he open-sourced it under the New BSD License - which means everyone's free to contribute. If you have anything you want to add, please send me a patch!
Friday, September 19, 2008
Configuration via IConfigurationSectionHandler
So far, so good - I've managed to unify the API of these disparate web services, but I had run into a stumbling block regarding how to configure these. After several false starts, my team lead suggested implementing IConfigurationSectionHandler. At first I balked (silently) - I can't stand dealing with 2.0 style Xml DOM objects, which IConfigurationSectionHandler uses - but after getting over myself I decided to take a look.
And I'm glad I did - IConfigurationSectionHandler is a *very* simple interface, exposing only a single method:
public object Create(object parent, object configContext, XmlNode section) {...}
For my purposes, 'parent' and 'configContext' weren't necessary - I only needed to concentrate on the 'section' argument. Implementing this was, as I expected, a bunch of Xml DOM code - but it wasn't so bad since the xml I'm working with is very simple.
One of my self-inflicted requirements was to keep the individual shipping carriers in separate assemblies, mostly to make adding a new carrier a no-rebuild operation. I want to be able to create the shipping carrier, drop its assembly into our Bin folder, add a configuration element, and go. So I made use of Assembly.Load to load the assembly in question, and Activator.CreateInstance to create an instance of the concrete carrier implementation. The constructor for the abstract Carrier type takes an IDictionary<string, string> of configuration properties (also gathered through my IConfigurationSectionHandler implementation) which the individual carrier will make use of - things like web service urls, etc.
I am in awe of how easy it was for all this to come together - it took maybe 2 hours, including MSDN browsing, to go from 0 knowledge of the problem to a working implementation that I'm comfortable putting into our production system.
Fun stuff! =)
Friday, September 5, 2008
ASP.NET MVC Preview 5, jQuery, and Validation
I've been given an interesting task - figure out how to provide both client-side and server-side validation of forms, without duplicating the validation logic.
The ASP.NET MVC team just released Preview 5, which, among other bits of goodness, includes the ability to perform server-side validation automagically, and have the results of this validation sent to the view. It's pluggable, much like the rest of the framework.
Meanwhile I went in search of a validation framework (admittedly so I wouldn't have to write my own) and found ValidationFramework - which upon inspection appears to be exactly what I need for server-side validation. It's a well-put-together framework, and has an extensibility model that includes outputing client-side validation for ASP.NET using server controls.
Of course, ASP.NET server controls aren't the best solution when working with the MVC framework, so I considered writing my own adapter layer to generate some Javascript validation from the existing validation rules. I remembered the jQuery Validation plugin and, while I haven't explored it fully, considered that a good starting point.
Well, it seems I wasn't the only one to think so, as this discussion thread shows. I've been in contact with the original poster - Dane O'Connor - and have been reviewing the latest drops of a set of helpers and extensions on both ASP.NET MVC P5 and ValidationFramework that achieves exactly what I initially set out to do on my own!
Now I just have to hope that I'll be allowed by my employer to contribute some code to this project, as we'll be using the system in a production environment. Any improvements we provide would benefit others as well, and since the code is free, I'd like to give something back.
That's it for now.