daveBlog

Sitting in relative obscurity since 2007…

Building Mono on Mac OS X (2011 Edition)

Quite a bit has changed since I wrote my post a few years ago on building Mono for OS X. So much has changed, in fact, that I've decided that a new post on the topic is in order. These instructions assume that you're using Snow Leopard. They should work on Leopard with minimal changes, but your mileage may vary.

Prerequisites

Installing the prerequisites for Mono is much simpler than it once was. Previously, Mono had external dependencies like glib, which would mean you'd need to install MacPorts, but they've taken steps in the last year to reduce and eliminate such dependencies.

Git

If you haven't yet heard about git, stop hiding under that rock! The Mono source is hosted on GitHub, so if you want to download and build it, you'll need a copy of Git. You can acquire it here.

XCode

XCode 4 is now a $4.99 download in the Mac app store. If you're too cheap for that, you can still (as of the time of this writing) grab XCode 3 here (free registration required). A copy may also be on one of the discs that came with your Mac.

Mono

While you can (theoretically) bootstrap Mono, it's not something I recommend unless you enjoy pain. Save yourself some trouble and download the latest version here.

Get the Source

The Mono source code is now hosted on GitHub. Open your Terminal and clone the repository by issuing the command

git clone git://github.com/mono/mono.git

Build and Install

First, you'll need to run autogen.sh. Here's how I usually invoke it:

./autogen.sh --with-sgen=no --with-xen_opt=no --prefix=/opt/mono-`git rev-parse HEAD` --with-mcs-docs=no --disable-nls

My rationale for each option is listed below.

Assuming that autogen.sh completes successfully, you can now build it with

make -j1

Depending upon how your development environment is set up, you may not need the -j1. However, if your default MAKEFLAGS has a different -j option, you'll want to use this. Otherwise, the Mono build can fail in strange ways. Once this is done, run sudo make install, and you'll be all set!


Rewrite History with git-filter-branch

I've found this page useful on a few occasions, so I'm linking it from here so that I don't forget where it is.

The author demonstrates how to use git-filter-branch to completely remove files from a git repository. I haven't felt compelled to take all the steps that he does in order to get rid of the files, but it's an excellent reference for the command, nonetheless.


Customized URLs in Rails with to_param

This is probably one of the most basic concepts for experienced Rails developers, but I had a hard time finding what I was looking for on Google, which means that other people are having a hard time too, so here's my first little contribution to the Rails community…

I recently moved from SubText to a tiny little (incomplete!) blog engine that I wrote for myself in Rails. While working on it, I was also reading a little bit about SEO; one of the concepts expressed was that each url on your site should have something to do with the content of the page to which it refers. While Rails has good defaults for a lot of things, a url like http://example.com/posts/123 certainly leaves room for improvement.

While I knew that I could accomplish the affect that I wanted by creating a bunch of custom routes in routes.rb, I wanted to be able to take advantage of map.resource and methods such as link_to, which seemed to insist upon using the record ID of my ActiveRecord model.

Until I found to_param.

to_param, as it turns out, is a very simple method that you can override in any ActiveRecord model. Whatever value you return from this method will be used in any urls generated by methods like link_to. The one caveat is that after you do this, you must change the code for any of your controllers so that they look up records based on this new external ID. In many cases, this may be as simple as changing MyController.find(params[:id]) to MyController.find_by_name(params[:id]).


Objective-C Reference Counting From the Bottom Up

I've been interviewing a lot of Objective-C developers, lately. In my mind, one of the most fundamental parts of working with Objective-C is understanding how reference counting works, and I'm consistently surprised by how many people are unable to clearly describe it. In this post, I'll outline the absolute minimum that anyone working with Objective-C ought to know about reference counting. If you find yourself in an interview with me, and you can describe everything in this blog post, I'll know where you got your information you'll be doing better than most.

 

The Basics

Objective-C objects are reference counted. This means that each object comes with a little counter, and anyone can modify the value of this counter by calling retain (to increase the value) or release (to decrease the value). When the value of the counter reaches 0, the dealloc method is called on the object, and any memory associated with the object is reclaimed by the system.

A good developer will make use of this system by calling retain on objects whose pointers are being stored in other objects and calling release on those objects when the pointer no longer needs to be stored. This is, in fact, the reason that we call it "reference counting": the counter is intended to indicate how many objects (or, in some cases, global variables) are holding references to the object.

 

Deadly Embraces and Retain Cycles

When two objects each call retain on the other, we call it a "deadly embrace": if no other action is taken, the objects will never be deallocated. This is widely regarded as a "bad thing".

When this sort of pattern occurs with more than two objects (for example, A retains B, B retains C, and C retains A), it is called a "retain cycle", and these can be even nastier to deal with.

Deadly embraces and retain cycles are dealt with by either preventing one object in the cycle from retaining its "parent" or by having explicit cleanup logic that is executed when it is certain that the objects are no longer needed. Really elite developers sometimes create proxy objects to stand in for one of the objects, although a full discussion of this technique is beyond the scope of this post.

 

Autorelease

The autorelease method is perhaps the most widely misunderstood concept in Objective-C memory management, although in practice, it's actually relatively simple.

At the beginning of each iteration through your application's run loop, an NSAutoreleasePool is created. At the end of each iteration it is destroyed. You can also create and destroy NSAutoreleasePools anytime you wish to do so (for example, you generally need to manually create and destroy them in background threads; more on this, later).

When you call autorelease on an object, the object searches for the most recently created NSAutoreleasePool in its thread. Assuming that it finds a pool, it adds itself to the list of objects that need to be released. When the NSAutoreleasePool is destroyed, it calls release on each object that is in its list--if an object is listed multiple times, release is called multiple times. If the object fails to find an NSAutoreleasePool, a message is logged to the console and the object is leaked (this is why you need to create an NSAutoreleasePool when doing work on a background thread).

 

