I am trying to learn C# and .NET programming in general but I am finding it
very hard going. To start with, I'd like to translate some trivial
functions from other languages that I am familiar with into C#.
Here is a simple function in OCaml that nests "n" applications of "f"
around "x", with "n" defaulting to "n=2":
let rec nest ?(n=2) f x = if n=0 then x else nest ~n:(n-1) f (f x)
For example, "nest f x" gives "f(f(x))" and "nest ~n:3 f x"
gives "f(f(f(x)))".
I am unable to write this elegantly in C#. This is the best I've come up
with and it doesn't even support partial application (currying):
class Program
{
abstract class Nest<T>
{
int n;
public Nest()
{
n = 2;
}
public abstract T f(T x);
public T Apply(T x)
{
while (n 0)
{
x = f(x);
--n;
}
return x;
}
public int N
{
get
{
return n;
}
set
{
n = value;
}
}
}
class NestTwice : Nest<int>
{
public override int f(int x)
{
return 2 * x;
}
}
static void Main(string[] args)
{
NestTwice nestTwice = new NestTwice();
nestTwice.N = 3;
System.Console.WriteLine(nestTwice.Apply(2));
}
}
So I've implemented the higher-order function "nest" as an abstract base
class "Nest" that you must derive from and override the "f" member
function. The optional argument "n" in the OCaml is implemented as a
mutable property "N" with its default value set to 2 by the constructor.
The "NestTwice" class derives from the "Nest" class, specialized to the
type "T=int", and implements the "f" member such that it doubles its
integer argument.
The main program then constructs an object of the class "NestTwice", sets
its property "N" to 3, overriding its default value of 2, and calls
the "Apply" method to compute the equivalent of "nest n f".
Needless to say, there are many aspects of this that I am not happy with!
1. Can the handling of the function argument "f" be written more elegantly
(but still generically) in terms of delegates? I'd like to replace my
C++-style abstract "Nest" class with something like:
public static T nest<T>(int n, Delegate<T, Tf, x) {
while (n>0) { x=f(x); --n; }
return x;
}
2. My handling of optional arguments is hideous. Can this be done without
mutation, i.e. without first setting the option to its default and then
altering it to the specified value?
3. Is there a simpler way of getting the return value of a function with
optional arguments than making up a "standard" member called "Apply" and
giving it the non-optional arguments after the optional ones have settled
to their true values?
4. Can the "Nest" class be derived from a statically-typed delegate class?
5. Did I miss something fundamental in C#: can any of this be written more
succinctly or elegantly in C#?
6. Are there any tools that can help by autogenerating code like this? Are
there any .NET languages that can do this as elegantly as OCaml?
My motivation is largely to write better F# code rather than C# but both
languages have the same implementation of optional arguments, so the F#
equivalent of the OCaml one-liner also entails a page of classes, mutation
etc.
--
Dr Jon D Harrop, Flying Frog Consultancy
The F#.NET Journal
http://www.ffconsultancy.com/product...ournal/?usenet