Observation: The Absence of Doubt

Observation:

Many beliefs we hold are not from research and careful thought. We could all probably use a little more intellectual honesty with ourselves, and it starts with the right attitude. Avoid the god complex, consider in good faith all possibilities (including those you disagree with on the outset), spend time researching before concluding, study your own viewpoint as much as those that differ from yours (you'll learn something regardless). Socrates had it right: start with knowing that you know nothing.

24. July 2011 00:30 by SirDuck | Comments (0) | Permalink

F# and Continued Fractions

As an exercise in F# and a refresher on Continued Fractions, I decided to put together some functions in F# for converting scalar values into their (Simple) Continued Fraction form, and vice versa. 

My approach for converting from Continued Fraction form to scalar was to utilize F#'s List.foldBack function to accumulate the denominators starting at the deepest level and moving "up". Rather than writing a special case for the terminal (innermost) fraction, I chose to seed the (general) accumulation with Double.MaxValue, amounting to 1.0 / (aLargeValue) or approximately 0 added to the innermost fraction.

For converting from a scalar value to Continued Fraction form, I devised a recursive function (which should, I hope, receive a tail recursion optimization) that constructs the sequence starting at the "top" and moving downward, following the basic algorithm outlined at the Wikipedia page. One of the exit conditions (if this were exact) is to check for a 0 fractional value, however due to numerical error I loosened this check to 0 + 0.1% of the most recent integer term.

Code:

(* functions *)

/// <summary>Converts a number from continued fraction representation to a scalar (binary float) representation.</summary>
let cfToScalar cf = List.foldBack (fun elem acc -> float elem + (1.0 / float acc)) cf System.Double.MaxValue

/// <summary>Converts a number from scalar (binary float) representation to a continued fraction representation.</summary>
let rec scalarToCF (s:float) (maxIters:int) = 
    if maxIters = 0 then Seq.empty
    else 
        let term = floor s
        let fraction = (s - term)
        if fraction < 0.001 * term then
            Seq.singleton (int term)
        else
            let fractionInv = 1.0 / fraction
            Seq.append (Seq.singleton (int term)) (scalarToCF fractionInv (maxIters-1))
Test:
(* testing *)

open System

let piAsCFFromWolframAlpha = Array.toList [|3; 7; 15; 1; 292; 1; 1; 1; 2; 1; 3; 1; 14; 2; 1; 1; 2; 2; 2; 2; 1; 84; 2; 1; 1;|]
let piAsScalarFromDotNet = Math.PI

printfn "π (.NET Framework): %f\n" piAsScalarFromDotNet
printfn "π CF (WolframAlpha): %A\n" piAsCFFromWolframAlpha
printfn "π (cfToScalar): %f\n" (cfToScalar piAsCFFromWolframAlpha)
printfn "π (scalarToCF): %A\n" (Seq.toList (scalarToCF piAsScalarFromDotNet 10))

let rational = 17.0/24.0
let rationalAsCFFromWolframAlpha = Array.toList [|0;1;2;2;3|]
printfn "17/24: %f\n" rational
printfn "17/24 CF (WolframAlpha): %A\n" rationalAsCFFromWolframAlpha
printfn "17/24 (cfToScalar): %f\n" (cfToScalar rationalAsCFFromWolframAlpha)
printfn "17/24 (scalarToCF): %A\n" (Seq.toList (scalarToCF rational 10))

Console.WriteLine "Press any key."
let x = Console.ReadKey()
Console.Write ""

Test Output:

π (.NET Framework): 3.141593

π CF (WolframAlpha): [3; 7; 15; 1; 292; 1; 1; 1; 2; 1; 3; 1; 14; 2; 1; 1; 2; 2;
2; 2; 1; 84; 2; 1; 1]

π (cfToScalar): 3.141593

π (scalarToCF): [3; 7; 15; 1; 292; 1; 1; 1; 2; 1]

17/24: 0.708333

17/24 CF (WolframAlpha): [0; 1; 2; 2; 3]

17/24 (cfToScalar): 0.708333

17/24 (scalarToCF): [0; 1; 2; 2; 3]

Press any key.
31. May 2011 01:27 by SirDuck | Comments (0) | Permalink

js-tipos, a Strong-typing Framework for JavaScript

Now on GitHub, js-tipos, a strong-typing framework for JavaScript. If you're a C#/Java/C++ programmer seeking ways to maintain your sanity in this crazy world called JavaScript, then this framework might be just what you're looking for.

https://github.com/duckmaestro/js-tipos/

Comments, questions, criticisms and forks welcome.

7. March 2011 01:38 by SirDuck | Comments (0) | Permalink

An Ill-Defined Probability Model and the Uniqueness of Labeling

The following started out as a thought experiment about where and how probability theory connects to our perception of the physical world around us. There may be a hole or two in my reasoning, and I'm always open to hearing opinions or questions -- so feel free to comment or contact me about this post!

Review: The Canonical Probability Model

The typical probability model by definition consist of the following:

  1. A set of outcomes Ω.
  2. A set of measurable events S such that
    1. ∀ s ∈ S, s ⊆ Ω
    2. Ω, ∅ ∈ S
    3. S is closed under union and complementation.
  3. A function P: S → ℝ such that
    1. P(α) ≥ 0 ∀ α ∈ S
    2. P(Ω) = 1
    3. α, β ∈ S, α ∩ β = ∅ ⇒ P(α ∪ β) = P(α) + P(β)

I'll call this the "canonical" probability model.

Putting ourselves in the shoes of a designer of such requirements, 3(a) and 3(b) clearly seem physically motivated.

  1. We tend to relate positive numbers to the presence of something, in this case the presence of likelihood. Further, it doesn't make sense that there be anti-likelihoods, but at the same time we can fathom a nil-likelihood. Taken all-together, we require strictly non-negative probabilities (3(a)).
  2. We want to assume that something will occur when measured. We don't envision the universe suddenly disappearing (and if it did we wouldn't be around to measure it). Though there may be some intuition to assume P(Ω) = ∞ ∈ ℝ∪{∞}, why not first keep things simple and try P(Ω) = 1 which is just as intuitive.