Ownership and Object Creation

While the notion of "ownership" is not baked into the semantics of Objective-C, one object can be thought to "own" another if it has called retain on the object or has created an instance of the object via the alloc or copy methods. An object that owns another is responsible for calling release on that object when it is no longer needed.

This brings us to an interesting question: what should be done for a method that creates an object but isn't called alloc or copy? In order for the object to be active, its retain count must be at least 1, but the calling method cannot be relied upon to call release.

The answer, of course, is to use the autorelease method. This allows the retain count to be a non-zero value when the method returns, and if nothing is done to keep the object alive, it will be reclaimed when the active NSAutoreleasePool is destroyed.

 

Property Getters and Setters

Care must be taken when writing a method that sets a property value. The naive implementation of such a method looks like this:

- (void)setProperty:(id)value
{
  [propertyField release];
  propertyField = [value retain];
}

This is bad: if value is the same as propertyField, and the retain count of this object is 1 when we enter the method, the first line of the method will cause the object to be deallocated, and the second line will cause bad things to happen (although bad stuff may not happen immediately, which is worse).

This problem can be worked around by retaining value before releasing propertyField, by ensuring that the values are not equal to each other before performing the operation, or even by autoreleasing propertyField instead of releasing it (although this adds overhead).

Another interesting problem in this space involves methods that get property values. Again, the naive implementation of such a method looks like this:

- (id)property
{
  return propertyField;
}

99 times out of a hundred, this will work fine. This of course means that when you run into that one time it doesn't work, it's going to be a huge pain to debug. Here's the case in which you can get into trouble:

id foo = [obj property];
[obj setProperty:bar];
[foo doSomething];

If the retain count of propertyField is 1 at the beginning of this block, then the second line will cause it to drop down to zero and be reclaimed. This means that the third line will be performed on an object that has been deallocated, which is, to say the least, less than ideal. The solution to this is to modify the property getter so that it calls retain and autorelease on propertyField before returning it. This has no net effect on the retain count of the object, but it does ensure that the object will stay alive at least until the active NSAutoreleasePool goes out of scope.

 


So Many Projects…

I have a lot of side projects at various phases of investigation right now. So many, in fact, that I'm quite sure that I won't get around to actually implementing even half of them. Because completed projects are more important to me than the right to say that I wrote the code, I'm going to list some of them here in the hopes that someone on the lazywebs will be inspired to do something with my vague description.

Add New Features to Clang. The Objective-C runtime (at least Apple's version of it) allows any string to be specified as the name of a class, but existing Objective-C compilers only allow letters, numbers, underscores and dollar signs in class names. I'd really love to introduce the ability to have class names with greater variety. Apple has already shown their willingness extend the Objective-C language; I'm just going one step further. Here are a few more ideas that I'd like to see in clang:

Refactor Monodevelop. Monodevelop has great support for things like syntax highlighting and code completion, but most of these features are very tightly tied to Gtk#, and if you want to access such features using a different UI framework, you're out of luck. I'd like to see Monodevelop refactored so that there is a library of common, platform-agnostic code that could conceivably be used from a variety of applications. I know I'd use it.

Write an Objective-C interop library for .NET that uses IDynamicMetaObjectProvider. Objective-C is a very dynamic language, so this sort of implementation makes quite a bit of sense. Individual Objective-C objects would likely inherit directly from SafeHandle and implement IDynamicMetaObjectProvider; all/most method invocation would happen via DynamicMetaObject. Then, using C#'s new dynamic keyword, most of the functionality in Cocoa would be accessible without the need for an enormous wrapper library.


A Very…Amazon…Christmas

You know that we’re in the Internet age when four out of five Christmas shoppers in my family use Amazon for shipping:Amazon boxes under a Christmas tree

The family members who sent us stuff through Amazon didn’t opt for gift wrap (it’s a pretty expensive option), so we have to wait for Christmas day to even know who each package is for, let alone what it is or who ordered it. Perhaps we are seeing the formation of a new holiday tradition?


Killer Apps—You're Doing it Wrong

During my morning journey through all that is new and noteworthy today, I ran across this article about a "killer development tool" for Linux. The author of this article claims that the tool is "going to make ISVs and other programmers start to love developing for Linux."

I must admit that my interest was piqued. I've done at least a little bit of development on each of the major platforms (Windows, Mac, various flavors of Linux), and I must say that tool support had a big effect on the pleasantness of each experience. Furthermore, while I understand that many developers are quite comfortable with Linux, the lack of a "big neon sign" saying "start here" was a big turn off for me (contrast this with Visual Studio for Windows and XCode for MacOS, and you'll begin to understand what I mean).

So what is this amazing tool? As it turns out, it's a package that helps developers find incompatibilities between their applications and various distributions of Linux.

That's a "killer" application? It's going to make me "love" developing for Linux?

Pardon my incredulity, but applying a band-aid over a problem that doesn't even exist (for the most part) on other platforms does not a killer application make. Nor will it make a person "love" developing for that platform. At the very most, one might say that it "makes the platform less painful" or "eases the burden associated with developing for the platform."

But "love?"

Not so much. I think I'll stick with Windows and MacOS for now, thankyouverymuch.

So today's lesson: if your "killer application" just eases the pain associated with a problem that doesn't exist in other environments, you're doing it wrong.


NSDuctTape now supports (rudimentary) two-way communication

This is just a quick note to let you know that NSDuctTape now supports communication in both directions (i.e.-you can now instantiate and manipulate Objective C objects from .NET). The support is still rudimentary, and it's not especially robust, but it's there, and it works. Currently, the new code is only available through Subversion, but I'll probably clean it up a bit and post a new download this weekend.


