473,800 Members | 2,273 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

lambda usages

I am not understanding what's happening in the code below (from
accelerated c#) -- I know what the outcome but not how .net does it:

using System;
using System.Linq;
public class LambdaTest
{
static void Main()
{
int counter = 0;
WriteStream( () =counter++ );
Console.WriteLi ne( "Final value of counter: {0}", counter );
}
static void WriteStream( Func<intcounter )
{
for( int i = 0; i < 10; ++i )
{
Console.Write( "{0}, ", counter() );
}
Console.WriteLi ne();
}
}

From what I understand, we are creating Func generic delegate ,
which is takes no parameters and returns the int. We and to that
delegate we pass local value type counter. Then why would counter
changed upon the retrun from WriteStream? Doesn't WriteSteam operate
on the local counter argument?

need some lambda education....

Thanks
Oct 22 '08 #1
11 1690
"puzzlecrac ker" <ir*********@gm ail.comwrote in message
news:9b******** *************** ***********@p49 g2000hsd.google groups.com...
I am not understanding what's happening in the code below (from
accelerated c#) -- I know what the outcome but not how .net does it:

using System;
using System.Linq;
public class LambdaTest
{
static void Main()
{
int counter = 0;
WriteStream( () =counter++ );
Console.WriteLi ne( "Final value of counter: {0}", counter );
}
static void WriteStream( Func<intcounter )
{
for( int i = 0; i < 10; ++i )
{
Console.Write( "{0}, ", counter() );
}
Console.WriteLi ne();
}
}

From what I understand, we are creating Func generic delegate ,
which is takes no parameters and returns the int. We and to that
delegate we pass local value type counter. Then why would counter
changed upon the retrun from WriteStream? Doesn't WriteSteam operate
on the local counter argument?

need some lambda education....

Thanks
Well, we are not passing counter into the generic delegate, the generic
delegate is using the local counter (local to the outer function) which is
the same value at the same address when updated/modified from the Main
function or the delegate. The "equivalent " method would be:

static int Increment(ref int counter) { counter++; }

By equivalent I mean that counter is being "passed" into the method (by
reference) instead of the method accessing the variable of the parent code
block directly.

I believe this is correct but I'm not 100% so I hope someone else replies if
I'm wrong :)

HTH,
Mythran
Oct 22 '08 #2
Mythran wrote:
"puzzlecrac ker" <ir*********@gm ail.comwrote in message
news:9b******** *************** ***********@p49 g2000hsd.google groups.com...
>I am not understanding what's happening in the code below (from
accelerated c#) -- I know what the outcome but not how .net does it:

using System;
using System.Linq;
public class LambdaTest
{
static void Main()
{
int counter = 0;
WriteStream( () =counter++ );
Console.WriteLi ne( "Final value of counter: {0}", counter );
}
static void WriteStream( Func<intcounter )
{
for( int i = 0; i < 10; ++i )
{
Console.Write( "{0}, ", counter() );
}
Console.WriteLi ne();
}
}

From what I understand, we are creating Func generic delegate ,
which is takes no parameters and returns the int. We and to that
delegate we pass local value type counter. Then why would counter
changed upon the retrun from WriteStream? Doesn't WriteSteam operate
on the local counter argument?

need some lambda education....

Thanks

Well, we are not passing counter into the generic delegate, the
generic delegate is using the local counter (local to the outer
function) which is the same value at the same address when
updated/modified from the Main function or the delegate. The
"equivalent " method would be:
static int Increment(ref int counter) { counter++; }

By equivalent I mean that counter is being "passed" into the method
(by reference) instead of the method accessing the variable of the
parent code block directly.

I believe this is correct but I'm not 100% so I hope someone else
replies if I'm wrong :)
Mostly right, but the difference is that here we have a closure, the
reference to the function's counter variable is part of the delegate. With
a reference argument the caller (i.e. WriteStream) would have to pass the
reference, here the caller isn't involved in any way.
>
HTH,
Mythran

Oct 22 '08 #3
On Oct 22, 2:20*pm, "Ben Voigt [C++ MVP]" <r...@nospam.no spamwrote:
Mythran wrote:
"puzzlecrac ker" <ironsel2...@gm ail.comwrote in message
news:9b******** *************** ***********@p49 g2000hsd.google groups.com....
I am not understanding what's happening in the code below (from
accelerated c#) -- I know what the outcome but not how .net does it:
using System;
using System.Linq;
public class LambdaTest
{
*static void Main()
*{
* * int counter = 0;
* * WriteStream( () =counter++ );
* * Console.WriteLi ne( "Final value of counter: {0}", counter );
*}
*static void WriteStream( Func<intcounter )
*{
* * *for( int i = 0; i < 10; ++i )
* * *{
* * * * *Console.Write( "{0}, ", counter() );
* * *}
* * *Console.WriteL ine();
* }
}
From what *I understand, we are creating Func *generic delegate ,
which is takes no parameters and returns the int. We and to that
delegate we pass local value type counter. Then *why would counter
changed upon the retrun from WriteStream? Doesn't WriteSteam operate
on the local *counter argument?
need some lambda education....
Thanks
Well, we are not passing counter into the generic delegate, the
generic delegate is using the local counter (local to the outer
function) which is the same value at the same address when
updated/modified from the Main function or the delegate. *The
"equivalent " method would be:
static int Increment(ref int counter) { counter++; }
By equivalent I mean that counter is being "passed" into the method
(by reference) instead of the method accessing the variable of the
parent code block directly.
I believe this is correct but I'm not 100% so I hope someone else
replies if I'm wrong :)