And then we come to 3(c). Where's the explanation in physical terms for that?

In this post, we shall construct a real-world -based probability model that violates this third requirement. We will then alter our model to fit 3(c), and compare the two for insights. First though, let's get physical...

Crossing over into the Physical Realm

At some point, a probabilistic model isn't useful unless you can sample the real-world for comparison against your model. The mathematical definitions above have no direct requirement for how your real-world sampling might work (i.e. produce elements in Ω). Let's bridge the gap between the math world and the real-world.

Let's construct a real-world sampling function M: A → 2Ω where A is a set containing imaginably possible, but not directly known whether true or not, physical states. 2Ω is a power set of set Ω of possible outcomes, and each element of 2Ω represents the presence or absence of one or more outcomes possibly perceived by our sampler. It is impossible to know the precise state of the real-world -- we are always relying on samplers (whether biological or electronic or otherwise) for our physical information. Our sampler returning data in terms of Ω enables us then to compare real-world data directly against our probability model built upon Ω.

Before moving on, let's talk about set A and the rationale behind choosing 2Ω.

Regarding A, it's perhaps difficult (or philosophically tedious?) to define all of the elements of A. One can imagine each element of A as a specific arrangement of molecules for some bounded area of the universe. One such element of A might correspond to the molecular arrangement of a quarter facing heads up; or likewise a molecular arrangement corresponding to tails facing up. Regardless, elements of A represent possible or imaginable states of the physical world.