Bindings and the Model-View-Controller Pattern

There has been a lot of talk lately about the usefulness (or lack thereof) of design patterns in software, but the Model-View-Controller pattern is, without a doubt, one of my favorites. For any who are unfamiliar with it, Model-View-Controller separates the code of an application into three tiers: code that presents an interface to the user (View), code that actually does useful stuff (Model), and code that glues it all together (Controller). On many platforms, such as Apple's Cocoa or Microsoft's WPF, the view may be partially (or completely) implemented without explicitly writing any code, which can greatly speed the development process.

One under-utilized implication of the Model-View-Controller Pattern is that very careful application of the pattern allows models to be reused in multiple contexts; for example, a model might be used as the backbone of both a Windows application and a web application (or theoretically, for a Windows application and a Macintosh application; this is currently rather difficult, although I am working to make it a practical reality). However, even when the models are reused, the views and controllers must be rewritten from scratch. In the case of the view, this is often not a terrible burden, especially when there are good tools for creating views on your platform of choice. On the other hand, rewriting a controller is tedious, boring work. Most of the time, a controller does little more than shuttle data between the view and the model and occasionally disable a control or two. You'd think that there'd be an easier way to hook everything up that didn't involve so much pain and suffering.

As it turns out, you'd be right.

A number of modern MVC frameworks provide a relatively new facility known as "bindings". The UI widgets in such frameworks provide you with the opportunity to specify data sources for various properties (for example, the text in a text field or the enabled state of a button). At runtime, the widgets sign up to receive notifications when the applicable properties on their data sources change (generally using something akin to the Observer pattern). If the data source changes its value for a property, the view will automagically catch this update and change its display accordingly. Likewise, when the user changes a value in the UI, the view propagates this change down to the model.

While this ability to bind directly to a model is incredibly useful and can greatly reduce the amount of code required for many applications, it also leaves us with a question: where do we put all that code that doesn't exactly fit in a model but that also cannot be adequately represented in the view (for example, the enabled state of a button)? One answer that has been proposed is Dan Crevier's DataModel-View-ViewModel pattern. In this pattern, the model (which is renamed to the "data model") and the view remain essentially unchanged, but the controller morphs into being just another model. However, rather than modeling the underlying data, a view model keeps track of application state.

When properly designed, a view model is much more unit testable than a controller, and it seems to me that it ought to be more portable between MVC frameworks, as well. Unfortunately, this pattern comes with a practical hurdle that must be overcome: sometimes, a desired behavior cannot be adequately modeled in a way that is usable by the view. It's often tempting to use this as an excuse to bake platform specific code into a view model, but I find this to be inelegant. In such cases, a developer has two options: either new UI widgets can be created (or extended) to understand the new behaviors, or a controller may be reintroduced in order to serve as a bridge between the view model and the view.

I'm fairly certain that each of these approaches has situations in which it is the best solution, but I strongly suspect that a new controller is the best choice in the majority of cases. While this method does add a fourth tier to the system, which will increase complexity, I believe that in most cases, it will ultimately be less work than baking new functionality right into a view toolkit.

