Uncover the mystery of how lambda works [duplicate] - c#

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Detailed Explanation of Variable Capture in Closures
public class Polynom {
public delegate double Func(double x);
private Func f;
public Polynom(params double[] coef) {
f = (double x) => {
double sum = 0;
for ( int i = 0 ; i < coef.Length ; i++ )
sum += coef[i] * Math.Pow(x,coef.Length-1-i);
return sum;
};
}
public double evaluate(double x) {
return f(x);
}
public static void Main() {
Polynom a=new Polynom(1,1,1);
Polynom b=new Polynom(2 , 2 , 0);
Console.WriteLine(a.evaluate(2));
Console.WriteLine(b.evaluate(2));
Console.ReadKey();
}
}
Notice how the code in f uses coef, while coef is a paramater of the constructor.
if you think about it, that should not work unless it gets a ref copy of coef, because once the constructor done its job, its parameters are suppose to vanish. but somehow, calling f manages to use coef as if it still exists. HOW?
I would love a good deep explantion if someone can explain this...
Another thing that i would like to know is, the code is the same on every Polynom instance, but does every instance get another copy of that same code? if so, is there a way to make my class run with just 1 copy of that code? (like make it static somehow)

Lambdas and other delegates are implemented as closures, special objects created by the compiler that combine a method of your lambda with all the data that the lambda needs to complete its execution. The values of all local variables and parameters that are used inside the lambda are implicitly captured as data members of the closure, so they remain available until the lambda itself is no longer referenced.
You can think of the closure as a special anonymous class created specifically for your lambda. In your case, a closure may look like this:
private Polynom_Closure {
private readonly double[] coef;
public Polynom_Closure(double[] coef) {
this.coef = coef;
}
public double evaluate(double x) {
double sum = 0;
for ( int i = 0 ; i < coef.Length ; i++ )
sum += coef[i] * Math.Pow(x,coef.Length-1-i);
return sum;
}
}
The compiler makes this class invisibly for you, and then inserts its use into your code:
public Polynom(params double[] coef) {
f = new Polynom_Closure(coef).evaluate;
}

The function is a so-called closure, which is well-explained in this wikipedia article
A closure allows a function to access variables outside its immediate lexical scope. An upvalue is a free variable that has been bound (closed over) with a closure. The closure is said to "close over" its upvalues. The referencing environment binds the nonlocal names to the corresponding variables in scope at the time the closure is created, additionally extending their lifetime to at least as long as the lifetime of the closure itself. When the closure is entered at a later time, possibly from a different scope, the function is executed with its non-local variables referring to the ones captured by the closure.
Concerning your second question: Making a closure static would somewhat contradict the purpose of functional principles.

Related

Why declare a local function static in C# 8.0