The rationale for 2Ω and not simply Ω is two-fold. Firstly, the same physical state can be perceived in different ways: is that vision yonder a tree, a cluster of green and brown shapes, or an arrangement of molecules? Perception and labels for such are not in absolute terms, but perception is all we have. Thus the best we can do, while maintaining a sort of philosophical generality, is to imagine a construction of Ω that contains many perceptions of the same physical state. Continuing with this idea, we construct our sampler M such that it returns a subset of Ω containing each possible interpretable outcome for a given element or subset of elements in A. Thus we formally define the codomain of M to be 2Ω. For an example, consider Ω = { ..., tree, green & brown cluster of form #1234, molecular arrangement of form #5678901, ... }, and for some A1 ⊆ A, M(a∈A1) = { tree, organism, green & brown cluster of form #1234, molecular arrangement of form #5678901}.

Secondly, it makes sense (if Ω is constructed for such) to have our sampler be able to return the state of two or more outcomes describing the state of the physical world. For an example, consider two quarters in our bounded sub-universe, with Ω = { Q1_Heads, Q1_Tails, Q2_Heads, Q2_Tails }, and for some A1 ⊆ A, M(a∈A1) = { Q1_Heads, Q2_Tails }.

Now that we've defined a real-world sampler and the means for comparison against a probability model, let's see how well an example holds up...

The Ill-Defined Probability Model

Let's construct a probability model from the ground up, starting with A, Ω, and M. Suppose we have a simplified roulette wheel with only two possible values: 1 (red) and 2 (black). We can say "1" is an outcome, "red" is an outcome, "2", is an outcome, and "black" is an outcome. Thus we define Ω = { 1, 2, red, black }. It should be clear that we can create a mapping M: A → 2Ω, such that some subset of A maps to { 1, red } ∈ 2Ω, and the remaining subset maps to { 2, black } ∈ 2Ω (we assume the roulette ball will always land in one of the two slots). We can now sample the real-world for outcomes, for comparison later against the rest of our probability model.

Now let's construct S within our probability model. We can attempt to build a simple version of S by pulling single elements from Ω, but we must be closed under complementation and union. Thus we end up with S = { ∅, {1}, {2}, {red}, {black}, {1, 2}, {1, red}, ..., Ω } = 2Ω.

And finally let's construct P. Let's say we know as a physical matter of fact the roulette wheel is fair, equally favoring each of the two slots. Thus P({1}) = P({2}) = c for some value c. 1 is our value for any event at all occurring, and {1}, {2} are mappable back to the only physically possible events, thus c + c = 1, so that P({1}) = P({2}) = 0.5.

We also know that "red" occurs whenever "1" does, so we can say P(red) = P(1) = 0.5. Similarly P(black) = P(2) = 0.5 for "black" and "2". We also know certain events are mutually exclusive, such as the event { 1, 2 } which has probability 0. We have then P is:

P(α) = {
 0.0 if α = ∅,
 0.5 if α = {1} or {red} or {1, red},
 0.5 if α = {2} or {black} or {2, black},
 1.0 if α = Ω,
 0.0 for all other α
}

It is clear that 2(a), 2(b), 2(c), 3(a), and 3(b) all hold. Testing 3(c) though, our model falls short.

It's true, for instance, that {1} ∩ {red} = ∅, but P({1} ∪ {red}) = 0.5 + 0.5 = 1, which implies we always land on the red or "1" slot. This contradicts our knowledge of how our roulette wheel behaves physically. Thus our model (A,Ω,M,S,P) is not valid as a canonical probability model.

A 3(c)-compliant Model

We know A corresponds directly to imaginable states in the physical world, so there is no changing A in any meaningful way. Further Ω and M are constructed on a philosophically sound basis, I believe. So let's reconsider the construction of S, our measurable events.

We, as sophisticated observers, can perceive both the difference between red and black, and the presence of two unique symbols "1" and "2".  We are able to see that perception of the red slot occurrence is inseparable from perception of the "1" slot occurrence, so let's simplify S as S' = { ∅, { 1, red }, { 2, black }, { 1, 2, red, black } }. It can be verified that S is closed under union and complementation.

Rebuilding P yields:

P'(α) = {
 0.0 if α = ∅,
 0.5 if α = { 1, red },
 0.5 if α = { 2, black },
 1.0 if α = Ω
 0.0 for all other α
}

Again, 2(a), 2(b), 2(c), 3(a), and 3(b) hold. Further, it should be clear that 3(c) now holds in this case for all α, β ∈ S', and so our revised model (A,Ω,M,S',P') is valid as a canonical probability model.