I really wish I could come up with a snappy ending for this post, but it just isn't coming, tonight. In closing, if you're not using MVC in your designs right now (or if you're using it in an undisciplined fashion), I strongly recommend that you study up on it and see if it's right for you. If you're already using MVC, but you aren't using bindings, I'd suggest that you look into whether or not your framework supports them, as they can save you from quite a bit of tedious code.

Technorati Tags: ,

Tutorial for NSDuctTape now available

I've posted an introductory tutorial to NSDuctTape on Google Code.

Expect more in the not-too-distant future.

Technorati Tags: ,,,

Crazy Extention Methods: ToLazyList

Way back in November, I promised to show how to optimize my final version of GetPrimes. Today, I give you the solution to the problem:

using System;
using System.Collections.Generic;
using System.Linq;
 
namespace Utility
{
  public static class EnumerableUtility
  {
    public static IList<T> ToLazyList<T>(this IEnumerable<T> list)
    {
      return new LazyList<T>(list);
    }

    private class LazyList<T> : IList<T>, IDisposable
    {
      public LazyList(IEnumerable<T> list)
      {
        _enumerator = list.GetEnumerator();
        _isFinished = false;
        _cached = new List<T>();
      } 
      public T this[int index]
      {
        get
        {
          if (index < 0)
            throw new ArgumentOutOfRangeException("index"); 
          while (_cached.Count <= index && !_isFinished)
            GetNext();
          return _cached[index];
        }
        set
        {
          throw new NotSupportedException();
        }
      } 
      public int Count
      {
        get
        {
          Finish();
          return _cached.Count;
        }
      } 
      public IEnumerator<T> GetEnumerator()
      {
        int current = 0;
        while (current < _cached.Count || !_isFinished)
        {
          if (current == _cached.Count)
            GetNext();
          if (current != _cached.Count)
            yield return _cached[current];
          current++;
        }
      } 
      public void Dispose()
      {
        _enumerator.Dispose();
        _isFinished = true;
      } 
      public int IndexOf(T item)
      {
        int result = _cached.IndexOf(item);
        while (result == -1 && !_isFinished)
        {
          GetNext();
          if (_cached.Last().Equals(item))
            result = _cached.Count - 1;
        } 
        return result;
      } 
      public void Insert(int index, T item)
      {
        throw new NotSupportedException();
      } 
      public void RemoveAt(int index)
      {
        throw new NotSupportedException();
      } 
      public void Add(T item)
      {
        throw new NotSupportedException();
      } 
      public void Clear()
      {
        throw new NotSupportedException();
      } 
      public bool Contains(T item)
      {
        return IndexOf(item) != -1;
      } 
      public void CopyTo(T[] array, int arrayIndex)
      {
        foreach (var item in this)
          array[arrayIndex++] = item;
      } 
      public bool IsReadOnly
      {
        get { return true; }
      } 
      public bool Remove(T item)
      {
        throw new NotSupportedException();
      } 
      System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
      {
        return GetEnumerator();
      } 
      private void GetNext()
      {
        if (!_isFinished)
        {
          if (_enumerator.MoveNext())
          {
            _cached.Add(_enumerator.Current);
          }
          else
          {
            _isFinished = true;
            _enumerator.Dispose();
          }
        }
      } 
      private void Finish()
      {
        while (!_isFinished)
          GetNext();
      } 
      readonly List<T> _cached;
      readonly IEnumerator<T> _enumerator;
      bool _isFinished;
    }
  }
}

Essentially, what the above code does is to wrap an IEnumerable<T> in a layer that disguises it as an IList<T>. Any value that we evaluate is automatically cached for easy lookup later, but we also don't evaluate values until they are specifically demanded.

The implication of this is that you no longer have to choose between caching all of your values up front and evaluating them lazily&emdash;you can have both with relatively little overhead.

Returning to our example of computing primes, if we simply replace this line:

primes = knownPrimes.Concat(computedPrimes);

With this one:

primes = knownPrimes.Concat(computedPrimes).ToLazyList();

Then everything is suddenly fine, and we can compute primes at a very rapid rate.

Technorati Tags: ,,

NSDuctTape on Google Code

This is by no means a huge update, but NSDuctTape is now hosted on Google Code. You can download the source (or binaries) from there, and the code is also hosted on their Subversion servers.

Technorati Tags: ,,,

Announcing NSDuctTape

About a year ago, I started looking for a way to create applications for OS X using the .NET Framework. I found a couple of alternatives, such as Cocoa# and Dumbarton, but neither of them seemed to be quite what I was looking for.

Cocoa# is a project that aims, first and foremost, to create CLR wrappers for most of the classes in the Cocoa library and secondarily, to allow developers to craft classes that are capable of being accessed by Objective C runtime. At first, this sounded like exactly what I wanted--until I realized that Cocoa strongly encourages the use of the Model-View-Controller pattern in its applications, meaning that most of the code written for such an application would be classes that Objective C would be accessing. While the wrappers are cool, the overhead required to create a class that is consumable by the Objective C runtime makes it less than appealing.

Next, I turned to Dumbarton. However, I quickly turned away when I realized that applications using Dumbarton are required to host mono in such a way as to require the application to be released under the GPL [Update: Paolo Molaro, a significant contributor to the Mono project, informs me that this statement is inaccurate. In any case, I would still argue that the issue is confusing enough that many would shy away from using Dumbarton, even if there really is no licensing requirement].  I have nothing against using (or contributing to) GPLed software, but I don't really want to be tied down to it as soon as I begin developing an application.

What was I to do? I looked into contributing to Cocoa#, but its design philosophy is completely different from my own, and I quickly realized that if I wanted to be happy with the result, I would have to write my own library from scratch.

So I did.

I'm posting a very early release of my new library, NSDuctTape, on the website, today. My goal in designing the application was to remove as much friction as possible from the process of designing Model and Controller classes, with the understanding that most views will be defined using Apple's Interface Builder. Today's release supports Models pretty well, and it also supports bindings from Cocoa objects to CLR object properties, so Controllers aren't even always necessary.

I'll post a tutorial soon, but for the moment, you can download it or read more about it.

Stay tuned for more!

Technorati Tags: ,,,

Applications of Iterate()

Since the code snippets in my previous post consisted mostly of vague hand-waving, I thought it would be good to spend some time today showing how Iterate() can be useful in common algorithms. Consider a fairly standard prime number generator:

public static class Primes 
{
  public static IEnumerable<ulong> GetPrimes(ulong max)
  {
    var list = new List<ulong> { 2 };
    for (ulong candidate = 3; candidate < max; candidate += 2)
    {
      var sqrt = (ulong)Math.Sqrt(candidate);
      bool isPrime = true;
      foreach (var prime in list)
      {
        if (prime > sqrt)
          break;

        if (candidate % prime == 0)
        {
          isPrime = false;
          break;
        }
      }

      if (isPrime)
      list.Add(candidate);
    }

    return list;
  }
}

Surely, one could provide additional optimizations to this routine, but it will serve our purposes as it is. So where do we start? The easiest simplification is to get rid of the inner loop because it is already characterized as an operation on a collection. Let's begin by moving the first breaking condition out of the loop:

var smallPrimes = list.TakeWhile(n => n <= sqrt);
foreach (var prime in smallPrimes)
{
  if (candidate % prime == 0)
  {
    isPrime = false;
    break;
  }
}

Having done this, it now becomes clear that we are verifying a condition against all elements of a collection. We can rewrite this as:

bool isPrime = list.TakeWhile(n => n <= sqrt).All(n => candidate % n != 0);

Of course, now that we're only using isPrime in one place after its definition, we may as well not have it as a temporary variable:

for (ulong candidate = 3; candidate < max; candidate += 2)
{
  var sqrt = (ulong)Math.Sqrt(candidate);

  if (list.TakeWhile(n => n <= sqrt).All(n => candidate % n != 0))
    list.Add(candidate);
}

These are fine modifications, but they may have left you wondering when Iterate() becomes useful. To demonstrate this, let's begin by applying it in the most obvious place:

public static IEnumerable<ulong> GetPrimes(ulong max)
{
  var list = new List<ulong> { 2 };

  var candidates = EnumerableUtility.Iterate<ulong>(3, n => n <= max, n => n + 2);
  foreach (var candidate in candidates)
  {
    var sqrt = (ulong)Math.Sqrt(candidate);

    if (list.TakeWhile(n => n <= sqrt).All(n => candidate % n != 0))
      list.Add(candidate);
  }

  return list;
}

Well, that doesn't make our code clearer, shorter, or more efficient! However, having a foreach loop does make it clearer that we are performing a filter operation on the collection before actually doing anything with the values:

public static IEnumerable<ulong> GetPrimes(ulong max)
{
  var list = new List<ulong> { 2 };

  var candidates = EnumerableUtility.Iterate<ulong>(3, n => n <= max, n => n + 2);

  var primes = candidates.Where(
    candidate =>
    {
      var sqrt = (ulong)Math.Sqrt(candidate);
      return list.TakeWhile(n => n <= sqrt).All(n => candidate % n != 0);
    });

  foreach (var prime in primes)
    list.Add(prime);

  return list;
}

As an aside, if you're not yet comfortable with closures, you may be a bit unsettled by the ordering of statements in this snippet: it appears as if we are checking the list of primes before we have actually populated it! Rest assured that this is not the case: the Where() function, as it is implemented in System.Core.Enumerable, does not calculate the next value in its result until that value is actually requested. Because we never request a new value until we've added all previous values to the list, we have nothing to fear (note, on the other hand, that other implementations of Where(), such as the one included the upcoming ParallelFX library, may not share this implementation detail, so be sure you're using the right one!).

It would seem that we are near the end of possible refactorings for this routine. However, to believe this is to forget that we are not required to calculate all the values in the list ourselves! Getting rid of list, we finally arrive at this:

public static IEnumerable<ulong> GetPrimes(ulong max)
{
  var knownPrimes = new ulong[] { 2, 3 };

  var candidates = EnumerableUtility.Iterate<ulong>(5, n => n <= max, n => n + 2);

  IEnumerable<ulong> primes = null;
  var computedPrimes = candidates.Where(
    candidate =>
    {
      var sqrt = (ulong)Math.Sqrt(candidate);
      return primes.TakeWhile(n => n <= sqrt).All(n => candidate % n != 0);
    });

  primes = knownPrimes.Concat(computedPrimes);

  return primes;
}

Once again, we have a rather clever use of closures, but I hope this one isn't quite as jarring as the last one might have been. While it may at first appear that we are using primes before it has been assigned a real value, recall that the evaluation of Where() does not occur until values are requested from it, which no longer even happens in this function.

It is also perhaps worth noting that our list of known primes has expanded to include 3. The reason for this is that failure to do so would cause infinite recursion when attempting to access the first value in computedPrimes. If it doesn't seem obvious to you, try it and see for yourself :).

One significant benefit to this latest refactoring is that we now only calculate each prime upon demand. Because of this, we may as well compute all primes from 1 to ulong.MaxValue, and forget about the max parameter:

public static IEnumerable<ulong> GetPrimes()
{
  var knownPrimes = new ulong[] { 2, 3 };

  var candidates = EnumerableUtility.Iterate<ulong>(3, n => n != ulong.MaxValue, n => n + 2).Select(n => n + 2);

  IEnumerable<ulong> primes = null;
  var computedPrimes = candidates.Where(
    candidate =>
    {
      var sqrt = (ulong)Math.Sqrt(candidate);
      return primes.TakeWhile(n => n <= sqrt).All(n => candidate % n != 0);
    });

  primes = knownPrimes.Concat(computedPrimes);

  return primes;
}

Aside from removing max, our only significant change has been to candidates, which is now defined as all odd numbers from 5 to ulong.MaxValue (the trickiness with the call to Select() is to keep ourselves from trying to go past MaxValue).

While we now have some beautiful code, you may have noticed that the last two snippets run significantly more slowly than their fully imperative counterparts. The reason for this is that we are no longer caching our prime numbers, so whenever we have to iterate through the list, all primes must be recalculated. Does this mean that we are doomed? Certainly not! In fact, a very minor change to this code is all that is necessary, but the details will have to wait until the next post.


Beyond Loops

Lately, I've been reading quite a bit about the functional programming concepts that are finally coming to C#. The benefits of this new hybrid (imperative/functional) style are numerous, from greater readability (for those who grasp the new idioms, anyway) to more convenient parallelization. However, I've seen very little about the advantage that excites me most: eliminating loops.

What?!

Okay, I'm not really advocating that we actually stop writing code that contains loops—after all, the most reasonable alternative to loops is recursion, and recursion hurts my brain. I am instead suggesting that the time has come for most of our loops to be abstracted away, and here is my first attempt at hiding them:

public static class EnumerableUtility

{

  public static IEnumerable<T> Iterate<T>(T initial, Func<T, bool> fnContinue, Func<T, T> fnNext)

  {

    for (T current = initial; fnContinue(current); current = fnNext(current))

      yield return current;

  }

 

  public static void ApplyToAll<T>(this IEnumerable<T> list, Action<T> fnAction)

  {

    foreach (T item in list)

      fnAction(item);

  }

}

(Note: Did It With .NET defines a similar function, Sequence(), that operates similarly but specifies the arguments in a different order. I prefer my function, but mine could be replaced by his by calling Sequence(initial, fnContinue, fnNext). Either way, the effect is the same.)

Why is this so great? All I really did was put a couple loops into a function, right? Well…sort of, but if you'll stick with me, I think that you'll see that these functions have some significant advantages.

The Problem

In order to compute very much that is of interest to anyone, a language must support sequence, choice, and repetition. When taken in isolation, each of these concepts is easy to grasp, but when combined, they can very quickly exceed the limits of human comprehension. Personally, I find that a few big loops will tax my abilities faster than either of the other two structures, but I also find that repetition tends to be the least frequently abstracted of the three basic constructs.

New Paradigm

Let's look at some code:

var somethingOrOther = initialValue;

while (SomeCondition(somethingOrOther))

{

  if (SomeOtherCondition(somethingOrOther))

    DoStuff(somethingOrOther);

  somethingOrOther = GetNext(somethingOrOther);

}

Or its common counterpart:

for (var somethingOrOther = initialValue; SomeCondition(somethingOrOther); somethingOrOther = GetNext(somethingOrOther)))

{

  if (SomeOtherCondition(somethingOrOther))

    DoStuff(somethingOrOther);

}

The details and complexity vary, but I've seen code like this many times in my (admittedly short) career. We've been trained to accept such things as normal, but is this really as good as it gets? Here are some of the issues I see:

However, the operations defined in EnumerableUtility allow us to think of this as a series of operations on a list, rather than as a loop:

var items = EnumerableUtility.Iterate(initialValue, SomeCondition, GetNext);

items = items.Where(SomeOtherCondition);

items.ApplyToAll(DoStuff);

How is this better? First of all, the second and third operations now appear as a single operation or a list, rather than as a series of operations or individual items—and I find this to be easier on my mental model. Second, we no longer have to concern ourselves about strange assignments to our iterator because the iterator itself has been abstracted away! Finally, having all of the primary operations (enumerating the values, filtering them, and performing an operation on the remaining values) separated from each other allows us to consider each in isolation, which is significantly easier on the brain.

Next time, I intend to introduce some common algorithms and show how using lists instead of loops can simplify their implementation.


And now for something completely different!

I just had to point out this bit of feedback for Visual Studio 2008 Beta 2. Did you notice the issue when you clicked through the license?

Subversion on the Macintosh

Prerequisites
  1. Move Apache 1.3 to Apache 2. This is actually much less painful that it sounds, but it's quite necessary because Subversion doesn't support anything less than Apache 2. You can try running multiple versions of Apache from one box if you like, but in my case, I found that it was easier to just make the switch. If we're lucky, Apple will put Apache 2 on Leopard, and we won't ever have to worry about this part again. Here's how you get Apache 2 on your machine:
    1. Run FinkCommander (you got that back when you were reading my first article on .NET development, right?)
    2. Install the apache2 package. That wasn't so hard, was it?
  2. If you're also serving up ASP.NET on this machine, rebuild mod_mono (discussed in part 2 of my .NET development series). When you run the configuration script, add --with-apxs=/sw/bin/apxs2 to the command line arguments.
    1. If you've installed a CruiseControl.NET dashboard (as discussed in part 3 of the .NET development series), then at the end of /sw/etc/apache2/httpd.conf, add:
Alias /ccnet "/web/ccnet"
AddMonoApplications default "/ccnet:/web/ccnet"
<Location /ccnet>
SetHandler mono
</Location>

Installing Subversion
  1. Run FinkCommander and install the libapache2-mod-svn package.
  2. Run sudo mkdir /svn, where /svn is the path where you want to store your repository.
  3. Run sudo svnadmin create /svn.
  4. Run sudo chown -R www /svn, where www is the name of the user the Apache uses.
  5. Edit /sw/etc/apache2/mods-enabled/dav_svn.conf; the comments should explain what you need to do here.
  6. Restart Apache (/sw/etc/sbin/apache2ctl -k restart).
At this point, you should have a pretty basic Subversion server set up at http://your-machine/svn. Of course, there are all sorts of other things that you can do to your repository, like set it up for secure access, put it on a different port, and what-have-you, but I haven't had need for any of these features (I'm running on a small, personal network). However, I would suspect that setting up these features would not vary as much from platform to platform as the initial setup procedure does, so try Google if you need that stuff.

Caveats

Sadly, I lost my notes on how to get Apache 2 to start up at boot. However, I did find this forum posting that suggests that it can be accomplished by replacing the Apache 1.3 startup scripts with links to the Apache 2 scripts.

I've also found that sometimes, even though I have Apache 2 set up to start up at boot, it fails to do so, or CruiseControl.NET fails to start (or eventually locks up). However, this happens infrequently enough that I haven't bothered to track down the root of the problem, and a reboot (or two) generally fixes it. If anyone reading this happens to stumble upon a solution to my problem, I'd love to hear about it.

Developing for .NET on the Mac, Part 3: Continuous Integration

If you're not already into automated testing and continuous integration, I highly recommend taking a serious look at it, although making a comprehensive argument for the practice is rather beyond the scope of this article. In any case, if you are into continuous integration, you'll definitely want to set up an instance of CruiseControl.NET (or whatever continuous integration server you use) on a Macintosh--the behavior of Mono varies slightly from platform to platform, so you can't really be sure that your code works properly on the Mac unless you test on a Mac.

Let's get down to business, then, shall we?

Prerequisite:
  1. Grab CruiseControl.NET from their SourceForge page. Get the file named CruiseControl.NET-[Version].zip where [Version] is the latest version number.
  2. Unzip the file and copy the contents of webdashboard into a directory that Apache can access. For the purpose of these instructions, I'll be calling it /web/ccnet.
  3. Open /etc/http/httpd.conf in your favorite editor, and add this to the end:
Alias /ccnet "/web/ccnet"
AddMonoApplications default "/ccnet:/web/ccnet"
<Location /ccnet>
SetHandler mono
</Location>

If you have your permissions set up correctly, you should now be able to see your CruiseControl.NET dashboard by going to http://your-server/ccnet/. But wait: we don't have the actual CruiseControl.NET service running! To get this set up, we need a few more steps:
  1. Copy the contents of CruiseControl.NET's server directory into some convenient location, such as /usr/local/ccnet.
  2. Edit ccservice.exe.config to your heart's content; make sure that you also create a valid ccnet.config. Neither of these tasks varies from the standard CruiseControl.NET installation procedures, so refer to the CruiseControl.NET site for details on this part.
  3. To get the service running when you first boot your Mac, create a new directory in /Library/StartupItems called ccnet.
  4. In this directory, create two files. One should be called StartupParameters.plist, and the other should be called ccnet. Here's what needs to be in StartupParameters.plist:
{
    Description = "CruiseControl.NET Server";
    Provides = ("ccnet")
    OrderPreference = "Late";
    Messages =
    {
       start = "Starting CruiseControl.NET";
       stop = "Stopping CruiseControl.NET";
       restart = "Restarting CruiseControl.NET"
    };
}

And here's what you put in the file called ccnet:

#!/bin/sh
# startup script for service CruiseControl.NET

. /etc/rc.common

case "$1" in
    start)
       ConsoleMessage "Starting CruiseControl.NET"d
       if [ -x /usr/local/ccnet/ccservice.exe ]; then
          /Library/Frameworks/Mono.framework/Versions/Current/bin/mono-service2 -d:/src/ccnet /usr/local/ccnet/ccservice.exe
       fi
       ;;