In C# 8.0, Static Local Functions are announced
Can anyone help enlighten me as to why you would want to declare a local function as static?
The reason given in in the article:
to ensure that local function doesn't capture (reference) any variables from the enclosing scope
But:
I don't understand why would you want to ensure that?
Is there any other reason or benefits to declare it static? (performance maybe?)
The example code given in the article is:
int M()
{
int y = 5;
int x = 7;
return Add(x, y);
static int Add(int left, int right) => left + right;
}
I don't understand why would you want to ensure that?
Because it prevents you from shooting yourself in the foot. It forces the local function to be a pure function that does not modify the state of the caller.
This returns false, because the function modifies local variables of its caller:
public bool Is42()
{
int i = 42;
Foo();
return i == 42;
void Foo()
{
i = 21;
}
}
And this doesn't, because it doesn't even compile:
public bool Is42()
{
int i = 42;
Foo();
return i == 42;
static void Foo()
{
i = 21;
}
}
It prevents surprises. Of course in these simple examples the benefit isn't immediately clear, because "well it's obvious that Foo() modifies i", but in larger codebases maintained by multiple people and not properly covered by unit tests, this simple modifier prevents grief.
Capturing variables has a small additional cost as it will generate an internally used type where your captured variables are public fields. Consider a slightly modified example:
int M()
{
int y = 5;
int x = 7;
return Add();
int Add() => x + y;
}
It will actually translate to something like this:
int M()
{
int y = 5;
int x = 7;
var capturedVars = new <>c__DisplayClass0_0 { x = x, y = y };
return <M>g__Add|0_0(ref capturedVars);
}
[CompilerGenerated]
private struct <>c__DisplayClass0_0
{
public int x;
public int y;
}
[CompilerGenerated]
internal static int <M>g__Add|0_0(ref <>c__DisplayClass0_0 class_Ref1) =>
(class_Ref1.x + class_Ref1.y);
This answer from CodeCaster and this separate answer from György Kőszeg individually answer different parts of my question, so I'm bringing them both together to form the full picture for the accepted answer:
For Part 1) of my question, #CodeCaster Says:
Because it prevents you from shooting yourself in the foot. It forces the local function to be a pure function that does not modify the state of the caller.
in larger codebases maintained by multiple people and not properly covered by unit tests, this simple modifier prevents grief
So Answer 1 is: Static Local Functions ensure reliable caller method state.
For Part 2) of my question, #György Kőszeg Says:
Capturing variables has a small additional cost as it will generate an internally used type where your captured variables are public fields
And he goes on to give an example of the produced compiler code via reflector.
So Answer 2 is: Static Local Functions prevent variable capturing. Variable capturing comes at a small cost. So there is a small performance boost by declaring the local function static
I think this is just to ensure correct usage of the variables used in the local function, as the documentation says. In large and complex methods, it can prevent accidental usage of enclosing scope variables if there are variables with the same name in the local function.

Why cannot I pass the address of a variable to an anonymous function?

unsafe class Program
{
static void Main(string[] args)
{
int x;
Thread t = new Thread(() => { sum(12, 6, &x); }); // can't pass adrees of x
}
static unsafe void sum(int a ,int b,int* p)
{
*p = a + b;
}
}
Throws the error:
Error CS1686: Local 'x' or its members
cannot have their address taken and be used inside an anonymous method
or lambda expression
The issue is the lifetime of the variable vs. the lifetime of the address taken in the lambda in which it's used. The compiler can ensure that the variable itself lives as long as the lambda (because it's stored in a separate hidden class, due to the capturing), but the address itself (which could be copied somewhere else after the fact) may live longer than the variable, and thus would refer to an address that is no longer valid.
Note that this contrasts with variables captured and used as ref or out parameters. For example:
class Program
{
static void Main(string[] args)
{
int x;
Thread t = new Thread(() => { sum(12, 6, out x); });
}
static void sum(int a, int b, out int p)
{
p = a + b;
}
}
The above is allowed, because the captured variable will be moved from the stack to a separate class that holds it, and that class's lifetime can be ensured to be at least as long as the delegate that will use it.
The unsafe throws a monkey wrench into the works. Unlike ref and out, which have semantics that the compiler can enforce and always use safely, pointers can be stored in arbitrary ways, and the compiler has no way to ensure the lifetime of those pointers. So, even if it captures the x variable to a hidden class like it would in other situations, it still can't guarantee that class remains live for at least as long as the address.
Your specific example is theoretically safe, because the address isn't actually stored anywhere and is used immediately by the method that the anonymous methods calls. But the compiler can't guarantee that safety, and so prohibit any taking of the address of the captured variable.
The memory location may have gone out of scope by the time the lambda is executed. Same reason you can't ref or out a parameter in a lambda. Lambda expressions capture the values of referenced variables at initialization time and use the captured values when they execute. Without the warning, you'd capture the address of x, then later when the lambda executes you would overwrite something else.

C# How to hack/fix 'this' keyword into a struct? [duplicate]