What is the Essence Here?

Comparing our non-canonical and canonical models, what is the difference? Well, essentially the canonical model requires uniqueness in the labeling of measurable events. In our initial model (A,Ω,Μ,S,P), the same fundamental, physical state is ultimately mapped to multiple l abels (elements) in S. In our revised model (A,Ω,Μ,S',P'), each unique (in a vague sense of the word) physical state is mapped to a single element in S. 

In fact any set S'' of measurable events that contains one or more elements not unique to a particular subset of physical states will lead to a non-canonical probability model.

Proof:

Let (A'',Ω'',Μ'',S'',P'') be a model such that:

  1. 1, 2(a-c), and 3(a-b) hold from the canonical probability model.
  2. A'' is a set of imaginable physical states.
  3. M'' is a sampler function A'' → 2Ω such that for each ε1 ∈ Image(M''), there is a unique subset A1 ⊆ A'' such that M''(a∈A1)=ε and M''(b∉A1) ∩ ε = ∅.
  4. For a subset A2 ⊆ A'' there exists an ε2 ∈ Image(M'') such that M''(a∈A2)=ε2 and |ε2| ≥ 2.
  5. There exists some non-empty s1 ∈ S'' such that s1 ⊂ ε2 (strict subset), and P''(s1) > 0.

Because s1 is a strict subset of ω, there exists some non-empty s2 ⊂ ε2 - s1. Because s1 and s2 are subsets of ε2, M''(a∈A2)=ε2 always indicates both s1 and s2. Further, because s1 and s2 are only found when states of A2 are sampled, P''(s1) = P''(s2). Let γ = P''(s1). From above we have γ > 0.

Let's now assume 3(c) holds. Because s2 ⊂ ε2 - s1, we have s1 ∩ s2 = ∅. Thus by 3(c), P''(s1 ∪ s2) = P''(s1) + P''(s2) = 2γ. However s1 ∪ s⊆ ε2, thus (s1 ∪ s2) is sampled by M'' whenever s1, s2 are, which implies P''(s1) = P''(s1 ∪ s2) or γ = 2γ. But γ > 0, thus we have a contradiction and 3(c) does not hold. Q.E.D.

By contrapositive, we have that 3(c) in the canonical model implies that each subset of A'' with a corresponding element in S'' has a unique such element in S''. In other words, S'' has unique labels for physical states.

We now have a explanation in a physical (or philosophical :)) context for requiring 3(c) in the first place -- it demands we (arbitrarily) choose a unique way of perceiving and labeling each class of physical outcomes!

15. August 2010 15:59 by SirDuck | Comments (0) | Permalink

Per-pixel Alpha Blending in Win32 Desktop Applications

It took a bit of research and experimenting, but I was able to correctly achieve per-pixel alpha blending in Windows desktop applications. In addition to having tested it on Windows XP SP3 and Windows 7, the code also detects failure in the alpha blend and will fall back to the chroma keying method instead (which seems to be necessary for Remote Desktop support).

Example of Per-Pixel Alpha Blending in Windows 7:

 

Preparing The Image

For this example, I've prepared an image with some text on a colorful, pixelated background.

Color

Alpha

Seeing the alpha channel, it should be apparent that the magenta regions of the color image will actually be unseen when drawn to screen. Theoretically I could have chosen any other color for those regions; however, the code below also must be able to resort to simple chroma keying if necessary, in which case magenta is often used for it's lack of occurrence "in the wild".

Though shown separately, each were combined and exported to a single BMP (Windows Bitmap) file from Photoshop CS4. Originally I hoped I could craft my image using typical Photoshop practices, however this proved unacceptable during export. I have no idea why, but Photoshop would not export transparency layers to BMP and still preserve color and alpha properly. Instead, it was flattening my layer to a white matte, and exporting a 24-bit BMP with no alpha channel.

So, in order to export correctly from Photoshop, I needed (once satisfied with the transparency look and feel) to edit in a Custom Channel (which I named "Alpha"), and remove the transparency from my primary channels' layer altogether. Once this is done, you will see the BMP option to export alpha channel, and can choose a 32-bit format along the way.