Mostly right, but the difference is that here we have a closure, the
reference to the function's counter variable is part of the delegate. *With
a reference argument the caller (i.e. WriteStream) would have to pass the
reference, here the caller isn't involved in any way.
HTH,
Mythran
Does anyone know what how Func is defined and implemented?

Oct 22 '08 #4
On Wed, 22 Oct 2008 09:56:33 -0700, puzzlecracker <ir*********@gm ail.com>
wrote:
[...] Then why would counter
changed upon the retrun from WriteStream? Doesn't WriteSteam operate
on the local counter argument?

need some lambda education....
Mythran's reply mostly covers it. The main correction that needs making
is that it's not that Main()'s "counter" local variable is passed by
reference. It's "captured" by the lambda expression. That is, by using
it in the lambda expression (which in this case is basically just a
different way of declaring an anonymous method), the local variable winds
up removed from the stack and being stored on the heap so that it can be
used by the lambda expression even after the Main() method has returned.

This is a significant point. If the variable were simply being passed by
reference, then the lambda expression would be useless after Main() had
returned (ignoring for the moment that Main() is a special method that,
after it returns, terminates the process :) ). By capturing the variable,
the lambda expression remains viable even after the Main() method has
returned.

This has a variety of implications, but one of them is that any time the
lambda expression is executed, it's using the same "counter" variable that
exists in the Main() method. If you modify the variable in the lambda
expression, that's visible in the Main() method as well (and vice a versa).

So, the WriteStream() method invokes the lambda expression ten times, and
each time it's invoked, it increments the local variable in Main(). After
the WriteStream() method returns, that local variable thus has been
incremented ten times.

Pete
Oct 22 '08 #5
On Wed, 22 Oct 2008 11:31:24 -0700, puzzlecracker <ir*********@gm ail.com>
wrote:
Does anyone know what how Func is defined and implemented?
Func<Tis just a delegate type. You can declare it yourself if you like:

delegate T Func<T>();

It's not "implemente d" at all. But you can create an instance of the type
in a variety of ways, all involving providing a method implementation that
matches the signature of the delegate type. In the case of anonymous
methods, the compiler can infer and cast to the correct type as long as
the anonymous method is compatible (i.e you haven't written it in a way
that is mutually exclusive with the desired type).

Pete
Oct 22 '08 #6
This is a significant point. If the variable were simply being passed by
reference, then the lambda expression would be useless after Main() had
returned (ignoring for the moment that Main() is a special method that,
after it returns, terminates the process :) ). By capturing the variable,
the lambda expression remains viable even after the Main() method has
returned.
Is this really possible? I don't see how you can move life-time of
the local counter variable beyond it's enclosed space, which is main
our case. It's conceptually wrong to prolong a variables lifetime.

Actually, on the second thought: perhaps ones example can be a
returning the of lambada expression from a function which used its
local variable to initialize it...
Someone needs to demonstrate it with an example... any volunteers?
Oct 23 '08 #7
On Oct 22, 3:35 pm, "Peter Duniho" <NpOeStPe...@nn owslpianmk.com>
wrote:
On Wed, 22 Oct 2008 11:31:24 -0700, puzzlecracker <ironsel2...@gm ail.com>
wrote:
Does anyone know what how Func is defined and implemented?

Func<Tis just a delegate type. You can declare it yourself if you like:

delegate T Func<T>();

It's not "implemente d" at all. But you can create an instance of the type
in a variety of ways, all involving providing a method implementation that
matches the signature of the delegate type. In the case of anonymous
methods, the compiler can infer and cast to the correct type as long as
the anonymous method is compatible (i.e you haven't written it in a way
that is mutually exclusive with the desired type).

Pete
I tend to think of delegates as classes, hence perceived Func as a
functor...am a paltry and recovering C++ developer
Oct 23 '08 #8
On Wed, 22 Oct 2008 19:03:48 -0700, puzzlecracker <ir*********@gm ail.com>
wrote:
Does anyone know what how Func is defined and implemented?

Func<Tis just a delegate type. You can declare it yourself if you
like:

delegate T Func<T>();

It's not "implemente d" at all. [...]

I tend to think of delegates as classes, hence perceived Func as a
functor...am a paltry and recovering C++ developer
I'm not sure what you mean. A delegate type is a class and a delegate
instance can indeed be thought of as a functor.