This question already has an answer here:
Why do I have to copy "this" when using LINQ in a struct (and is it OK if I do)?
(1 answer)
Closed 7 years ago.
Apparently you cannot use the keyword "this" in a method in a struct.
Note that in the below example I do not explicitly type "this" but it is implied when I reference the properties "X" or "Y".
My struct:
public struct Coord
{
public int X;
public int Y;
public Coord(int x, int y)
{
X = x;
Y = y;
}
// some other methods omitted
public List<int> GetPossibles()
{
return LaurenceAI.Values.Where(n => LaurenceAI.Possibilities[X, Y, n]).ToList();
}
}
usage example:
foreach(int numeral in targetCoord.GetPossibles())
{
//do stuff
}
Error:
Error 1 Anonymous methods, lambda expressions, and query expressions inside structs cannot access instance members of 'this'. Consider copying 'this' to a local variable outside the anonymous method, lambda expression or query expression and using the local instead. C:\Projects\Sodoku\SodokuSolver\Sodoku\LaurenceAI.cs 367 74 Sodoku
Questions:
What is the technical reason that a method in a struct cannot use keyword "this"?
Is there an elegant way to fix this so that I don't have to type out the reflection code longhand every time I want a list of possible numerals for a given Coord?
The reason is that structs are passed by value, not by reference. Using this in this context results in typically not what you want - it'll access the this pointer of the copy, not the outer object, and it'll be really confusing when any assignments you make aren't showing in the outer call. It's annoying in this specific circumstance, but in general it's stopping more weird errors.
The error message actually gives you a fairly reasonable solution - copy the values first. Do something like:
public List<int> GetPossibles()
{
var localX = X;
var localY = Y;
return LaurenceAI.Values.Where(n => LaurenceAI.Possibilities[localX, localY, n]).ToList();
}

Why Lambda variable scope exists outside LINQ Query?