The Essential Code

Create your window instance using WS_EX_LAYERED. This instructs Windows to treat your graphics output differently. In particular, this causes Windows to hold an additional buffer for your graphics output (I believe), and causes Windows to render your graphics output with chroma keying or alpha blending enabled.

	
//////
// Win32 setup

// create the window class
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = TEXT("Splash");
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wcex);

// create the window instance
hWnd = CreateWindowEx(
	WS_EX_LAYERED, // <---- !!!!!
	TEXT("Splash"), 
	TEXT("Splash"), 
	WS_POPUP,
	x, 
	y, 
	g_iSplashImageWidth, 
	g_iSplashImageHeight, 
	NULL, 
	NULL, 
	hInstance, 
	NULL
);

 

Next, you must ensure your pixel colors have been premultiplied against their respective alpha values. This is a requirement of the Win32 API in order to achieve the proper and intended results. In my case, I was not able to export from Photoshop a proper 32-bit BMP file with premultiplied alpha, so I perform this at load time. If you run an off-line tool or otherwise have premultiplied pixels, then it is not necessary to perform this step. To see an example of pre-multiplying, see the downloadable source code attached to this post.

With our image pixels premultiplied, we are now ready to render to the Windows display.

//////
// WNDPROC

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_CREATE:
		if(g_bUsePerPixelAlpha)
		{
			// try the per pixel method
			bool bPaintSuccess = Paint(0, 0, hWnd);
			

	// ...
}


//////
// Specialized Paint method
bool Paint(HDC hdc, PAINTSTRUCT* ps, HWND hWnd)
{
	// ...


	// setup a "back buffer" to be same pixel 
	// format as the screen DC and same dimensions
	// as source image.
	HDC hdcScreen = GetDC(NULL);
	HDC hdcBackBuffer = CreateCompatibleDC(hdcScreen);
	HBITMAP hbmBackBuffer = CreateCompatibleBitmap(hdcScreen, g_iSplashImageWidth, g_iSplashImageHeight);
	HGDIOBJ hbmOld = SelectObject(hdcBackBuffer, hbmBackBuffer);

	// copy source image to backbuffer
	SetDIBitsToDevice(
		hdcBackBuffer, 
		0,
		0,
		g_iSplashImageWidth,
		g_iSplashImageHeight,
		0,
		0,
		0,
		g_iSplashImageHeight,
		g_pSplashImagePixels,
		reinterpret_cast<BITMAPINFO*>(g_pbmiSplashImage), 
		0
	);

	// inform Windows that we have new graphics data available.
	POINT ptSrc;
	ptSrc.x = 0;
	ptSrc.y = 0;
	SIZE size;
	size.cx = g_iSplashImageWidth;
	size.cy = g_iSplashImageHeight;
	BLENDFUNCTION bf;
	bf.AlphaFormat = AC_SRC_ALPHA;
	bf.SourceConstantAlpha = 255;
	bf.BlendFlags = 0;
	bf.BlendOp = AC_SRC_OVER;
	if(!UpdateLayeredWindow(hWnd, NULL, NULL, &size, hdcBackBuffer, &ptSrc, 0, &bf, ULW_ALPHA))
	{
		SelectObject(hdcBackBuffer, hbmOld);
		DeleteDC(hdcBackBuffer);
		return false;
	}
		
	SelectObject(hdcBackBuffer, hbmOld);
	DeleteDC(hdcBackBuffer);
	return true;
}

 

Can this method fail? Yes. In particular, it seems this method is not supported under Remote Desktop connections, and infact will fail immediately but yield no specific error code from GetLastError(). The source code provided will respond to this failure and fall back to a chroma keying method that is supported (as far as I have seen) under Remote Desktop connections.

if(!bPaintSuccess)
{ // per pixel failed
	// switch to chroma key method.
	g_bUsePerPixelAlpha = false;
	SetLayeredWindowAttributes(hWnd, CHROMA_KEY, 255, LWA_COLORKEY);
}

Epilogue: UpdateLayeredWindow vs. SetLayeredWindowAttributes

