 Welcome back. In the last segment, we discussed functions which operate on functions. We are going to continue on that theme and now we are going to describe something called lambda expressions which make it easier to pass functions to other functions. Lambda expressions originated from Lisp and in Lisp they were present maybe in the 50s, 60s something like that, 1950s, 1960s and in C++ they have been present at least for 15-20 years now. So a lambda expression is an expression which represents a function and the function does not really have a name. So it is just sitting there but it does not have a name. Here is an example. So square bracket into parenthesis double x into braces written x times x minus 2 is an expression and it represents a function and in this case it represents the function f of x equals x squared minus 2. The general form of this is the square brackets first and the square brackets will tell you what they exactly do a little bit later but first there is the parameter list. So double x is the parameter over here. If the function that you want to represent has more parameters, you just put it here just like a regular old parameter list and then this is like a regular old body. In this case the function is really simple so you just have a single return statement but in general you can have a whole complete function over here. However complex you want to make it. So that is what a lambda expression is. Now what can you do with it? Well the simplest thing that you would expect is can you apply it? Can you use it to operate upon some arguments? So yes you can. So here I have shown this lambda expression which is the function x squared minus 2 and that is operating on 3.5. So it is computing f of x f of 3.5 where f of x is x squared minus 2. So this evaluates so x times x is 12.25 minus 2 so this evaluates to 10.25 as you might want and you can certainly write z equals square bracket double x all of this 3.5 and then z would be set to 10.25. The more interesting thing for us is that you can pass this as a parameter to functions such as or pass it as argument I guess I should say to functions such as bisection. So in the main program that you saw earlier we had, we were printing out the value square root of 2. So there we wanted to pass a function x squared minus 2. So there we wrote a function and passed its name but here we can just send the expression for the function x squared minus 2 instead. So this is exactly, this is all that is needed. I can write this in the body of my main program and this will call bisection with this function and this will work. So this will indeed produce square root of 2, it will, the bisection will return square root of 2. So this is as good as writing, as defining a full function outside your main program and giving it some name say whatever f as we called it and sending f over here. But you do not really need to do that. You can just, you can just make this something local. So here as I read my code I can see that oh I am just, I am just trying to find the square root of 2. I do not need to go to some other place. So basically this is going to make your program less cluttered and it will improve local readability. Now I am going to, some comments about this general form. So the parameter list is comma separated as usual as I mentioned earlier, body is like the body of any function. Now the return type is not stated explicitly. So in a usual function the return type will be stated and in this case the C++ compiler looks at the return statement and says oh the return statement is inferring this type of value and therefore the return type of this function must be this. Sometimes it is not possible to infer the type and in that case you can specify it explicitly. So for example here is that is the form, another form in which I am saying that look this function is supposed to return something of return type this. So as an example I might write all of this and inside I might have a return statement returning 1. But now C++ compiler cannot figure out what 1 is, 1 can have several types. One could be short, one could be long, one could be int and therefore it is desirable to specify the type and that is how you specify over here. Lambda general expressions can be more general. So here is a problem that needs that higher generality. So the problem says write a program that reads a number from the keyboard and prints its square root using the bisection method. Now of course you could again go back and ask look do we need to modify the bisection method. But now we said that look that does not seem very elegant and another thing is that you may not have the code, you may have the object module in which case there is no question of modifying it. Now this can also be written with this more general lambda expression. So here is the code fragment. So suppose we want the square root of z. So what are we going to do? We are going to first read z. So we are going to declare a variable to store z and we are going to read a value into it. And after this we are going to have a call to bisection almost like what we had earlier. So double x, the function is the same except that here now we want to calculate the root of x squared minus z and not x squared minus 2. So this root is being calculated, the root of x squared minus z is calculated and the z is taken or captured from outside of this body. So this is the body. So normally you expect everything every variable to be used that is used over here to be defined inside that body just like a regular function. But you can go do a little bit more. So I can put a variable over here which appears over here as well or I can put an expression as I have done which uses variables which appear outside which have been defined outside. So now we are telling we have to tell the C++ compiler that I am doing this because the C++ compiler is always worried that look are you doing this deliberately or are you making a mistake. And therefore just to indicate that this variable is being captured from outside inside the square brackets we have to put in z. So this says to the compiler that look this I am going to use the value of the variable z which has been defined outside and now I can use that variable inside over here. So the z inside those square brackets says that the lambda expression will capture that is the technical term used the value of z from the function in which the lambda expression is written. So this lambda expression is written in this this code fragment which is a part of the main function and z is a variable defined in the main function and I can use the value of it. The value of it will be substituted over here and then this function will be constructed and then passed to bisection. And without this the body of the lambda expression cannot refer to variables which are defined outside and furthermore I should say that if I want to capture more variables I can just put them here separated by commas. So I am going to give a demo of this this program and let us take a look at it. So this is the program so as you will see this bisection function is the same as before nothing changed and over here I am indicating this variable capture and I am finding the root of x squared minus z and I am reading the value over here. So let us compile it let us run it so now I want to give it a value so let us try 2 so it is printing the value that we have seen before the correct value or merely correct value of course this is an approximation to certain number of decimals of bits. So let us try one more so maybe let us give it a value which is a perfect square so it is printing out 4.9997 so again as I said this is going to print an approximate value and indeed this is a close enough value. Here is an exercise for you so you are given a piece of code and you are supposed to tell what that function does. So this should be reasonably you should be able to figure out reasonably quickly from knowing what lambda expressions are and in any case you can execute it to see what it does. Here is another somewhat elaborate exercise now in this case I have given a code in which a function is being passed. The function that is being passed is not going to return anything nor is it going to take any arguments and it is called fd and that function fd is going to be called. So this is going to be something which draws a square presumably and it is going to repeat 4 and here you would have seen the line forward 100 or something like that and then it turns. Now instead of doing forward 100 you can supply some different command through fd. So for example you might say that look instead of just going straight in drawing the square maybe I want the turtle to do funny things like this. So what you can do now is I can write a single function square and I can pass to it a function which does this and that function will be used to draw the 4 sides. So essentially by supplying the appropriate function you can do other things. So maybe the other thing you could do is supply a function which draws a dotted line or you can just supply fd forward 100 and it will draw this square. So whatever it is but you can have the same square function draw squares but which are sort of decorated which are decorated in a different manner. Now it turns out that by place yeah that you can do more variable more complex variable capture. So what we have seen so far is that if you place names of variables inside this you enable the values of the variables to be used inside the body of the lambda expression. But you can also cause the lambda expression to not take the current value but take the value of the variable at the time the lambda expression is actually evaluated. So during the time when the variable when the expression is evaluated and then when the value changes you can figure out what the value is and so you can do that and it is discussed in the book but it will not be considered in this course because this is just a little bit too elaborate and we are not going to really make interesting use of it. So what have we discussed? So we have said that lambda expressions evaluate to nameless functions and we can evaluate these by supplying arguments or pass them to functions. We also said that lambda expressions can also capture the values of variables defined in the function in which the lambda expression appears. So this concludes this segment in the next segment we will discuss functions a feature of functions where you can write functions so that you specify default values to some parameters. So we will take a break here.