I read this question(What is the scope of a lambda variable in C#?)
But it is about Lambda variable scope inside LINQ Query.
Now to my question
Lets say I have a very simple LINQ query.
var Foo = FoobBar.Select(x => x);
var x = somefunction();
Compiler says : A local variable 'x' cannot be declared in this scope because it would give a different meaning to 'x', which is already used in a 'child' scope to denote something else.
Why is that so? Shouldn't Lambda variable cease to exist when LINQ query ends?
EDIT: After reading answers i came to conclusion that its the outside x (returned from function) whose scope extends inside LINQ Query.
It's not about LINQ it's about child scopes.
For example:
foreach (var bar in FooBar.Bars)
{
var x = FooBar.GetFoo();
}
var x = new Foo();
produces exactly the same error message from compiler.
To fix that you just have to place variables in different (non-nesting) scopes. For example:
foreach (var bar in FooBar.Bars)
{
var x = FooBar.GetBar();
}
{
var x = new Foo();
}
Lets look carefully,
var Foo = FoobBar.Select(x => x);
true the scope of x ends in the expression
var x = somefunction()
Now this is interesting, this is scoped for the entire method which holds the lamda expression too, so the compiler cannot distinguish since the scope of the latter overlaps the former. and very informative message too give a different meaning to 'x', which is already used in a 'child' scope (Select as in your case)
Similar scope question
maybe you can include braces around the other so that it's scope is defined
{
var x = somefunction()
}
Think if C# would allow those two variables to exist on same scope level, this will not be possible:
static void test() {
Action<int> x = (z) => {
Console.WriteLine(z);
};
int[] i = { 5,2,0,1,3,1,4 };
var kyrie = i.Select (x => x);
}
How you would say to C# that you wanted to assign the Action delegate named x to kyrie variable; or the vice versa, how you would say to C# you wanted to use the integer projection itself? How C# would resolve that?
And C# scoping resolution is very consistent whether you declare it before the other variable or after the other variables, they are the same. e.g. http://www.anicehumble.com/2012/05/java-said-c-said-scope-consistency.html
To disambiguate those scenario, C# doesn't allow you to compile a program that have variable names that exists on same level
It's all about expressing your intent to the compiler in a non-ambiguous way. And C# did a good job on that regard
It's not clear (to the compiler) which 'x' you mean by the second 'x' (after the =>).
What if you wrote this:
var Foo = FoobBar.Select(y => x);
var x = somefunction();
then that x in the lambda would clash with the 'somefunction' result.
You can't declare two variables with the same name in the same scope.
"Same scope" meaning they either are both inside the current scope
void method()
{
int a;
int a; //wrong!
}
or one is in the current and the other is in a child scope.
void method()
{
int a;
for(;;)
{
int a; //wrong again!
}
}
This is by design and holds for any variable, from ints to lambda references.

Using out keyword in c#

can anyone suggest me the exact use of out keyword as a paramter, and how its connected for returning multiple values from the function, as in this POST, i am confused with out variable with normal variable. can anyone help me for this.
This is frequently confusing, and I think the MSDN documentation actually is a bit "clear only if already known". That is, it is correct, but it really only makes sense if you already understand the concept.
Here's how I think of it.
A regular parameter makes a copy of the value of the argument. When you say:
static int M(int z) { z = z + 1; return z; }
...
int x = 123;
int y = M(x);
That is just like you said:
int x = 123;
int z = x; // make a copy of x
z = z + 1;
int y = z;
A ref or out parameter make an alias for an existing variable. When you say
static void N(ref int q) { q = q + 1; }
...
int x = 123;
N(x);
That is the same as saying:
int x = 123;
// MAGIC: q is now an another name for variable x
q = q + 1;
q and x are two different names that refer to the same variable. Incrementing q also increments x because they are the same. z and x in the previous example are two different names that refer to two different variables. Incrementing z does not change x.
Summing up: "out" and "ref" just mean "do not make a new variable; rather, temporarily make a second name for an existing variable".
Is that now clear?
UPDATE: I did not say what the difference between "out" and "ref" is. The difference is simple. On the "caller" side, a "ref" must be a definitely assigned variable before the method is called. An "out" need not be. On the "callee" side, a "ref" may be read before it is written to, but an "out" must be written to before it is read. Also, an "out" must be written to before control leaves the method normally.
MSDN documentation already does a great job explaining this:
The out keyword causes arguments to be passed by reference. This is
similar to the ref keyword, except that ref requires that the variable
be initialized before being passed. To use an out parameter, both the
method definition and the calling method must explicitly use the out
keyword. For example:
class OutExample
{
static void Method(out int i)
{
i = 44;
}
static void Main()
{
int value;
Method(out value);
// value is now 44
}
}
It's very frequently used in a pattern that "tries" to get a value, something like:
int result;
if(Int32.TryParse("123", out result))
{
Console.WriteLine(result + 1);
}
out keyword should be used when you want to:
a) Allow your function to modify specific variable from calling code stack AND
b) enforce setting this variable value inside your function
MSDN is always a good place to start
In most languages c# included you can pass values in 2 ways, by value, by reference.
by value gives the method a copy of your data, so changing the data wont have any effect on the original data
by reference essentially gives the method the memory address of your data, so if the method modifies the data, it changes the original.
Out is a special type of ref, in that you do not need to initialise the variable before you call the method, it can be called with null being passed in. and it MUST be set by the method.
Another way you can think of it (from the outside code's point of view) is:
val = read only
ref = read/write
out = write only.
http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx
out keyword is good if you want to return multiple values of pre-defined types (for example an int, a List<string> and a DateTime), and you don't want to create a new class just for this purpose.
Ok,
let look at the usual pattern for this kind of function - the TrySomething.
Suppose you have a function that might succeed giving you an value or not but you don't won't to use an exception for this because you don't want the overhead or it's a common trait.
Then you normaly return true if the method suceeded and false if not. But where would you put your outputvalue to?
One possible answer is using an out parameter like this:
bool TrySomething(MyInputType input, out MyOutputType output)
{
output = default(MyOutputType);
/* ... Try getting the answer ... */
if (!successful)
return false;
output = successfulOutput;
return true;
}
Remark:
Or you might consider using a Tuple<bool,MyOutputType> and indeed F# interpretes the pattern above as resulting in such a tuple by itself.

Categories

Resources