Lastly, there are some important differences between UpdateLayeredWindow() and SetLayeredWindowAttributes(). Once you create your window with WS_EX_LAYERED, you have two options:

I. Do nothing else:

  1. Allows the full range of blend effects -- opaque, uniform transparency, chroma-keying, and per-pixel alpha.
  2. WM_PAINT messages are no longer fired -- you must initiate and perform the rendering of your window yourself.

 

or II. Call SetLayeredWindowAttributes():

  1. Allows opaque, uniform transparency, and chroma-keying blend effects. Per-pixel alpha is not possible.
  2. WM_PAINT messages continue to fire as normal.

 

Source Code & Acknowledgments

The full source is available here, AlphaBlending.zip (103.07 kb), and includes the photoshop file and exported BMP.

The following posts were helpful in my quest:

  1. http://www.autohotkey.com/forum/topic24628.html&sid=b09d522553d07c4ae0a834fc21239635
  2. http://www.gamedev.net/community/forums/topic.asp?topic_id=449081&whichpage=1&#2970300
  3. http://msdn.microsoft.com/en-us/library/ms997507.aspx

 

6. June 2010 04:43 by SirDuck | Comments (0) | Permalink

Real-Time Water Flow Simulation and Visualization (Video)

By request, I've posted a video (available in 720p) of the Water Simulation below:

At the start of the video, the sim has been initialized with random height values. Once the simulation begins, you can see the effects of gravity take place immediately. Downward (actually radially outward) forces are then applied to the pool.

Comments/questions welcome.

1. June 2010 03:31 by SirDuck | Comments (0) | Permalink

HTML5 Game Engine

The HTML5 game engine begins! Let her henceforth be known as "JameE".

http://code.google.com/p/jamee/

It's off to a good start, with good encapsulation thus far and asynchronous loading of images, scripts, and serialized (human-readable) objects.

Want to participate? Let me know.

2. April 2010 10:45 by SirDuck | Comments (0) | Permalink

Open-Source Software

A convincing and informative talk on the what and why of open-source software.

http://www.youtube.com/watch?v=hmZyyBVbkOQ

 

 

29. March 2010 03:57 by SirDuck | Comments (0) | Permalink

Thread Pools

So you've decided you want to multithread something? Well, the first question you should ask yourself is (after reading this article of course!) -- "should I use the thread pool?". Here are some basics on what a thread pool is and why you should (or shouldn't) use one.

Thread Pool

  1. Manages a pool of already allocated, reusable threads, available for your evil bidding.
  2. Maintains a queue of tasks, or a to-do list if you will. This list holds on to whatever tasks give the thread pool.
  3. As long as there are tasks to do, the pool keeps its threads busy doing those tasks. Once a thread finishes a task, it moves on to a new task if there is one.
  4. Minimizes the cost associated with creating/destroy threads, because threads are reused instead of created/destroyed.
  5. Minimizes system resource usage by limiting the number of threads it will ask the operating system or virtual machine for.

When to Use a Thread Pool

  1. If you're concerned about your main thread being held up for too long on less-than-important pieces of logic, then you should consider off-loading some of your algorthm to the thread pool.
  2. Thread pools are meant for tasks that will completely relatively quickly. Imagine a line of people and your task is a person -- if you are holding up the line, you are preventing everyone else from doing what they need to do too. Though this is what you wanted to avoid in the first place with regard to your main thread, if too many threads are taking too much time it begins to defeat the purpose of the thread pool, as well as rob other, possibly more important, tasks in the queue of timely completion.
  3. You have tasks that can be broken down into isolated chunks of work with no or relatively simple interdependencies.

When not to Use a Thread Pool

  1. If you're writing high-performance code and are multithreading to that end, requiring fine-grained control over your threads.
  2. If your tasks are highly interdependent and require complex signaling or cross-thread communication.
  3. If your tasks need to complete in a semi-predictable order.
  4. If you need to ensure a thread is on standby so-to-speak, ready at any moment for a particular task.

