Assume there is the following delegate:
delegate int Foo(int x);
I've seen people create this delegate in multiple ways, for example:
Example 1:
Foo f = Bar;
With Bar being:
int Bar(int x) => x * 2;
Example 2:
Foo f = new Foo(x => x * 2);
Example 3:
Foo f = x => x * 2;
Are there any differences (pro's, con's, efficiency, etc.) other than personal coding style preference?
Although examples 2 and 3 are pretty much identical, the two may become different from example 1 when used as local declarations.
There is no difference between 2 and 3: in 2, you specify delegate type explicitly, while in the second case you let the compiler figure out the type of the delegate by looking at the type of f. When f is a local variable, you can further simplify the declaration to
var f = new Foo(x => x * 2);
so that Foo is specified only once.
The first example uses a lambda-bodied method to define a delegate through a method group. The obvious difference here is that this way of declaring a delegate requires a separate method.
However, there is another subtle difference here: when delegates from examples 2 and 3 are used in a local context, they can close over local variables. In contrast, example 1 cannot capture local variables, even if you use it in a local context.
Code examples 2 and 3 let you do this:
Foo Make(int y) {
var res = x => x * y; // y is captured from the context
return res;
}
while example 1 is limited to using x that you pass and any fields of the object that declares Bar.
Therefore, you need to consider these points when deciding among these three options:
If you need a delegate that does not close over local variables, and relies on logic that can be used elsewhere, use method group,
If you need a delegate that closes over local variables, use 2 with var, or 3,
If you are declaring a field, use 3, because you must specify the type of the field anyway.
The main difference is that in Example 1 you can reuse your function Bar. I believe that 2 and 3 are synonymous and that the lambda expression is just syntactic sugar for the anonymous function.
The first, example below is called expression bodied method, so the delegate will refer to this method which returns an int and will take whatever value of x is and multiply it by 2.
int Bar(int x) => x * 2;
The second, example below is using a lambda expression, it is instantiating the delegate and passing a reference to the method that will return the value of x multiplied by 2.
Foo f = new Foo(x => x * 2);
The last example is just syntactic sugar which behind the scenes is pretty much the same as the example above.
Foo f = x => x * 2;
Are there any differences (pro's, con's, efficiency, etc.) other than
personal coding style preference?
they all essentially accomplish the same end result, however, the first example you could reuse the method as many times as you want whereas the last two you're passing in a behaviour that just gets executed (at a later time) without any identifier to the method for later reuse.
Related
I am coming from a OOP, non-functional background, so I am having trouble fully visualizing several online examples regarding continuation passing. Also, functional languages like Scheme don't have to specify types of arguments or return values, so I am unsure whether I got the idea correctly.
Since C# supports lambdas, I took the first example from the Wikipedia article and tried to port it to C# with strong typing, to see how the pattern would apply:
// (Scheme)
// direct function
(define (pyth x y)
(sqrt (+ (* x x) (* y y))))
// rewriten with CPS
(define (pyth& x y k)
(*& x x (lambda (x2)
(*& y y (lambda (y2)
(+& x2 y2 (lambda (x2py2)
(sqrt& x2py2 k))))))))
// where *&, +& and sqrt& are defined to
// calculate *, + and sqrt respectively and pass the result to k
(define (*& x y k)
(k (* x y)))
So, rewriting the CPS pyth& version in C# resulted in:
// (C#6)
// continuation function signature
delegate double Cont(double a);
// *&, +& and sqrt& functions
static double MulCont(double a, double b, Cont k) => k(a * b);
static double AddCont(double a, double b, Cont k) => k(a + b);
static double SqrtCont(double a, Cont k) => k(Math.Sqrt(a));
// sqrt(x*x + y*y), cps style
static double PythCont(double x, double y, Cont k) =>
MulCont(x, x, x2 =>
MulCont(y, y, y2 =>
AddCont(x2, y2, x2py2 =>
SqrtCont(x2py2, k))));
I could have used generics instead of double, but signatures would be longer. Anyway, what I am not sure is:
Is the Cont signature above correct (i.e. Func<double, double>)? Should the continuation fn. accept the parameter, process it, and then return the value of the same type back?
When I first started reading about continuations, I got the feeling that this continuation function will get invoked for each step in the call stack, but in the example above it's only passed to sqrt&, and all other calls get lambdas which don't really "pass" intermediate values to the original continuation. The code above in the function above is basically analogue to k(Math.Sqrt(x * x + y * y)), so does this mean my assumption about intermediate "hooks" is wrong?
Yes, unless you want to do anything non-numerical with the outermost continuation, it is correct.
You would only need more "Cont"s when your original expression involves more types, e.g.
(define (foo x) (if (= x 0) 1 0))
in which case it might look like this (sorry I write in scheme for brevity):
(define (foo& x k)
(=& x 0 (lambda (r1)
(if r1 (k 1) (k 0)))))
-- now the outermost continuation has a number (let's say an int) as input, while the one provided to "=&" has bool->int type.
You are almost right (up to duality) -- each step on the call stack is now a call to some continuation.
In general you might be confusing first-class continuations with cps -- the former is a language feature (as in scheme where you can access the current continuation with call/cc operator), the latter is a technique you can use anywhere.
You actually can convert expressions to cps without even having higher-order functions in your language (by just representing them somehow).
Another thing you asked is how cps relates to control flow. Well, notice that in applicative, functional language (like scheme) the only thing you have specified is that in case of application, you first evaluate the operands and the operator, and then apply the latter to the former. It does not matter in what order you evaluate the operands -- you might do it left-to-right, right-to-left [or perhaps in some crazy way]. But what if you're not using purely functional style, and the operands cause some side effects? They might e.g. print something to stdout, and later return some value. In that case, you would like to have control over the order. If I remember well, programs compiled with gambit-C evaluate arguments right-to-left, while interpreted with gambit's interpreter left-to-right -- so the problem really exists ;). And precisely then the cps might save you [actually there are other means as well, but we're about cps right now!].
In the scheme example you posted it is forced that the arguments of "+" are evaluated left-to-right.
You might alter that easily:
(define (pyth& x y k)
(*& y y (lambda (y2)
(*& x x (lambda (x2)
(+& x2 y2 (lambda (x2py2)
(sqrt& x2py2 k))))))))
And that's the thing.
Of some further applications, as guys already said in the comments, transformation to CPS moves every application to tail-position, so the call stack is being replaced with lambdas, and further if you defunctionalize them, what you get is a data structure representing the control flow -- a neat form to be converted to, say C, or some other imperative language. Fully automagicaly!
Or, if you'd like to implement some monad mumbo-jumbo, say Maybe monad, in CPS it's easy, just prepend to each continuation-lambda the test on whether the received value is "Just something" (in which case do the job and push the result to your continuation), or "Nothing", in which case you just push Nothing (to the continuation-lambda).
Of course rather by another program or macro, not by hand, as it might be tedious -- the most magic behing cps is that it's so easy to automate the transformation to cps.
Hope I didn't make it unnecessarily complicated.
I have created a very comprehensive introduction to the Continuation monad that you can Find Here Discovering the Continuation Monad in C#
Also you can find a.Net Fiddle here
I Repeat it in summary here
Starting from an initial Function
int Square(int x ){return (x * x);}
Use Callback and remove return type
public static void Square(int x, Action<int> callback)
{
callback(x * x);
}
Curry the Callback
public static Action<Action<int>> Square(int x)
{
return (callback) => { callback(x * x); };
}
Generalize the returned Continuation
public static Func<Func<int,T>,T> Square<T>(int x)
{
return (callback) => { callback(x * x); };
}
Extract the Continuation Structure Also Known As the Return Method of the monad
delegate T Cont<U, T>(Func<U, T> f);
public static Cont<U, T> ToContinuation<U, T>(this U x)
{
return (callback) => callback(x);
}
square.ToContinuation<Func<int, int>, int>()
Add The bind Monadic method and thus Complete the Monad
public static Cont<V, Answer> Bind<T, U, V, Answer>(
this Cont<T, Answer> m,
Func<T, Cont<U, Answer>> k,
Func<T, U, V> selector)
{
return (Func<V, Answer> c) =>
m(t => k(t)(y => c(selector(t, y))));
}
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();
}
Basic manuals on C# state that to change a value type when passed to another method you must use the out or ref keywords, etc.
For example:
int Loop(int counter)
{
return(++counter);
}
void ClickIt ()
{
int count = 0;
for (int c1 = 0; c1 < 10; c1++)
{
count = Loop(count);
Console.Writeline(count);
}
}
Here, ClickIt outputs the following result: 1, 2, 3, 4, ... 10
In the example, count (a value type), which is being passed from the method ClickIt to the method Loop without out or ref, is being changed in Loop. And Loop then returns count to the calling method ClickIt which picks up the change to count.
So, my question is: When is a value type, when passed as an argument to another method, required to use out or ref so that the value can be changed?
You have an incorrect understanding of the meaning of "ref", and you are also mixing up values and variables. These are common mistakes.
Let's go back to basics.
A variable is a storage location which can contain a value.
Let's simplify your program:
int M(int x)
{
x++;
return x;
}
void N()
{
int y = 0;
y = M(y);
}
If N is called, what happens?
Imagine a variable is a drawer that can contain a sheet of paper. We make a drawer and label it y. In y we put a piece of paper that says "0". Now we call M(y). What happens?
We make a new drawer labeled "x" and we make a photocopy of the piece of paper in "y". We put the copy in drawer x. y contains a piece of paper that says 0, and x contains a different piece of paper that also contains 0.
Now in M we increment x. What happens? We make a new piece of paper that says 1, throw away the old one, and put the new one in drawer x.
Now we make a photocopy of the value in x, so we have another piece of paper that says 1. When M returns we put that piece of paper into y and throw away the 0 that is already in there.
Did M modify y? No. M only modified x. N modified y, twice. Once when y was created, and once after M returned.
Notice that we made two copies. First, we made a copy of y on the way in to M and copied it to x, and then we made a copy of x on the way out and copied it to y.
Now suppose we have
void P(ref int b)
{
b++;
}
void Q()
{
int c = 0;
P(ref c);
}
We run Q. What happens? We make a drawer called c and put a piece of paper in it that says "0". What happens when we call P? Something different. This time we make a drawer called b and put a piece of paper in it that says "don't use this drawer! Every time you try to use this drawer, use c instead!" That is, b refers its behaviour to c.
Now P tries to increment b. It tries to get a value out of b, but discovers that b says no, use c. So it looks in c, finds 0, makes a new piece of paper that says 1, replaces the contents of b -- no, wait, we need to replace the contents of c -- with 1, and returns. So c is updated to 1.
Does it make sense why these two things are different? The first is called copy in, copy out because we make a photocopy of y on the way in to M, and a copy of x on the way out. The second is called by reference because b refers its behaviour to c; no values are copied.
In your sample you actually do not modify passed count variable.
When it's passed, a copy inside a Loop function scope is being created. Then modification done, you return in back and set to your count variable.
Actually, the purpose of:
ref - is that variable should be already initialized before passing into function. And copy is not created inside. You modify passed variable directly. As result - you don't need to return modified value and set it back to your variable.
out - it does not require passed variable to be initialized before passing into your function. But it actually MUST be initialized inside that function.
Hope that's all.
Long comment...
Your code could be confusing - make sure to separate result of function from parameter:
void ClickIt ()
{
int count =0;
for (int c1 =0; c1 < 10; c1++)
{
var resultCount = Loop(count);
Console.Writeline("Result:{0}, count:{1}", resultCount, count);
}
}
Answer (opinion based) - you should almost never use out/ref - it is much harder to reason about than return values. Such functions also are hard to use in LINQ/lambda expression due to need of arguments to be variables.
Common case when it somewhat acceptable is when function returns more than one result (like TryParse), but consider if some other return type (i.e. nullable int?) would work too.
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.
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.