There is in fact implementation behind a delegate type, but without a more
specific question it's not clear what you were asking by "defined and
implemented". I thought you were asking about the declared type Func<T>,
as opposed to the Delegate type that provides the implementation. I
suppose saying that Func<Tisn't "implemente d at all" is a bit
misleading; obviously there's an implementation somewhere. It's just that
there's nothing special about Func<Tas opposed to other delegate types.

Pete
Oct 23 '08 #9
On Wed, 22 Oct 2008 19:01:01 -0700, puzzlecracker <ir*********@gm ail.com>
wrote:
>This is a significant point. If the variable were simply being passed
by
reference, then the lambda expression would be useless after Main() had
returned (ignoring for the moment that Main() is a special method that,
after it returns, terminates the process :) ). By capturing the
variable,
the lambda expression remains viable even after the Main() method has
returned.

Is this really possible?
Yes, of course. I wouldn't have written it otherwise.
I don't see how you can move life-time of
the local counter variable beyond it's enclosed space, which is main
our case. It's conceptually wrong to prolong a variables lifetime.
It's definitely conceptually wrong. Except when it's right. :p
Actually, on the second thought: perhaps ones example can be a
returning the of lambada expression from a function which used its
local variable to initialize it...

Someone needs to demonstrate it with an example... any volunteers?
I thought the original example in this thread demonstrated it reasonably.
But taking your suggestion as a more overt version, here's what the code
would look like:

void MethodA()
{
Func<intfunc = MethodB();

Console.WriteLi ne(func());
Console.WriteLi ne(func());
}

Func<intMethodB ()
{
int i = 5;

return () =i++;
}

As you suggested, MethodB() returns the delegate. The variable i is
captured by the lambda expression and so the lifetime is moved out of the
local stack frame and into the heap so that the delegate created with the
lambda expression can always access it, even after MethodB() returns.

You'll find that if you call MethodA(), you get 5 and then 6 written to
standard output.

Pete
Oct 23 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

53
3704
by: Oliver Fromme | last post by:
Hi, I'm trying to write a Python function that parses an expression and builds a function tree from it (recursively). During parsing, lambda functions for the the terms and sub-expressions are constructed on the fly. Now my problem is lazy evaluation. Or at least I think it is. :-)
63
3424
by: Stephen Thorne | last post by:
Hi guys, I'm a little worried about the expected disappearance of lambda in python3000. I've had my brain badly broken by functional programming in the past, and I would hate to see things suddenly become harder than they need to be. An example of what I mean is a quick script I wrote for doing certain actions based on a regexp, which I will simlify in this instance to make the pertanant points more relevent.
26
3507
by: Steven Bethard | last post by:
I thought it might be useful to put the recent lambda threads into perspective a bit. I was wondering what lambda gets used for in "real" code, so I grepped my Python Lib directory. Here are some of the ones I looked, classified by how I would rewrite them (if I could): * Rewritable as def statements (<name> = lambda <args>: <expr> usage) These are lambdas used when a lambda wasn't needed -- an anonymous function was created with...
181
8921
by: Tom Anderson | last post by:
Comrades, During our current discussion of the fate of functional constructs in python, someone brought up Guido's bull on the matter: http://www.artima.com/weblogs/viewpost.jsp?thread=98196 He says he's going to dispose of map, filter, reduce and lambda. He's going to give us product, any and all, though, which is nice of him.
4
2636
by: Xah Lee | last post by:
A Lambda Logo Tour (and why LISP languages using λ as logo should not be looked upon kindly) Xah Lee, 2002-02 Dear lispers, The lambda character λ, always struck a awe in me, as with other mathematical symbols. In my mind, i imagine that those obscure math
23
5338
by: Kaz Kylheku | last post by:
I've been reading the recent cross-posted flamewar, and read Guido's article where he posits that embedding multi-line lambdas in expressions is an unsolvable puzzle. So for the last 15 minutes I applied myself to this problem and come up with this off-the-wall proposal for you people. Perhaps this idea has been proposed before, I don't know. The solutions I have seen all assume that the lambda must be completely inlined within the...
5
2164
by: Octal | last post by:
How does the lambda library actually works. How does it know how to evaluate _1, how does it recognize _1 as a placeholder, how does it then calculate _1+_2, or _1+2 etc. The source files seem a bit complicated so any explanation would be appreciated. Thanks
21
1858
by: globalrev | last post by:
i have a rough understanding of lambda but so far only have found use for it once(in tkinter when passing lambda as an argument i could circumvent some tricky stuff). what is the point of the following function? def addn(n): return lambda x,inc=n: x+inc if i do addn(5) it returns
1
2632
by: Tim H | last post by:
Compiling with g++ 4: This line: if_then_else_return(_1 == 0, 64, _1) When called with a bignum class as an argument yields: /usr/include/boost/lambda/if.hpp: In member function 'RET boost::lambda::lambda_ functor_base<boost::lambda::other_action<boost::lambda::ifthenelsereturn_action>
0
9690
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10505
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10275
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10253
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9085
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7576
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5471
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5606
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3764
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.