Other Things to Keep in Mind

  1. Many if not all of the possible trouble-makers when writing multithreaded code also apply to thread pools. Stay mindful.
  2. Because threads are reused from task to task, thread-specific data or state may carry over from the last task to the next task. For example the next task may find unexpected data in variables marked for thread-local storage.
  3. Don't take the attitude of, it's in a separate thread now so I don't need to care about unhandled exceptions. Wrong! The thread is still a thread. Some APIs/runtimes will raise an error for the whole process if a thread has an unhandled exception.

A Quick C#/.NET Example

ThreadPool.QueueUserWorkItem(
    new WaitCallback(
        delegate(object state)
        {
            // do something asynchronously
        }
    )
);

C# is great in this instance because we can use an anonmyous method (and the closure it creates for us) to very easily off-load a subtask to the thread pool. Very painless!

Lastly...

Not all thread pools are created equal. Check the documention on the thread pool or API you are working with to get a better idea of it's features and limitations!

17. March 2010 08:24 by SirDuck | Comments (0) | Permalink

Anonymous Functions

Introduction

Knowing how to use anonymous functions (or anonymous methods) is a critical piece to have in your programming playbook. It's a great technique for quickly building up proof of concept code or first iteration code, and over the lifetime of a project save many hours of work when properly applied. Lucky for us, the "anonymous" aspect doesn't have to be mysterious.

Basics

Let's start with some examples in JavaScript (a.k.a. ECMAScript). Note that the (near) equivalent of an anonymous function in C# is the anonymous method, and I'll speak on some of the differences between the two later.

A Basic Function (JavaScript)

// a definition
function AddAndAlert(x, y) {
    var result = x + y;
    alert(result.toString());
}

Firstly, the inner logic here is probably a bad idea in practice, as it couples a data operation with a user interface operation. Disclaimer aside, this is what your basic function in JavaScript looks like.

An Anonymous Function (JavaScript)

// an expression
function(x, y) {
    var result = x + y;
    alert(result.toString());
}

What's different here? Well, the function doesn't have a name for one thing. In fact here we're looking at an expression that evaluates to a function object. This expression can be passed into other methods, or can be assigned to a variable name. For example you might decide to declare a variable fnMyFunc and assign the above expression to it.

var fnMyFunc 
    = function(x, y) {
        var result = x + y;
        alert(result.toString());
    }
;

fnMyFunc(3,7);

The last line simply calls the function, which should present "10" to the user.

What's The Point?

What we're really demonstrating here is the fact that JavaScript treats functions as first-class objects. A very common use of object-like functions is to define predicates for filtering sets or arrays. If you are familiar with SQL then you have already used predicates which are similar the conditions listed within your WHERE clauses. In JavaScript, a good example is with jQuery (a popular JavaScript library), where you can use anonymous functions as predicates to filter sets of HTML elements according to complex programmer-defined rules. Example:

var jqAllMyDivs = $("div");