esac
exit 0

Now, if you restart your Mac and navigate to your CruiseControl.NET page, you should have a running instance of ccnet running whatever tests you have set it up to perform.
A couple of notes about the StartupItem I've provided:
Well, that's it for this post. Next time, I'll probably talk about installing Subversion on a Mac. It's not strictly a .NET topic, but it is a quite handy thing to have around, and there are a couple of gotchas to installing it in OS X.

Developing for .NET on the Mac, Part 2: Serving ASP.NET Pages

[Updated 2/11/09: Included information about my experience in making a fresh build on a fresh install of Leopard] Getting a Macintosh to serve up ASP.NET content is actually pretty simple. Mono's primary support for ASP.NET comes through an Apache plugin called mod_mono. This is very good news for the Mac user because Apache version 1.3 comes as part of Tiger. As long as you don't need to run other plugins that require newer versions of Apache (like Subversion), setting up ASP.NET on a Mac could scarcely be easier.

Prerequisites:

  1. Open a terminal and go to ~/src/mono.
  2. Check out the code for mod_mono. This command should get the job done: svn checkout svn://anonsvn.mono-project.com/source/trunk/mod_mono.
  3. Go to ~/src/mono/mod_mono and run the command ./autogen.sh --prefix=/Library/Frameworks/Mono.framework/Versions/Current.
  4. Update: on a fresh install of Leopard, I found that autogen.sh and configure were failing because a tool named libtoolize was renamed to glibtoolize, and the configuration scripts were not configured to handle this. You can fix the problem either by creating an alias for libtoolize or by editing the single line in autogen.sh that refers to libtoolize to point to glibtoolize, instead; furthermore, based on what I read here, it seems that the configuration script fails to detect the 64-bit architecture on some Macs. If this happens to you (you'll know because Apache will fail to start up), run CFLAGS="-m64" ./autogen.sh --prefix=/Library/Frameworks/Mono.framework/Versions/Current followed by a make clean and make.
  5. Follow this by running make && make install. Note that you will probably need elevated permission to complete the installation ste.
  6. Edit /etc/httpd/httpd.conf and add this to the end of the file: Include /private/etc/httpd/mod_mono.conf. Update: in Leopard, this is /etc/apache2/httpd.conf.
  7. Open System Preferences and select "Sharing".
  8. Check the box next to "Personal Web Sharing".
At this point, you should have basic support for ASP.NET on your Mac. The last step that you performed turned on Apache, which by default will look for content in /Library/WebServer/Documents, and putting aspx files ino this folder should result in them being handled by mod_mono.

It should be noted that many applications will require more advanced setup than this (for example, applications like the CruiseControl.NET web dashboard want to be able to handle all web requests for their directory, not just the ones pointing to aspx files), but this is a topic for another post.

Developing for .NET on the Mac, Part 1: Building Mono for the First Time

Update: the process for building Mono has changed significantly since I first wrote this. You can view updated instructions here.

Ever since I first heard about Mono, I've been fascinated by the potential of .NET to become a viable platform for software that targets multiple OSes. Unfortunately, I've discovered (as seems to be the case with many OSS projects), the documentation aimed towards beginners is quite limited, especially when one ventures away from running Mono on Linux.

I've spent many hours trying to get my development environment for the Mac just right, and at times, it's been a rather painful process. So, in the interest of reducing the pain felt by any beginners following after me, I've decided to start recording my processes for getting things set up. At best, this blog will become a useful resource for anyone doing .NET development on the Mac. At worst...well, at least I'll be able to set things up again the next time I have to wipe a hard drive or replace a machine.

One of the first things that I've found in my work is that the Mono installer available from the Mono Project is rarely sufficient for doing any serious development work: bugs abound in the new parts of Mono (I've found a number of problems in generics), and sometimes, I simply can't resist the urge to dig in and fix them. Therefore, when setting up a new development environment, my first goal is generally to get a custom build of Mono up and running.

