Note: The point of this question is more from a curiosity perspective. I want to know out of curiosity whether it is even possible to transliterate the Haskell implementation into a functional C# equivalent.
So I've been learning myself Haskell for great good, and while solving Project Euler problems I ran into this beautiful Haskell Fibonacci implementation:
fibs :: [Integer]
fibs = 1:1:zipWith (+) fibs (tail fibs)
Of course I was tempted to write a C# version like this, so:
If I do this:
IEnumerable<int> fibs =
Enumerable.Zip(Enumerable.Concat(new int[] { 1, 1 }, fibs),
//^^error
fibs.Skip(1), (f, s) => f + s);
The error says use of unassigned local variable fibs.
So I went slightly imperative, while this compiles...
public static IEnumerable<int> Get()
{
return Enumerable.Zip(Enumerable.Concat(new int[] { 1, 1 }, Get()),
Get().Skip(1), (f, s) => f + s);
}
It breaks with a stack overflow exception! So I came here..
Questions:
Can anyone think of a functional C# equivalent that works?
I'd like some insight into why my solutions don't work.
The answer to your first question is: this is how to do it in C#:
using System;
using System.Collections.Generic;
using System.Linq;
class P
{
static IEnumerable<int> F()
{
yield return 1;
yield return 1;
foreach(int i in F().Zip(F().Skip(1), (a,b)=>a+b))
yield return i;
}
static void Main()
{
foreach(int i in F().Take(10))
Console.WriteLine(i);
}
}
The answer to your second question is: C# is eager by default, so your method has an unbounded recursion. Iterators that use yield however return an enumerator immediately, but do not construct each element until required; they are lazy. In Haskell everything is lazy automatically.
UPDATE: Commenter Yitz points out correctly that this is inefficient because, unlike Haskell, C# does not automatically memoize the results. It's not immediately clear to me how to fix it while keeping this bizarre recursive algorithm intact.
Of course you would never actually write fib like this in C# when it is so much easier to simply:
static IEnumerable<BigInteger> Fib()
{
BigInteger prev = 0;
BigInteger curr = 1;
while (true)
{
yield return curr;
var next = curr + prev;
prev = curr;
curr = next;
}
}
Unlike the C# version provided in Eric Lippert's answer, this F# version avoids repeated computation of elements and therefore has comparable efficiency with Haskell:
let rec fibs =
seq {
yield 1
yield 1
for (a, b) in Seq.zip fibs (Seq.skip 1 fibs) do
yield a + b
}
|> Seq.cache // this is critical for O(N)!
I have to warn you that I'm trying to fix your attempts, not to make a productive code.
Also, this solution is good to make our brains to explode, and maybe the computer also.
In your first snippet you tried to call recursive your field or local variable, that is not possible.Instead we can try with a lambda which could be more similar to that. We know from Church, that is also not possible, at least in the traditional way. Lambda expressions are unnamed; you can't call them by their name ( inside of the implementation ). But you can use the fixed point to do recursion. If you have a sane mind there is big chance of not knowing what is that, anyway you should give a try to this link before continuing with this.
fix :: (a -> a) -> a
fix f = f (fix f)
This will be the c# implementation (which is wrong)
A fix<A>(Func<A,A> f) {
return f(fix(f));
}
Why is wrong? Because fix(f) represents a beautiful stackoverflow. So we need to make it lazy:
A fix<A>(Func<Func<A>,A> f) {
return f(()=>fix(f));
}
Now is lazy! Actually you will see a lot of this in the following code.
In your second snippet and also in the first, you have the problem that the second argument to Enumerable.Concat is not lazy, and you will have stackoverflow exception, or infinite loop in the idealistic way. So let's make it lazy.
static IEnumerable<T> Concat<T>(IEnumerable<T> xs,Func<IEnumerable<T>> f) {
foreach (var x in xs)
yield return x;
foreach (var y in f())
yield return y;
}
Now, we have the whole "framework" to implement what you have tried in the functional way.
void play() {
Func<Func<Func<IEnumerable<int>>>, Func<IEnumerable<int>>> F = fibs => () =>
Concat(new int[] { 1, 1 },
()=> Enumerable.Zip (fibs()(), fibs()().Skip(1), (a,b)=> a + b));
//let's see some action
var n5 = fix(F)().Take(5).ToArray(); // instant
var n20 = fix(F)().Take(20).ToArray(); // relative fast
var n30 = fix(F)().Take(30).ToArray(); //this will take a lot of time to compute
//var n40 = fix(F)().Take(40).ToArray(); //!!! OutOfMemoryException
}
I know that the F signature is ugly like hell, but this is why languages like haskell exists, and even F#. C# is not made for this work to be done like this.
Now, the question is, why haskell can achieve something like this?Why? because whenever you say something like
a:: Int
a = 4
The most similar translation in C# is :
Func<Int> a = () => 4
Actually is much more involved in the haskell implementation, but this is the idea why similar method of solving problems looks so different if you want to write it in both languages
Here it is for Java, dependent on Functional Java:
final Stream<Integer> fibs = new F2<Integer, Integer, Stream<Integer>>() {
public Stream<Integer> f(final Integer a, final Integer b) {
return cons(a, curry().f(b).lazy().f(a + b));
}
}.f(1, 2);
For C#, you could depend on XSharpX
A take on Eric's answer that has Haskell equivalent performance, but still has other issues(thread safety, no way to free memory).
private static List<int> fibs = new List<int>(){1,1};
static IEnumerable<int> F()
{
foreach (var fib in fibs)
{
yield return fib;
}
int a, b;
while (true)
{
a = fibs.Last();
b = fibs[fibs.Count() - 2];
fibs.Add(a+b);
yield return a + b;
}
}
Translating from a Haskell environment to a .NET environment is much easier if you use F#, Microsoft's functional declarative language similar to Haskell.
Related
I am writing a dice-based game in C#. I want all of my game-logic to be pure, so I have devised a dice-roll generator like this:
public static IEnumerable<int> CreateDiceStream(int seed)
{
var random = new Random(seed);
while (true)
{
yield return 1 + random.Next(5);
}
}
Now I can use this in my game logic:
var playerRolls = players.Zip(diceRolls, (player, roll) => Tuple.Create(player, roll));
The problem is that the next time I take from diceRolls I want to skip the rolls that I have already taken:
var secondPlayerRolls = players.Zip(
diceRolls.Skip(playerRolls.Count()),
(player, roll) => Tuple.Create(player, roll));
This is already quite ugly and error prone. It doesn't scale well as the code becomes more complex.
It also means that I have to be careful when using a dice roll sequence between functions:
var x = DoSomeGameLogic(diceRolls);
var nextRoll = diceRolls.Skip(x.NumberOfDiceRollsUsed).First();
Is there a good design pattern that I should be using here?
Note that it is important that my functions remain pure due to syncronisation and play-back requirements.
This question is not about correctly initializing System.Random. Please read what I have written, and leave a comment if it is unclear.
That's a very nice puzzle.
Since manipulating diceRolls's state is out of the question (otherwise, we'd have those sync and replaying issues you mentioned), we need an operation which returns both (a) the values to be consumed and (b) a new diceRolls enumerable which starts after the consumed items.
My suggestion would be to use the return value for (a) and an out parameter for (b):
static IEnumerable<int> Consume(this IEnumerable<int> rolls, int count, out IEnumerable<int> remainder)
{
remainder = rolls.Skip(count);
return rolls.Take(count);
}
Usage:
var firstRolls = diceRolls.Consume(players.Count(), out diceRolls);
var secondRolls = diceRolls.Consume(players.Count(), out diceRolls);
DoSomeGameLogic would use Consume internally and return the remaining rolls. Thus, it would need to be called as follows:
var x = DoSomeGameLogic(diceRolls, out diceRolls);
// or
var x = DoSomeGameLogic(ref diceRolls);
// or
x = DoSomeGameLogic(diceRolls);
diceRolls = x.RemainingDiceRolls;
The "classic" way to implement pure random generators is to use a specialized form of a state monad (more explanation here), which wraps the carrying around of the current state of the generator. So, instead of implementing (note that my C# is quite rusty, so please consider this as pseudocode):
Int Next() {
nextState, nextValue = NextRandom(globalState);
globalState = nextState;
return nextValue;
}
you define something like this:
class Random<T> {
private Func<Int, Tuple<Int, T>> transition;
private Tuple<Int, Int> NextRandom(Int state) { ... whatever, see below ... }
public static Random<A> Unit<A>(A a) {
return new Random<A>(s => Tuple(s, a));
}
public static Random<Int> GetRandom() {
return new Random<Int>(s => nextRandom(s));
}
public Random<U> SelectMany(Func<T, Random<U>> f) {
return new Random(s => {
nextS, a = this.transition(s);
return f(a).transition(nextS);
}
}
public T Run(Int seed) {
return this.transition(seed);
}
}
Which should be usable with LINQ, if I did everything right:
// player1 = bla, player2 = blub, ...
Random<Tuple<Player, Int>> playerOneRoll = from roll in GetRandom()
select Tuple(player1, roll);
Random<Tuple<Player, Int>> playerTwoRoll = from roll in GetRandom()
select Tuple(player2, roll);
Random<List<Tuple<Player, Int>>> randomRolls = from t1 in playerOneRoll
from t2 in playerTwoRoll
select List(t1, t2);
var actualRolls = randomRolls.Run(234324);
etc., possibly using some combinators. The trick here is to represent the whole "random action" parametrized by the current input state; but this is also the problem, since you'd need a good implementation of NextRandom.
It would be nice if you could just reuse the internals of the .NET Random implementation, but as it seems, you cannot access its internal state. However, I'm sure there are enough sufficiently good PRNG state functions around on the internet (this one looks good; you might have to change the state type).
Another disadvantage of monads is that once you start working in them (ie, construct things in Random), you need to "carry that though" the whole control flow, up to the top level, at which you should call Run once and for all. This is something one needs to get use to, and is more tedious in C# than functional languages optimized for such things.
Lets assume you have a function that returns a lazily-enumerated object:
struct AnimalCount
{
int Chickens;
int Goats;
}
IEnumerable<AnimalCount> FarmsInEachPen()
{
....
yield new AnimalCount(x, y);
....
}
You also have two functions that consume two separate IEnumerables, for example:
ConsumeChicken(IEnumerable<int>);
ConsumeGoat(IEnumerable<int>);
How can you call ConsumeChicken and ConsumeGoat without a) converting FarmsInEachPen() ToList() beforehand because it might have two zillion records, b) no multi-threading.
Basically:
ConsumeChicken(FarmsInEachPen().Select(x => x.Chickens));
ConsumeGoats(FarmsInEachPen().Select(x => x.Goats));
But without forcing the double enumeration.
I can solve it with multithread, but it gets unnecessarily complicated with a buffer queue for each list.
So I'm looking for a way to split the AnimalCount enumerator into two int enumerators without fully evaluating AnimalCount. There is no problem running ConsumeGoat and ConsumeChicken together in lock-step.
I can feel the solution just out of my grasp but I'm not quite there. I'm thinking along the lines of a helper function that returns an IEnumerable being fed into ConsumeChicken and each time the iterator is used, it internally calls ConsumeGoat, thus executing the two functions in lock-step. Except, of course, I don't want to call ConsumeGoat more than once..
I don't think there is a way to do what you want, since ConsumeChickens(IEnumerable<int>) and ConsumeGoats(IEnumerable<int>) are being called sequentially, each of them enumerating a list separately - how do you expect that to work without two separate enumerations of the list?
Depending on the situation, a better solution is to have ConsumeChicken(int) and ConsumeGoat(int) methods (which each consume a single item), and call them in alternation. Like this:
foreach(var animal in animals)
{
ConsomeChicken(animal.Chickens);
ConsomeGoat(animal.Goats);
}
This will enumerate the animals collection only once.
Also, a note: depending on your LINQ-provider and what exactly it is you're trying to do, there may be better options. For example, if you're trying to get the total sum of both chickens and goats from a database using linq-to-sql or linq-to-entities, the following query..
from a in animals
group a by 0 into g
select new
{
TotalChickens = g.Sum(x => x.Chickens),
TotalGoats = g.Sum(x => x.Goats)
}
will result in a single query, and do the summation on the database-end, which is greatly preferable to pulling the entire table over and doing the summation on the client end.
The way you have posed your problem, there is no way to do this. IEnumerable<T> is a pull enumerable - that is, you can GetEnumerator to the front of the sequence and then repeatedly ask "Give me the next item" (MoveNext/Current). You can't, on one thread, have two different things pulling from the animals.Select(a => a.Chickens) and animals.Select(a => a.Goats) at the same time. You would have to do one then the other (which would require materializing the second).
The suggestion BlueRaja made is one way to change the problem slightly. I would suggest going that route.
The other alternative is to utilize IObservable<T> from Microsoft's reactive extensions (Rx), a push enumerable. I won't go into the details of how you would do that, but it's something you could look into.
Edit:
The above is assuming that ConsumeChickens and ConsumeGoats are both returning void or are at least not returning IEnumerable<T> themselves - which seems like an obvious assumption. I'd appreciate it if the lame downvoter would actually comment.
Actually simples way to achieve what you what is convert FarmsInEachPen return value to push collection or IObservable and use ReactiveExtensions for working with it
var observable = new Subject<Animals>()
observable.Do(x=> DoSomethingWithChicken(x. Chickens))
observable.Do(x=> DoSomethingWithGoat(x.Goats))
foreach(var item in FarmsInEachPen())
{
observable.OnNext(item)
}
I figured it out, thanks in large part due to the path that #Lee put me on.
You need to share a single enumerator between the two zips, and use an adapter function to project the correct element into the sequence.
private static IEnumerable<object> ConsumeChickens(IEnumerable<int> xList)
{
foreach (var x in xList)
{
Console.WriteLine("X: " + x);
yield return null;
}
}
private static IEnumerable<object> ConsumeGoats(IEnumerable<int> yList)
{
foreach (var y in yList)
{
Console.WriteLine("Y: " + y);
yield return null;
}
}
private static IEnumerable<int> SelectHelper(IEnumerator<AnimalCount> enumerator, int i)
{
bool c = i != 0 || enumerator.MoveNext();
while (c)
{
if (i == 0)
{
yield return enumerator.Current.Chickens;
c = enumerator.MoveNext();
}
else
{
yield return enumerator.Current.Goats;
}
}
}
private static void Main(string[] args)
{
var enumerator = GetAnimals().GetEnumerator();
var chickensList = ConsumeChickens(SelectHelper(enumerator, 0));
var goatsList = ConsumeGoats(SelectHelper(enumerator, 1));
var temp = chickensList.Zip(goatsList, (i, i1) => (object) null);
temp.ToList();
Console.WriteLine("Total iterations: " + iterations);
}
I am playing a little bit with functional programming and the various concepts of it. All this stuff is very interesting. Several times I have read about Currying and what an advantage it has.
But I do not get the point with this. The following source demonstrates the using of the curry concept and the solution with linq. Actually, I do not see any advatages of using the currying concept.
So, what is the advantage of using currying?
static bool IsPrime(int value)
{
int max = (value / 2) + 1;
for (int i = 2; i < max; i++)
{
if ((value % i) == 0)
{
return false;
}
}
return true;
}
static readonly Func<IEnumerable<int>, IEnumerable<int>> GetPrimes =
HigherOrder.GetFilter<int>().Curry()(IsPrime);
static void Main(string[] args)
{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Console.Write("Primes:");
//Curry
foreach (int n in GetPrimes(numbers))
{
Console.Write(" {0}", n);
}
Console.WriteLine();
//Linq
foreach (int n in numbers.Where(p => IsPrime(p)))
{
Console.Write(" {0}", n);
}
Console.ReadLine();
}
Here is the HigherOrder Filter Method:
public static Func<Func<TSource, bool>, IEnumerable<TSource>, IEnumerable<TSource>> GetFilter<TSource>()
{
return Filter<TSource>;
}
what is the advantage of using currying?
First off, let's clarify some terms. People use "currying" to mean both:
reformulating a method of two parameters into a methods of one parameter that returns a method of one parameter and
partial application of a method of two parameters to produce a method of one parameter.
Clearly these two tasks are closely related, and hence the confusion. When speaking formally, one ought to restrict "currying" to refer to the first definition, but when speaking informally either usage is common.
So, if you have a method:
static int Add(int x, int y) { return x + y; }
you can call it like this:
int result = Add(2, 3); // 5
You can curry the Add method:
static Func<int, int> MakeAdder(int x) { return y => Add(x, y); }
and now:
Func<int, int> addTwo = MakeAdder(2);
int result = addTwo(3); // 5
Partial application is sometimes also called "currying" when speaking informally because it is obviously related:
Func<int, int> addTwo = y=>Add(2,y);
int result = addTwo(3);
You can make a machine that does this process for you:
static Func<B, R> PartiallyApply<A, B, R>(Func<A, B, R> f, A a)
{
return (B b)=>f(a, b);
}
...
Func<int, int> addTwo = PartiallyApply<int, int, int>(Add, 2);
int result = addTwo(3); // 5
So now we come to your question:
what is the advantage of using currying?
The advantage of either technique is that it gives you more flexibility in dealing with methods.
For example, suppose you are writing an implementation of a path finding algorithm. You might already have a helper method that gives you an approximate distance between two points:
static double ApproximateDistance(Point p1, Point p2) { ... }
But when you are actually building the algorithm, what you often want to know is what is the distance between the current location and a fixed end point. What the algorithm needs is Func<Point, double> -- what is the distance from the location to the fixed end point? What you have is Func<Point, Point, double>. How are you going to turn what you've got into what you need? With partial application; you partially apply the fixed end point as the first argument to the approximate distance method, and you get out a function that matches what your path finding algorithm needs to consume:
Func<Point, double> distanceFinder = PartiallyApply<Point, Point, double>(ApproximateDistance, givenEndPoint);
If the ApproximateDistance method had been curried in the first place:
static Func<Point, double> MakeApproximateDistanceFinder(Point p1) { ... }
Then you would not need to do the partial application yourself; you'd just call MakeApproximateDistanceFinder with the fixed end point and you'd be done.
Func<Point, double> distanceFinder = MakeApproximateDistanceFinder(givenEndPoint);
The comment by #Eric Lippert on What is the advantage of Currying in C#? (achieving partial function) points to this blog post:
Currying and Partial Function Application
Where I found this the best explantion that works for me:
From a theoretical standpoint, it is interesting because it (currying) simplifies
the lambda calculus to include only those functions which have at most
one argument. From a practical perspective, it allows a programmer to
generate families of functions from a base function by fixing the
first k arguments. It is akin to pinning up something on the wall
that requires two pins. Before being pinned, the object is free to
move anywhere on the surface; however, when when first pin is put in
then the movement is constrained. Finally, when the second pin is put
in then there is no longer any freedom of movement. Similarly, when a
programmer curries a function of two arguments and applies it to the
first argument then the functionality is limited by one dimension.
Finally, when he applies the new function to the second argument then
a particular value is computed.
Taking this further I see that functional programming essentially introduces 'data flow programming as opposed to control flow' this is akin to using say SQL instead of C#. With this definition I see why LINQ is and why it has many many applications outside of pure Linq2Objects - such as events in Rx.
The advantage of using currying is largely to be found in functional languages, which are built to benefit from currying, and have a convenient syntax for the concept. C# is not such a language, and implementations of currying in C# are usually difficult to follow, as is the expression HigherOrder.GetFilter<int>().Curry()(IsPrime).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is there not a ForEach extension method on the IEnumerable interface?
I've noticed when writing LINQ-y code that .ForEach() is a nice idiom to use. For example, here is a piece of code that takes the following inputs, and produces these outputs:
{ "One" } => "One"
{ "One", "Two" } => "One, Two"
{ "One", "Two", "Three", "Four" } => "One, Two, Three and Four";
And the code:
private string InsertCommasAttempt(IEnumerable<string> words)
{
List<string> wordList = words.ToList();
StringBuilder sb = new StringBuilder();
var wordsAndSeparators = wordList.Select((string word, int pos) =>
{
if (pos == 0) return new { Word = word, Leading = string.Empty };
if (pos == wordList.Count - 1) return new { Word = word, Leading = " and " };
return new { Word = word, Leading = ", " };
});
wordsAndSeparators.ToList().ForEach(v => sb.Append(v.Leading).Append(v.Word));
return sb.ToString();
}
Note the interjected .ToList() before the .ForEach() on the second to last line.
Why is it that .ForEach() isn't available as an extension method on IEnumerable<T>? With an example like this, it just seems weird.
Because ForEach(Action) existed before IEnumerable<T> existed.
Since it was not added with the other extension methods, one can assume that the C# designers felt it was a bad design and prefer the foreach construct.
Edit:
If you want you can create your own extension method, it won't override the one for a List<T> but it will work for any other class which implements IEnumerable<T>.
public static class IEnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
action(item);
}
}
According to Eric Lippert, this is mostly for philosophical reasons. You should read the whole post, but here's the gist as far as I'm concerned:
I am philosophically opposed to
providing such a method, for two
reasons.
The first reason is that doing so
violates the functional programming
principles that all the other sequence
operators are based upon. Clearly the
sole purpose of a call to this method
is to cause side effects.
The purpose of an expression is to
compute a value, not to cause a side
effect. The purpose of a statement is
to cause a side effect. The call site
of this thing would look an awful lot
like an expression (though,
admittedly, since the method is
void-returning, the expression could
only be used in a “statement
expression” context.)
It does not sit well with me to make
the one and only sequence operator
that is only useful for its side
effects.
The second reason is that doing so
adds zero new representational power
to the language.
Because ForEach() on an IEnumerable is just a normal for each loop like this:
for each T item in MyEnumerable
{
// Action<T> goes here
}
ForEach isn't on IList it's on List. You were using the concrete List in your example.
I am just guessing here , but putting foreach on IEnumerable would make operations on it to have side effects . None of the "available" extension methods cause side effects , putting an imperative method like foreach on there would muddy the api I guess . Also, foreach would initialize the lazy collection .
Personally I've been fending off the temptation to just add my own , just to keep side effect free functions separate from ones with side effects.
ForEach is implemented in the concrete class List<T>
Just a guess, but List can iterate over its items without creating an enumerator:
public void ForEach(Action<T> action)
{
if (action == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
for (int i = 0; i < this._size; i++)
{
action(this._items[i]);
}
}
This can lead to better performance. With IEnumerable, you don't have the option to use an ordinary for-loop.
LINQ follows the pull-model and all its (extension) methods should return IEnumerable<T>, except for ToList(). The ToList() is there to end the pull-chain.
ForEach() is from the push-model world.
You can still write your own extension method to do this, as pointed out by Samuel.
I honestly don't know for sure why the .ForEach(Action) isn't included on IEnumerable but, right, wrong or indifferent, that's the way it is...
I DID however want to highlight the performance issue mentioned in other comments. There is a performance hit based on how you loop over a collection. It is relatively minor but nevertheless, it certainly exists. Here is an incredibly fast and sloppy code snippet to show the relations... only takes a minute or so to run through.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Start Loop timing test: loading collection...");
List<int> l = new List<int>();
for (long i = 0; i < 60000000; i++)
{
l.Add(Convert.ToInt32(i));
}
Console.WriteLine("Collection loaded with {0} elements: start timings",l.Count());
Console.WriteLine("\n<===============================================>\n");
Console.WriteLine("foreach loop test starting...");
DateTime start = DateTime.Now;
//l.ForEach(x => l[x].ToString());
foreach (int x in l)
l[x].ToString();
Console.WriteLine("foreach Loop Time for {0} elements = {1}", l.Count(), DateTime.Now - start);
Console.WriteLine("\n<===============================================>\n");
Console.WriteLine("List.ForEach(x => x.action) loop test starting...");
start = DateTime.Now;
l.ForEach(x => l[x].ToString());
Console.WriteLine("List.ForEach(x => x.action) Loop Time for {0} elements = {1}", l.Count(), DateTime.Now - start);
Console.WriteLine("\n<===============================================>\n");
Console.WriteLine("for loop test starting...");
start = DateTime.Now;
int count = l.Count();
for (int i = 0; i < count; i++)
{
l[i].ToString();
}
Console.WriteLine("for Loop Time for {0} elements = {1}", l.Count(), DateTime.Now - start);
Console.WriteLine("\n<===============================================>\n");
Console.WriteLine("\n\nPress Enter to continue...");
Console.ReadLine();
}
Don't get hung up on this too much though. Performance is the currency of application design but unless your application is experiencing an actual performance hit that is causing usability problems, focus on coding for maintainability and reuse since time is the currency of real life business projects...
It's called "Select" on IEnumerable<T>
I am enlightened, thank you.
This question already has answers here:
Closed 14 years ago.
Of course both F# and C# compile to IL and the CLR JITter does most of the hard work, however I wanted to know whether there's anything implicit in the F# language or its core libraries which result in lesser performance compared to C#?
Additionally, is there anything in the use of functional programming in the .net framework that might make it slower compared to C#?
I am going to sit down and measure differences of course, as that really is the only real way to know for sure, however I just wondered whether anybody had any broad-stroke knowledge on this topic.
See Also
C# / F# Performance comparison
Is a program F# any more efficient (execution-wise) than C#?
There is nothing intrinsic that makes one language faster than the other. They both run on the CLR and hence have roughly the same performance characteristics of any language that runs on the CLR. There are features of the respective languages though that do affect performance.
Tail recursion is a great example. If you write an F# app which heavily uses tail recursion, the compiler will attempt to rewrite it as an iterative loop removing the recursion penalty. Additionally F# uses the .tail IL op code in order to ask the CLR to remove the recursion stack penalty where possible.
It's easy to demonstrate this by translating some F# continuation samples to C# and then insert huge data sets. F# will work and C# will eventually crash.
http://blogs.msdn.com/jaredpar/archive/2008/11/13/comparing-continuations-in-c-and-f-part-3-double-wrong.aspx
But that is not necessarily a deficiency in C#. C# is not meant to be written with continuations while that is certainly the case in F#. It's in fact not surprising that writing algorithms meant for F# in C# produce not so great results.
Conversely, C# iterators are usually more efficient than F# sequence expressions. The reason is that C# iterators are very efficient state machines vs. F#'s are continuation passing.
In general though, in the abscence of threads, if you use the languages as they are intended to be used they will have similar performance characteristics.
A good example is the sieve of eratosthenes.
A co-worker and I wrote similar sieves in C# and F#. The performance of the C# version was almost 10 times slower than it's functional counterpart written by my co-worker.
There were probably some inefficiencies in the C# version that could have been cleaned up, but the F# version is noticeably faster.
This sort of problem lends itself to being written in a functional language..
Hope this helps some.
Edit -
Here's one of the C# examples using similar functionality to F#'s List.Partition. I'll keep looking for the F# example. I have hundreds of projects that it could be in, it's just a matter of sorting through all of my stuff to find it (I save everything I ever experiment with, so this could be time consuming.. lol)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ListPartitionTest
{
public static class IEnumerableExtensions
{
public static KeyValuePair<IEnumerable<T>, IEnumerable<T>> Partition<T>(this IEnumerable<T> items, Func<T, bool> f)
{
return items.Aggregate(
new KeyValuePair<IEnumerable<T>, IEnumerable<T>>(Enumerable.Empty<T>(), Enumerable.Empty<T>()),
(acc, i) =>
{
if (f(i))
{
return new KeyValuePair<IEnumerable<T>, IEnumerable<T>>(acc.Key.Concat(new[] { i }), acc.Value);
}
else
{
return new KeyValuePair<IEnumerable<T>, IEnumerable<T>>(acc.Key, acc.Value.Concat(new[] { i }));
}
});
}
}
class PrimeNumbers
{
public int Floor { get; private set; }
public int Ceiling { get; private set; }
private IEnumerable<int> _sieve;
public PrimeNumbers(int floor, int ceiling)
{
Floor = floor;
Ceiling = ceiling;
}
public List<int> Go()
{
_sieve = Enumerable.Range(Floor, (Ceiling - Floor) + 1).ToList();
for (int i = (Floor < 2) ? 2 : Floor; i <= Math.Sqrt(Ceiling); i++)
{
_sieve = _sieve.Where(x => (x % i != 0 && x != i));
foreach (int x in _sieve)
{
Console.Write("{0}, ", x);
}
Console.WriteLine();
}
return _sieve.ToList();
}
}
class Program
{
static void Main(string[] args)
{
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
int floor = 1;
int ceiling = 10;
s.Start();
PrimeNumbers p = new PrimeNumbers(floor, ceiling);
p.Go();
//foreach (int i in p.Go()) Console.Write("{0} ", i);
s.Stop();
Console.WriteLine("\n{0} to {1} completed in {2}", floor, ceiling, s.Elapsed.TotalMilliseconds);
Console.ReadLine();
}
}
}