Here is one such example where F# developers try to make it look like F# can do things that C# can not.
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!165.entry
F# code
F# code that apparently is much easier to read than C# code:
HttpGet "http://www-static.cc.gatech.edu/classes/cs2360_98_summer/hw1" |> fun s -> Regex.Replace(s, "[^A-Za-z']", " ") |> fun s -> Regex.Split(s, " +") |> Set.of_array |> Set.filter (fun word -> not (Spellcheck word)) |> Set.iter (fun word -> printfn " %s" word)
C# code
My attempt to accomplish the same in C#.
HttpGet("http://www-static.cc.gatech.edu/classes/cs2360_98_summer/hw1")
.Transform(s => Regex.Replace(s, "[^A-Za-z']", " "))
.Transform(s => Regex.Split(s, " +"))
//.AsParallel() // [EDIT] now with parallelism support
.Distinct()
.Where(word => !Spellcheck(word))
.Process(word => Console.WriteLine(" {0}", word))
.Execute();
I think that’s fairly similar?
OK, I cheated, “Transform”,”Process” and “Execute” does not exist out of the box in C#.
You would have to write those extension methods yourself.
However, they are reusable and fits nicely into a util lib.
public static class Extensions
{
public static TOut Transform<TIn, TOut>(this TIn self, Func<TIn, TOut> selector)
{
return selector(self);
}
public static IEnumerable<T> Process<T>(this IEnumerable<T> self, Action<T> action)
{
return self.Select(item =>
{
action(item);
return item;
});
}
public static ParallelQuery<T> Process<T>(this ParallelQuery<T> self, Action<T> action)
{
return self.Select(item =>
{
action(item);
return item;
});
}
public static void Execute<T>(this IEnumerable<T> self)
{
self.ToList();
}
public static void Execute<T>(this ParallelQuery<T> self)
{
self.ToList();
}
}
Either way, I hope this shows that you can accomplish the same thing using good old C# instead of F#.

Pattern matching:
let rec zip la lb =
match (la, lb) with
| (ha::ta), (hb::tb) -> (ha, hb) :: (zipWith func ta tb)
| _ -> []
Pattern matching on one argument can look nice in C# (not as nice as in F#, IMHO), but on several arguments at once you are going to have a problem.
The closest I can come up with is (FList is a functional list class):
FList<Tuple<A>> Zip<A>(FList<A> la, FList<B> lb)
{
return la.Match(() => FList<Tuple<A>>.Empty,
(ha, ta) => lb.Match(() => FList<Tuple<A>>.Empty,
(hb, tb) => Tuple.New(ha, hb).Cons(Zip(la, lb))));
}
which looks _a lot_ worse to me. And this is a very simple pattern match…
Full type inference.
I’d add first-class events, but Reactive Framework will be available for all languages, so I won’t.
Argh, the formatting is messed up there. Hopefully you get the idea.
In my humble opinion, both F# and C# snippets here are not readable at all. (with C# being slightly better).
hi,
First of all. Thanks very much for your useful post.
I just came across your blog and wanted to drop you a note telling you how impressed I
was with the information you have posted here.
Please let me introduce you some info related to this post and I hope that it is useful
for .Net community.
There is a good C# resource site, Have alook
http://www.csharptalk.com
simi
Algebraic data types:
F#:
type 'a 'b optfun = | Konst of 'b | Fun of ('a -> 'b) ... let x = Konst 0C#:
Lost generics again.