Here's how I do it:

Prerequisites:
The actual work:
  1. Create a folder for your mono source. For the purpose of these instructions, I'll assume you're going to put it in ~/src/mono.
  2. Open a Terminal window and go to ~/src/mono. Run the command svn checkout svn://anonsvn.mono-project.com/source/trunk/mono svn://anonsvn.mono-project.com/source/trunk/mcs. This will download the code for the core Mono libraries and the Mono Compiler System. They'll end up in ~/src/mono/mono and ~/src/mono/mcs.
  3. Create a folder into which you can install your custom build. I put mine in /opt/mono.
  4. Run the command cd ~/src/mono/mono && ./autogen.sh --prefix=/opt/mono. This step should get Mono ready to build.
  5. You're now ready to build and install: make && make install. I'd love to be able to recommend that you also insert make check in that list, but the sad fact is that Mono on MacOS actually fails a number of tests.
After you've done all this, you should have a working (custom) build of Mono working on your machine. You can, at any time, upgrade to the latest code by going to ~/src/mono and running the command svn update mono mcs. Generally, you'll be able to jump straight to building Mono again, but you may sometimes be required to also run autogen.sh.

Also, it's often very handy to have a script around that will set up all of your paths and whatnot to your custom build of mono. The Parallel Mono Environments page on the Mono website describes this, although I had to modify mine a bit to get it working right. Here's what it looks like now:

#!/bin/bash
MONO_PREFIX=/opt/mono
GNOME_PREFIX=/opt/gnome
export LD_LIBRARY_PATH=$MONO_PREFIX/lib:/sw/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=$MONO_PREFIX/include:$GNOME_PREFIX/include:/sw/include:/Library/Frameworks/Mono
.framework/Versions/1.2.2.1/include/libpng
export ACLOCAL_PATH=$MONO_PREFIX/share/aclocal
export PKG_CONFIG_PATH=$MONO_PREFIX/lib/pkgconfig:$GNOME_PREFIX/lib/pkgconfig:/sw/lib/pkgconfig:/usr/
lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/X11R6/lib/pkgconfig:/Library/Frameworks/Mono.framework/Ve
rsions/1.2.2.1/lib/pkgconfig
PATH=$MONO_PREFIX/bin:$PATH:/sw/bin
PS1="[mono] \w @ "

Mine is stored in ~/mono-dev-env and is invoked via source ~/mono-dev-env

That's it for my first post on setting up a development environment for Mac/.NET development. In the future, I'll go into setting up mod_mono (for ASP.NET), CruiseControl.NET (you do have unit test you'd like to run regularly, don't you?), and Subversion (I realize that Subversion isn't strictly related to .NET, but I didn't have a Subversion server when I started this project, and trying to figure out how to get it set up wasn't terribly fun).

Just switched to SubText 1.9.5

Update: Google Analytics tells me that people are coming to my blog for information about installing Subtext on GoDaddy's servers. Because I'm such a wonderful person, I'm adding instructions for how to do this. (7-4-07)

Update 2: Mikeas has posted more detailed instructions on how to modify the Web.config that comes with Subtext, including a couple of things that I had forgotten to mention (like e-mail). You can view his instructions here.

I used to be on dasBlog, but it was difficult to install onto GoDaddy's servers, and the version I was using didn't have support for ASP.NET 2.0 (which is needed for some other development that I want to do), so I switched to SubText.

With any luck, I'll actually get around to posting real content here in the future...

Installing SubText on GoDaddy's Servers

This wasn't originally what I had intended to blog about, but it seems to be why people are coming to my site right now, so here's how I did it. For the sake of completeness, I'm using GoDaddy's Deluxe Windows Hosting for this site, and it runs me about seven bucks a month.

  1. Log into your GoDaddy account; then, go to My Account -> Hosting & Servers -> My hosting account -> Open Control Panel.
  2. Go to Settings -> ASP.NET Runtime
    1. Open the properties for Content Root and make sure that your ASP.NET version is 2.0. If you have to change it, be aware that it may take some time for GoDaddy to update its servers, and it's not a terribly great idea to upload files to your server until this is done.
    2. Create a directory (I'm assuming you'll call it 'blog'). Give it Read, Web, Write, and SetRoot permissions.
    3. If you want to use Photo Galleries or the MetaWeblog API's MediaObject, you'll also need to create a directory called blog/Images and make sure that it has similar permissions (I haven't actually done this part, since the setup guide at http://www.subtextproject.com/Home/About/Docs/Installation/tabid/111/Default.aspx says it's optional)
    4. Be aware that steps 2 and 3 may take a while to complete on GoDaddy's end. I don't recommend uploading files until the Control Panel says that everything is up to date.
  3. Go to Databases -> SQL Server
    1. Create a database that uses SQL Server 2005. Most of the settings won't matter a whole lot, but you'll want to make sure that you remember the password, at least for a few minutes. :)
    2. Once the database is set up, grab the ODBC connections string for your new database (you can find this by going to the details page of the new database and clicking the configuration button). Remove the "Driver" attribute from this string, and put your password into it.
  4. Modify Subtext's Web.Config file and insert the connection string that you got in step 3. The location for this should be somewhere around line 40. The name of the string is "subtextData".
  5. Once GoDaddy is done setting up all of your directories and databases, ftp to your site and upload all of your content into /blog.
  6. Navigate to http://yourdomain.sometld/blog. Subtext should make the rest of the process easy.

A note about automatic redirecting:

For whatever reason, GoDaddy has elected to not allow you to change the ASP.Net permissions on your root folder, and 404 redirects won't work for visiting http://yourdomain.sometld/. If, like me, your blog is the primary content on your site, and this is the first thing that you'd like visitors to see, you can configure a Default.aspx that will redirect people to http://yourdomain.sometld/blog. Here's what mine looks like:

<%@ Page language="c#" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<html>
  <head runat="server">
    <title></title>
    <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
    <meta name="CODE_LANGUAGE" Content="C#">
    <meta name=vs_defaultClientScript content="JavaScript">
    <meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
  </head>
  <body MS_POSITIONING="GridLayout">
    <form id="Form1" method="post" runat="server">
  <% Response.Redirect("http://www.fallingcanbedeadly.com/blog"); %>
     </form>
  </body>
</html>

Anyway, this is how I have my blog set up, and I would assume that it would work for most users, but I make no guarantees to this effect. Let me know how it turns out for you!