Consider the factorial function defined within a method body as a lambda expression and assigned to a variable:
Func<int, int> factfail = n =>
{
if (n == 0)
return 1;
else
return n * factfail(n-1);
};
This fails, since factfail isn't bound by the the local variable yet.
Is there a way to add a sort of fixpoint - by abstracting over the function itself?!
Func<Func<int, int>, int, int> fact_ = (fact, n) =>
{
if (n == 0)
return 1;
else
return n * fact(n-1);
};
fact_(??);
long story:
I need to write a recursive function that has the side effect of changing some outer state.
Therefore i am trying to write that method as a lambda expression that captures that outer state.
I am still experimenting with different styles how to write that and - besides of that one dictionary that needs to be the same for all recursive calls - i want to be as purely functional and lazy as possible.
So i was playing with LINQ, since it helps me reducing mutual data.
It also helps with understanding which parts of the code can be expressed in a functional style.
To be brief in the LINQ statement it is helpful to be able to define some helper functions in front of and i did that by binding lambda expressions to variables.
And with lamda expression i also can capture my dictionary without the need to pass its reference to the method explicitely, which is quite nice.
not sure if i am on the right track though...
You can find more information about recursive lambda expressions in this blog post by Mads Torgersen. He shows how to define the usual fixed point combinator. He uses factorial function as an example, so you can find your exact sample there :-).
However, in practice, you can just define a local Func<..> variable and then mutate it. If you want to give a name to the delegate, then it works just fine (it is a bit dirty, but simple):
Func<int, int> fact = null;
fact = (n) => (n == 0) ? 1 : n * fact(n-1);
This works, because the closure captures reference to the fact variable, so when you actually call it (during the recursive call), the value is not null anymore, but references the delegate.
Related
We can do:
using (Stream s ..)
and:
for (int i ...)
Why can't we as well do something like:
while ((int i = NextNum()) > 0) {..}
I find it very useful and sensible.
I'm not a language designer, but I'll give it an educated guess.
The clause inside the while() is executed every single time the loop is executed. (+1 more time at the end.) The statement int i = NextNum() declares a local variable. You can't declare a local variable more than once.
Update
Semantically, it makes sense that this should be possible. In fact, as pointed out in the comments, this is possible in other languages. However, this would not be possible in C# without re-writing some major syntax rules.
Local variables must be declared in a statement. I believe the language to be separated this way because a variable declaration is not really executed. When you see a line of code that creates a variable and assigns it a value, that is actually just a shortcut for two statements. From the ECMA-334 Specification:
The example
void F() {
int x = 1, y, z = x * 2;
}
corresponds exactly to
void F() {
int x; x = 1;
int y;
int z; z = x * 2;
}
The variable declaration part by itself is not "executed". It just means that there should be some memory allocated on the stack for a certain type of variable.
The while statement is expecting a boolean expression, but an expression cannot be composed of a statement -- without a special casing some new grammar.
The for loop is specially designed to declare a local variable, but you'll note that declaration part is "executed" only once.
The using statement was specifically designed to declare local variables (and dispose of them). It is also "executed" only once.
Also consider that a local variable declaration doesn't return a value -- it can't since the it allows you to declare multiple variables. Which value would this statement return?
int x = 1, y, z = x * 2;
The above statement is a local-variable-declaration. It is composed of a type, and three local-variable-declarators. Each one of those can optionally include an "=" token and a local-variable-initializer To allowing a local variable to be declared in this manner would mean that you pull apart the existing grammar a bit since you would need the type specifier, but mandate a single declarator so that it could return a value.
Enabling this behavior may nave negative side effects also, Consider that the while and do/while statements are opposite, but parallel. As a language designer, would you also enable the do statement to declare a local variable? I don't see this as possible. You wouldn't be able to use the variable in the body of the loop because it wouldn't have been initialized yet (as of the first run). Only the while statement would be possible, but then you would destroy the parallelism between while and do statements.
Don't know for certain but here is my educated guess.
The for case works because it actually has 3 parts.
The iteration variable
The terminating condition
The increment
These 3 run differing amounts of times. #1 runs only once, #2 runs number of iterations +1 and #3 runs once per iteration. Since #1 runs only once it's a nice and clean place to define a variable.
Now lets examine the while loop. It only has 1 part and it runs every iteration + 1. Since it runs every single time it's not a great place to define a variable which must necessarily be a part of the condition. It raises questions like
Should the define happen once or once per iteration? If it's the latter how many people will misunderstand this and mess up the conditional? If it's the former then you have a complete statement of which only part executes once per query
How do multiple variable defines behave?
I'm guessing the complexity / ambiguity is one of the reasons why it's not allowed. That and it's probably never been high on the priority list.
Because then it's defined in every iteration. A for loop doesn't do that. (So you cant define it again after the first loop. Since it already exists.)
As opposite to the 'for' loop, 'while' doesn't have a initialization part. The 'for' syntax looks like this:
for ( initializer; conditional expression; loop expression)
{
statements to be executed
}
and the 'while' looks like this:
while (condition)
{
statements to be executed
}
The closest thing to your request is:
int i;
while ((i = NextNum()) > 0) { ... }
There's no inherent reason why it couldn't be done - the C# designers just chose not to allow it. It works just fine in Perl, for example ("while ((my $i = NextNum()) > 0) { ... }").
Variable declarations are statements; the while loop expects an expression (an expression can be a statement, but not the other way around). using and for, on the other hand, are special-cased to allow variable declarations.
More importantly, the scope of such a thing would be unclear. Consider:
int x;
// ...
y = (int x = 42) + x;
// what is y?
Or worse:
(int x = 42) + (int x = 42);
Or even:
(int x = 42, y = 24) // what is the value of this expression?
Once you allow declarations be expressions, you have to deal with these things. In particular, the last example becomes a problem because it's hard to disambiguate between expression-declaration-as-a-statement or statement-declaration, so the expression style will have to be general enough to be how we do statement declarations.
This is starting to get to be a bit of a hairy design challenge, and since it's not really a very important feature, it's likely the C# committee decided not to allow declarations be expressions (or they simply never thought of it :).
Finally, you can actually get what you want with just a for loop. For example:
while ((int i = NextNum()) > 0) {..}
// becomes...
for (int i; (i = NextNum()) > 0; ) {..}
// or...
for (int i = NextNum(); i > 0; i = NextNum()) {..}
Ten years later and it's possible,
while (NextNum() is int i and > 0) { ..}
This is more of a why question. Here it goes.
C# 7.0 added a new feature called "Local Function". Below is a code snippet.
public int Fibonacci(int x)
{
if (x < 0) throw new ArgumentException("Less negativity please!", nameof(x));
return Fib(x).current;
(int current, int previous) Fib(int i)
{
if (i == 0) return (1, 0);
var (p, pp) = Fib(i - 1);
return (p + pp, p);
}
}
What I dont understand is, its doing a recursive call to the same method. We can easily achieve this with a normal foreach. Then why a local function.
MSDN says
methods implemented as iterators commonly need a non-iterator wrapper
method for eagerly checking the arguments at the time of the call.
(The iterator itself doesn’t start running until MoveNext is called).
Need some help in understanding the concept that it.
its doing a recursive call to the same method. We can easily achieve this with a normal foreach
That are two different things: tail recursion (method calling itself at the end of the method itself) or iterating over a collection. They are not always exchangeable, but they can be used to achieve the same end result.
The local function is nothing more that a class method, with a scope limited to the method body it is declared in.
Local functions are useful for many more than recursion. It is an easy way to prevent repeating code in several blocks.
I have a List/IEnumerable of objects and I'd like to perform a calculation on some of them.
e.g.
myList.Where(f=>f.Calculate==true).Calculate();
to update myList, based on the Where clause, so that the required calulcation is performed and the entire list updated as appropriate.
The list contains "lines" where an amount is either in Month1, Month2, Month3...Month12, Year1, Year2, Year3-5 or "Long Term"
Most lines are fixed and always fall into one of these months, but some "lines" are calulcated based upon their "Maturity Date".
Oh, and just to complicate things! the list (at the moment) is of an anonymous type from a couple of linq queries. I could make it a concrete class if required though, but I'd prefer not to if I can avoid it.
So, I'd like to call a method that works on only the calculated lines, and puts the correct amount into the correct "month".
I'm not worried about the calculation logic, but rather how to get this into an easily readable method that updates the list without, ideally, returning a new list.
[Is it possible to write a lambda extension method to do both the calculation AND the where - or is this overkill anyway as Where() already exists?]
Personally, if you want to update the list in place, I would just use a simple loop. It will be much simpler to follow and maintain:
for (int i=0;i<list.Count;++i)
{
if (list[i].ShouldCalculate)
list[i] = list[i].Calculate();
}
This, at least, is much more obvious that it's going to update. LINQ has the expectation of performing a query, not mutating the data.
If you really want to use LINQ for this, you can - but it will still require a copy if you want to have a List<T> as your results:
myList = myList.Select(f => f.ShouldCalculate ? f.Calculate() : f).ToList();
This would call your Calculate() method as needed, and copy the original when not needed. It does require a copy to create a new List<T>, though, as you mentioned that was a requirement (in comments).
However, my personal preference would still be to use a loop in this case. I find the intent much more clear - plus, you avoid the unnecessary copy operation.
Edit #2:
Given this comment:
Oh, and just to complicate things! the list (at the moment) is of an anonymous type from a couple of linq queries
If you really want to use LINQ style syntax, I would recommend just not calling ToList() on your original queries. If you leave them in their original, IEnumerable<T> form, you can easily do my second option above, but on the original query:
var myList = query.Select(f => f.ShouldCalculate ? f.Calculate() : f).ToList();
This has the advantage of only constructing the list one time, and preventing the copy, as the original sequence will not get evaluated until this operation.
LINQ is mostly geared around side-effect-free queries, and anonymous types themselves are immutable (although of course they can maintain references to mutable types).
Given that you want to mutate the list in place, LINQ isn't a great fit.
As per Reed's suggestion, I would use a straight for loop. However, if you want to perform different calculations at different points, you could encapsulate this:
public static void Recalculate<T>(IList<T> list,
Func<T, bool> shouldCalculate,
Func<T, T> calculation)
{
for (int i = 0; i < list.Count; i++)
{
if (shouldCalculate(items[i]))
{
items[i] = calculation(items[i]);
}
}
}
If you really want to use this in a fluid way, you could make it return the list - but I would personally be against that, as it would then look like it was side-effect-free like LINQ.
And like Reed, I'd also prefer to do this by creating a new sequence...
Select doesn't copy or clone the objects it passes to the passed delegate, any state changes to that object will be reflected through the reference in the container (unless it is a value type).
So updating reference types is not a problem.
To replace the objects (or when working with value types1) this are more complex and there is no inbuilt solution with LINQ. A for loop is clearest (as with the other answers).
1 Remembering, of course, that mutable value types are evil.
We all know that Expression Trees do not support recursion.
I can create a recursive Func, wrap it in an expression tree, and invoke it.
Func<int, int> func1 = null;
func1 = x => (x == 0) ? 1 : x * func1(x - 1);
Expression<Func<int, int>> expression1 = i => func1(i);
var func1 = expression1.Compile();
var z1 = func1.Invoke(5);
However, when I try to serialize (eg using MetaLINQ) , I of course get an exception as it is a recursive expression.
Lisp constructs expression trees and supports recursion. Genetic Programming mutates expression trees. There are some types of problems whose solutions are inherently recursive, because of prior state they need to track: tree traversal, depth-first search, and divide-and-conquer algorithms. I am aiming to generate efficient algorithms within a managed distributed environment, where branches can be passed around and recombined.
My question is: How could I override the serialization / deserialization to swap out / in the call with a non recursive "mock" token , swapping the recursive call back in when reloading the deserialized tree?
I know this is not an exact answer to your question, but I would apply the Replace Recursion with Iteration Refactoring pattern.
Recursion is usually considered bad, and sometime looked upon as lazy. I however understand the need to solve the problem first, then refactor the code so that is can be maintained and read with ease.
I'm trying to wrap my head around what the C# compiler does when I'm chaining linq methods, particularly when chaining the same method multiple times.
Simple example: Let's say I'm trying to filter a sequence of ints based on two conditions.
The most obvious thing to do is something like this:
IEnumerable<int> Method1(IEnumerable<int> input)
{
return input.Where(i => i % 3 == 0 && i % 5 == 0);
}
But we could also chain the where methods, with a single condition in each:
IEnumerable<int> Method2(IEnumerable<int> input)
{
return input.Where(i => i % 3 == 0).Where(i => i % 5 == 0);
}
I had a look at the IL in Reflector; it is obviously different for the two methods, but analysing it further is beyond my knowledge at the moment :)
I would like to find out:
a) what the compiler does differently in each instance, and why.
b) are there any performance implications (not trying to micro-optimize; just curious!)
The answer to (a) is short, but I'll go into more detail below:
The compiler doesn't actually do the chaining - it happens at runtime, through the normal organization of the objects! There's far less magic here than what might appear at first glance - Jon Skeet recently completed the "Where clause" step in his blog series, Re-implementing LINQ to Objects. I'd recommend reading through that.
In very short terms, what happens is this: each time you call the Where extension method, it returns a new WhereEnumerable object that has two things - a reference to the previous IEnumerable (the one you called Where on), and the lambda you provided.
When you start iterating over this WhereEnumerable (for example, in a foreach later down in your code), internally it simply begins iterating on the IEnumerable that it has referenced.
"This foreach just asked me for the next element in my sequence, so I'm turning around and asking you for the next element in your sequence".
That goes all the way down the chain until we hit the origin, which is actually some kind of array or storage of real elements. As each Enumerable then says "OK, here's my element" passing it back up the chain, it also applies its own custom logic. For a Where, it applies the lambda to see if the element passes the criteria. If so, it allows it to continue on to the next caller. If it fails, it stops at that point, turns back to its referenced Enumerable, and asks for the next element.
This keeps happening until everyone's MoveNext returns false, which means the enumeration is complete and there are no more elements.
To answer (b), there's always a difference, but here it's far too trivial to bother with. Don't worry about it :)
The first will use one iterator, the second will use two. That is, the first sets up a pipeline with one stage, the second will involve two stages.
Two iterators have a slight performance disadvantage to one.