var jqDivsWithMoreThanTwoChildren 
    = jqDivs
    .filter(
        function() {
            if($(this).find("*").length > 2) { return true; }
            else { return false; }
    )
;

Notice the use of an anonymous function, simply an expression that is passed into the jQuery function filter. At a conceptual level we're defining a predicate that requires an object have at least two children; but at a technical level we're defining a function that, once called, evaluates certain inner expressions to return either true or false, signalling whether or not your conditions were met. For example, if jqDivs has 12 elements, then our anonymous function is executed 12 times, once for each element. A new set is then generated containing only the elements which met our conditions.

If you're confused about some of the code there, just know that $() is a jQuery method for constructing sets using elements in an HTML document, $(this) constructs a jQuery object containing the element being inspected at that moment, and filter acts much like WHERE does in SQL.

Now, to borrow a line from everyone's favorite marketing bit ...but wait... there's more!

The Magic of Closures

Thus far, anonymous functions have been just fine and dandy. They give us some flexibility in how we package up our logic, and also allow us to neatly group related chunks of logic near to each other. But where the true power and convenience lie is in closures.

Simply put, a closure is internally managed, and contains access to all the variables needed for an anonymous function to execute. Let's modify our first example and see how a closure let's us break some preconceived rules.

function AddAndAlert(x, y, delay) {
    var result = x + y;

    window.setTimeout(
        function() 
        { 
            // notify user
            alert(result.toString()); 
        }, 
        delay
    );
}

// add 4 and 9, and notify the user
// one second later.
AddAndAlert(4, 9, 1000);

Now, if you have a keen eye (or some C++ background) your bat senses should be freaking out about now. We're declaring a local variable result, defining a function that relies on result, scheduling our function for later execution, but immediately leave scope of AddAndAlert. Won't the value of result be undefined (in the C++ sense) when fnNotifyUser executes? The answer no -- in fact the JavaScript runtime has prepared a closure for us that contains a reference to result. This closure is implicitly bundled with fnNotifyUser so that when it is finally executed, it will still have access to the data stored in result as of the time AddAndAlert returns. Furthermore, result as a variable remains unique to each call to AddAndAlert, resulting in no inconsistancies or race conditions.

This is a very powerful feature of the language, especially when needing to build logic that executes in a deferred manner, or logic with complex dependencies that would otherwise require you explicitely package up data for passage to other areas of your code. Any or all local variables in your "outer" function can at any time be utilized by your "inner" anonymous functions without any extra work by the programmer.

Be warned though, there are some "interesting" behaviors that become apparent when relying on closures and loops. I'll cover these gotchas, including some work-arounds, in a follow up post.

C# Anonymous Methods

Now that we know in JavaScript how anonymous functions are built and how closures work, let's take a look at the equivalent in C#.

The good news is that C# fully supports all the concepts covered thus far. The biggest differences are in the syntax and in the fact that C# is a strongly-typed language. Let's revisit our previous examples side-by-side with JavaScript and C#.

A Basic Function (JavaScript)

// a definition
function AddAndAlert(x, y) {
    var result = x + y;
    alert(result.toString());
}

A Basic Method (C#)

// a definition
void AddAndAlert(int x, int y)
{
    int result = x + y;
    Console.Write(result.ToString());
}

An Anonymous Function (JavaScript)

// an expression
function(x, y) {
    var result = x + y;
    alert(result.toString());
}

An Anonymous Method (C#)

// an expression
delegate(int x, int y)
{
    int result = x + y;
    Console.Write(result.ToString());
}

The first thing you'll notice is the "delegate" keyword, which reminds us that the underlying base type that our expression evaluates to is a Delegate. You can think of the Delegate type as being a function pointer combined with a context pointer.

As you will find out, in more complicated situations it's easy to get slowed down by explicit typing in C# when using delegates. C# 3.0 features a great deal of type inference though, some built-in generic delegate types, and lambda expressions. Each of these is beyond the scope of this article but save a great deal of time. For now let's wrap up with our last JavaScript example as written in C#.

Deferred Execution w/Use of Closure (JavaScript)

function AddAndAlert(x, y, delay) {
    var result = x + y;

    window.setTimeout(
        function() 
        {
            // notify user
            alert(result.toString()); 
        }, 
        delay
    );
}

// add 4 and 9, and notify the user
// one second later.
AddAndAlert(4, 9, 1000);

Deferred Execution w/Use of Closure (C#)

void AddAndAlert(int x, int y, TimeSpan delay)
{
    int result = x + y;
    ThreadPool.QueueUserWorkItem(
        delegate(object state) 
        { 
            // very bad! for consistent example only
            Thread.Sleep(delay); 

            // notify user
            Console.Write(result.ToString()); 
        }
    );
}

void MyStartingCode()
{
    AddAndAlert(4, 9, new TimeSpan(0, 0, 1));
}

Notice the similarities -- the logic contained in our anonymous delegate is not executed until a later time and until outside the scope of AddAndAlert. However, because a closure is maintained for us with our anonymous method, our inner logic will have access to result with the correct value.

I like to use the word "magic", especially when describing C# anonymous methods, because there is some trickery that happens under-the-hood to make this behavior work correctly in C#. (more).

13. March 2010 17:05 by SirDuck | Comments (0) | Permalink

Page List