Lambda Functions?

Hi, I'm very very new to C++, and sometimes i like to go ahead of myself. I came apon an article (http://msdn.microsoft.com/en-us/library/dd293608(VS.100).aspx) that talks about Lambda functions in C++. It describes a Lambda function as an anonymous function; a function, with a function body, but no name.....Why would a person want a function with no name? and how would use such a function?
Read the Wikipedia article on lambda calculus. If I got it right, lambdas are used to pass expressions as parameters, so to speak.
I have a book on lambdas, yea, basicaly a lambda is a function, that passes another function into it arguments. Lambdas dont have a names, and also data (including numbers) are also lambda functions. Lambdas (i guess in its purest sence) don't have more then one paremeter, but you can put another lambda function ito its expression to sort of give it more them one paremeter. I also think lamdba's in its purest sence return one argument


but ignoring all that, is it not possible to pass functions as arguments to otehr function in c++ without Lambdas?...and again why you want the function to be anonymous?
It's there if you want to say, create a function to be passed an argument, but you would only really be using that function there, so you don't want to waste time making a normal function.
O, so basicaly its just a short cut?
Lambda expressions only exist for convenience.

Typically, you need to write predicates (boolean functions) to handle STL algorithms. For example, to count a vector of int to see how many items are less than ten, you would normally have to write a separate piece of code to do it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

bool less_than_10( const int& value )
  {
  return value < 10;
  }

int main()
  {
  vector <int> v;
  for (int n = 0; n < 20; n++) v.push_back( n );

  cout << "There are "
       << count_if( v.begin(), v.end(), less_than_10 )
       << " ints less than 10\n";
  return 0;
  }

That little function is somewhat of an eyesore, particularly if it is only used in one unique case. The STL recognizes that certain expressions (like x < 10) are convenient cases for, in essence, a form of lambda expression:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;

int main()
  {
  vector <int> v;
  for (int n = 0; n < 20; n++) v.push_back( n );

  cout << "There are "
       << count_if( v.begin(), v.end(), bind2nd( less <int> (), 10 ) )
       << " ints less than 10\n";
  return 0;
  }

Such 'lambdas' are really just another version of the first problem (implemented as functors -- function-like classes), but they are useful anyway.

However, what if you really wanted to write an actual little function to be used? A true lambda allows you that power. Again, as helios indicated, a quick perusal of the Wikipedia Lambda Calculus and Programming Languages page might prove interesting:
http://en.wikipedia.org/wiki/Lambda_calculus#Lambda_calculus_and_programming_languages

You can also look into some functional languages to help out. For example, in Scheme (see http://plt-scheme.org/ ) you can create a function on the fly:
1
2
3
4
5
6
7
8
9
10
11
(display "There are ")
(display
  (length  ; returns the number of items in a list -- same as STL count()
    (filter  ; removes items that don't satisfy the predicate
      (lambda x (x < 10))  ; this is the predicate, written as a lambda
      '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)  ; the list, of course
      )
    )
  )
(display " ints less than 10" )
(newline)

That there on line 5 is a function created on the fly. It has no name (making it anonymous) and it is right there with the code that uses it. Alternately, you would have had to give the function a name and used the function name, just as we did above in the first C++ example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(define less_than_10
  (lambda x
    (x < 10)
    )
  )
(display
  (length
    (filter
      less_than_10  ; this is the name of the existing predicate function to use
      '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
      )
    )
  )
(display " ints less than 10" )
(newline) 

C++ really is an iterative language, not functional (like Scheme), making lambdas like these something of a bunch of magic tricks with expressions. It really isn't possible to get true lambdas without embedding some sort of C/C++ interpreter in your program.

However, I hope this helps to understand the purpose and convenience of 'lambdas'.
Last edited on
Duoas wrote:
C++ really is an iterative language, not functional (like Scheme), making lambdas like these something of a bunch of magic tricks with expressions. It really isn't possible to get true lambdas without embedding some sort of C/C++ interpreter in your program.


Douas, you don't think that the lambda support coming in C++0x gives C++ true lambdas? These really do become unnamed functions and are designed exactly for the use you describe in your count_if() example.

 
count_if( v.begin(), v.end(), [](auto x) {return x < 10;} );


http://herbsutter.spaces.live.com/Blog/cns!2D4327CC297151BB!785.entry
According to that article, Lambdas also have the benfit of being able to wright a function on the spot, instead of right in the beginning of code.

So C++0x lambdas? I'm assuming that C++0x is going to be a new release of the language with new features? but how will the lambdas in the C++0x be diffrent then the lamba expressions that I read about in the Microsoft article?
Lambdas described on that article are C++0x lambdas, if you read carefully you will notice that it says Visual Studio 2010 - Visual C++, the current Visual Studio is the 2008 one.
Currently are available lambdas from the Boost libraries: http://www.boost.org/doc/libs/1_39_0/doc/html/lambda/using_library.html
Lambda expressions support the notion of functional programming. C++ is, as are many other high level languages, an imperative language. Imperative languages are arguably easier to use, but functional languages support the notion of being able to prove an algorithm's correctness.

However, as Duoas said, most people will use lambda expressions in C++ as a convenience, to a) avoid having to write an entire function object, and b) for maintainability/understandability. The idea is that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// In Foo.h:
struct Foo {
    int x;
    char c;
};

struct FooCompareByChar {
    explicit FooCompareByChar( char c ) : ch( c ) {}
    bool operator()( const Foo& f ) const { return f.c == ch; }
    char ch;
};


// And in some completely unrelated file:
vector<Foo> foos;
// ... fill in entries ...
vector<Foo>::const_iterator item = std::find_if( foos.begin(), foos.end(), FooCompareByChar( 'X' ) );


What the find_if does is very dependent upon what FooCompareByChar does. The problem is that
you have to look somewhere else for FooCompareByChar to know what the line of code does.

Contrast that to:

1
2
3
4
vector<Foo> foos;
// ... fill in entries ...
vector<Foo>::const_iterator item = std::find_if( foos.begin(), foos.end(),
    &boost::lambda::_1->*&Foo::c == 'X' );


As long as you can read lambda expressions, you now know exactly what that line of code does
without having to look somewhere else.

As a side benefit, it is also less typing and fewer symbols in the namespace.
Topic archived. No new replies allowed.