Mondrian for .NET
by Jason Smith, Nigel Perry, and Erik Meijer

Listing One
delegate bool SortComp(Object lxpr, Object rxpr);
static void QSort(Object[] Data, SortComp Cmp)
{  QSortPart(Data, 0, Data.Length-1, Cmp);
}
static void QSortPart(Object[] Data, int Left, int Right, SortComp Cmp)
{  if(Right <= Left) return;
   int NewPivot = Partition(Data, Left, Right, Cmp);
   QSortPart(Data,       Left,   --NewPivot, Cmp);
   QSortPart(Data, ++NewPivot,        Right, Cmp);
}
static int Partition(Object[] Data, int Left, int Right, SortComp Cmp)
{  int iLeft  = Left - 1;
   int iRight = Right;
   int iPivot = Right; // Pick right element as the pivot
   Object PivotValue = Data[iPivot];
   while(true)
   {  while(Cmp(Data[++iLeft], PivotValue));
      while(Cmp(PivotValue, Data[--iRight]))
         if(iRight == iLeft) break;
      if(iLeft >= iRight) break;
      Swap(Data, iLeft, iRight);
   }
   Swap(Data, iLeft, iPivot);
   return iLeft;
}
static void Swap(Object[] Data, int i, int j)
{  Object x = Data [i];
   Data[i] = Data[j];
   Data[j] = x;
}


Listing Two
// qsort : forall a. (a -> a -> Boolean) -> List<a> -> List<a>
qsort = compare -> l ->
   switch(l)
   {  case []: [];
      case (pivot::t):
         let
            before = filter (x -> compare x pivot)       t;
            after  = filter (x -> not (compare x pivot)) t;
         in
            (qsort compare before)
            ++ (pivot :: (qsort compare after));
   };


Listing Three
partition = pred -> data -> before -> after ->
   switch(data)
   {  case []:
         Pair{ a = before;
               b = after;
             };
      case (first::tail):
         if(pred first)
            partition pred tail (first::before) after
         else
            partition pred tail before (first::after);
   };


Listing Four
static ArrayList primes(int limit)
{  int [] sieve = new int[limit];
   ArrayList found = new ArrayList();

   // initialise array
   for (int i = 2; i < limit; i++) sieve[i] = i;
   // find primes
   for (int cursor = 2; cursor < limit; cursor++)
   {  if (sieve[cursor] != 0)
      {  // found a prime
         found.Add(cursor);
         // Sieve the array
         for (int j = cursor + 1; j < limit; j++)
            if (sieve[j]%cursor == 0)
               sieve[j] = 0;
      }
   }
   return found;
}


Listing Five
// sieve : List<Integer> -> List<Integer>;
sieve = xs ->
   switch (xs)
   {  case (y::ys):
         // keep head, remove all multiples of head from tail,
         // then recursively sieve tail
         y :: sieve (filter (x -> x % y != 0) ys);
   };
primes = sieve (from 2);


Listing Six
class PrimeIterator
{  private Object list = primeGenerator.primes.Apply();
   public int Current()
   {  return (int)mondrian.prelude.hd.Apply(list);
   }
   public void Next()
   {  list = mondrian.prelude.tl.Apply(list);
   }
}


Listing Seven
// readLinesFromURL :: String -> IO<List<String>>;
readLinesFromURL = url ->
{  try
   {  req <- HttpWebRequest.Create(url);
      rsp <- req # HttpWebRequest.GetResponse();
      str <- rsp # WebResponse.GetResponseStream();
      readLines str;
   }
   catch (e : Exception)
   {   result Nil;
   };
};


Listing Eight
<form method="POST" action="SortMondrian.aspx" runat=server>
<table border=0 cellspace=4>
  <tr>
    <td valign=center>
      <asp:Button id="I1" text="Sample 1" OnClick="Init1"
       runat="server" />
      <br>&nbsp;<br>
      <asp:Button id="I2" text="Sample 2" OnClick="Init2"
       runat="server" /><br>
    </td>
    <td valign=center>
      <asp:TextBox id="T" rows="6" textmode="multiline" text=""
       runat="server" />
    </td>
    <td valign=center align=center>
      <asp:Button id="B" text="-> Sort ->" OnClick="DoSort"
       runat="server" />
    </td>
    <td valign=center>
      <asp:TextBox id="T2" rows="6" textmode="multiline" text=""
       runat="server" />
    </td>
  </tr>
</table>
</form>


Listing Nine
void Init1(object sender, EventArgs e)
{ T.Text = "turtle\nkakapo\naardwolf\neagle\ntuatara\nvole\nbadger";
}
void Init2(object sender, EventArgs e)
{ T.Text = "reversed\ninput\ndata";
}


Listing Ten
SortLines = cs ->
   let
      l = lines (stringToList cs);
      r = qsort stringLT l;
   in
      listToString (unlines r);


Listing Eleven
void Clicked(object sender, EventArgs e)
{  T2.Text = (string)SortLines.Apply(T.Text);
}


Listing Twelve
<%@ Page Language="Mondrian" %>
<script runat="server">
// qsort - Listing Two
// SortLines - Listing Ten
</script>
<script runat="server">[C#]
// C# handlers - Listings Nine and Eleven
</script>
<html>
<body>
// the form - Listing Eight
</body>
</html>

