 In this video we're going to look into what expressions are and how they contrast themselves to statements. And also we will look into a topic which is called side-effects and what side-effects in memory are. And yeah, this is a topic that is a little bit theoretical and in the beginning may be a little bit hard to understand, but I try to give you a good example. So let's create a new file and call it expressions versus statements. Okay, so let's start simple. Okay, what are permanent side-effects in memory? Question mark. So let's go ahead and write a very simple expression, 1 plus 2. And let's execute it and then we get back 3. And now let's see in a memory diagram what is going on here. So in memory what the expression does is it first goes ahead and it creates an object, an integer object with the number 1. And it also creates an integer object with the number 2. And then Python will go ahead and will ask the left operand, hey, do you know how you can handle the right operand for addition? And then they both say or the left one says, yes, I know. And then they add themselves together and this gives us a new object of type integer with the number 3. And now, as I did in a couple of previous videos, a reference to this object will be given back to us. So let's maybe indicate it like this with a red dotted line. And now it depends on us what we do with it. Now, in the example here, where I simply say 1 plus 2 and I get back a 3 here. That is why I use the red dots because here in tuple lab, this is always shown in red here. So what we do here is we don't do anything with the result. So in other words, I am calculating something on the fly, so to say. I get back a result and I don't do anything with the result. So in the memory diagram, what that means is the 1 is now right away garbage collected. The 2 is right away garbage collected. And the 3, the result, because we are not doing anything with the reference we're getting back, is also going to be garbage collected. And that means after that, so after the line here, after the cell here, the code cell has been executed, there are no permanent side effects. By looking into the memory, there is no way to see if the object is actually there because on the left-hand side, we don't have a name referencing any of these objects. So we couldn't even tell if the object ever existed. And now if I go ahead and I do the following, I simply go ahead and I re-execute the same code cell a second time. What that will do is it will simply create a new one which is an integer. It will create a new int object with the value 2. Those two do the addition. They will create a third object and integer. And then a reference to the third one is of course also going to be given back to me. So let's use the red dots here. And then after that, because we are not doing anything with the reference, what's going to happen is all of the objects are garbage collected again. And so what we say is we don't have a permanent side effect in memory. That is important. So let me emphasize this. There are things going on in memory. So there are objects being created and objects work with each other and so on. However, they don't survive. At the end of the code cell, it is as if we never even executed a code cell. We couldn't tell because the objects are not reachable. They are gone. And the garbage collector will sooner or later get rid of the objects. So that is why there is no permanent side effect. Okay. So let's do a second example. Let's go ahead and add one plus two and assign the result to a variable. Let's call it a. Let's execute this code cell. And now what is going to happen is the right hand side is going to be evaluated first. So what this is going to do, it will first create the one object on the fly again. It will create the two object on the fly again. Those two work together for doing the addition and they will create another one with the number three. Now we will get back the reference to that. And now the question is what do we do with the reference? And now the situation is different because now we are assigning the reference we get back to a variable called a. So that means we are creating a new variable a and we will make a reference to three object. And then after some time the garbage collector will remove the one and the two and the three will survive. Okay. And this is an example of a so-called permanent side effect. Okay. So we did something. We executed a cell and after we executed the cell, the memory is different, at least the part that we can see. And what do I mean by the part that we can see? Well, anything that has a name can be reached. So anything that has a name can be seen. So to say anything that does not have a name, we don't even know if it ever existed because there's no way to go to this location. There's no reference. And that is a big idea here. So this is what we call an expression. So what do I mean by that? Anything, any expression, any line of code in Python that is executed by the Python interpreter and that evaluates into some object. And then we get back a reference to this object. That is what we call an expression. Okay. So let's say expressions. That's the definition. Let's call it commands where Python creates new objects and returns a reference to one of them as the result. Okay. That is in a way what an expression is. And we say, what we say is an expression evaluates into an object. That is usually what you hear programmers say. Now, so in other words, there is no permanent side effect that is here. Okay. So let's also maybe put that here. Expressions have no permanent side effect. In other words, we can run the cell as often as we wish and nothing ever changes. Okay. In contrast, there are lines that are lines of code that when executed, they have a permanent effect. So after they have been executed, something is different in memory. If we continue with the program, then we are dependent maybe on the state change here. And these are no expressions. Okay. A line of code that has a permanent side effect is not an expression. However, note that on the right hand side, we still have an expression. Okay. So the right hand side is an expression that evaluates into an object with the number three. And then a reference to this object is going to be assigned to A. And now interestingly, in JupyterLab, but also in some other interactive environments, whenever under a code cell, we get back a result. So here we have in blue the input to the cell, so to say. And in red, we have the output of the cell. That is when we see that this expression here is an expression or this line of code is an expression because that is the signal that JupyterLab gives us, so to say, a subtle signal here. In contrast, down here, we don't see any output. Okay. So in other words, this is a line of code that as a whole is not an expression. It does not give us back a reference to some object. So in other words, if I went ahead and let's try to do something crazy, let's go ahead and copy paste this line. So let's assign to A, one plus two. And let's also put parentheses around there to indicate the order of residence, so to say. So if we go ahead and we want to assign the result of this expression here, let's say to another variable, let's call it X, then this is going to give us a syntax error. And the reason why is because an assignment statement requires that on the right-hand side, we only have one expression. Okay. So we must not have a permanent side effect on the right-hand side for the assignment statement to work. That is an important idea. So now comes another definition. And that goes as follows. So oftentimes, when you go on some sources on the internet like Stack Overflow and other good sources where programmers talk about code, you will often hear that the opposite of an expression is a statement. And that kind of makes sense because if I say that an expression by definition is something that does not change the state, so to say, of a program, then a statement is basically the opposite. Okay. So in other words, there are people who do the following. They go ahead and they say that we have basically all possible commands in Python. So these are all possible lines of code and they can be separated into expressions and into statements. Okay. However, if you want to go by the book, so if you went into the Python documentation in the language reference and you read about that, then the picture looks as follows. We have all the available commands that Python understands and a subset of that is expressions. Okay. And then the outer set, so to say, these are all the commands that are not expressions. And for the term command, what we use is the word statement. Okay. So a statement in the Python world, if you go by the book, so to say, is any line of code that can be executed, anything that the Python interpreter understands. And some of those statements are expressions, but there are also statements that are not expressions. Okay. So don't be confused by these pictures. And oftentimes in the real world, you will see that or you will hear programmers talk as if expression is the opposite of a statement. So these are two terms and they are perfectly dividing all possible commands in a language. And that is one way of using these terms, expression and statement. And then there's the other way where we say every command, every single line that a Python interpreter understands is what we call a statement. And some statements are expressions, but not all statements are expressions. So expressions are a perfect subset of statements. This is the theoretically correct way of viewing the world. But again, and this is also the one that I will be using in this lecture series. However, don't be confused if you hear people use the terms in this way. Okay. This is often, this is something when I started the program I was confused about because sometimes you see this way, sometimes this way. Just know these are two possible conventions, so to say. And this is the official way. And this is one that many practitioners use. Okay. Don't be confused about that. Okay. So let's also go ahead and provide a more formal definition or expressions. So let's say a form less we can be in a practical programming course. So formal definition of an expression. And let's say an expression is any tactically correct combination of, yeah, let's say of variables could also use the word names here. Literals. We saw the literal notation to create a list of bracket notation and there are also other literal notations and operators. Okay. So that is the more formal definition. So let's see a couple of examples of what are expressions. So first of all, if I simply go ahead and write a literal something that Python literally understands, let's say the number one, this creates a new object with the number one as an integer. This is an expression because I'm using a single literal. If I write a list object, so with the bracket notation, the literal notation for list objects, and I put in there the numbers one, two, three, this is of course also one expression. Okay. If I go ahead and assign a variable A to the result of some calculation, this is not an expression as we saw. This is why we don't see any output below the cell. However, if I go ahead and I read the variable, reading a variable is an expression. This is what we mean by a syntactically correct combination of variables, literals and operators. And then of course, we could make it a bit more complicated. We could go ahead and say A plus one, maybe the entire expression is also an expression. Why? Because any combination of a variable, a literal and an operator is also an expression. So the entire cell here is now one big expression. And then of course, we could still go ahead and take it one level further. And we could, for example, put the A plus one into parentheses and multiply the result by two. And now we also have an expression. Okay. So this is like, so we have like a sub expression on the left hand side and the sub expression on the left hand side and the literal on the right hand side. They are connected together with the operator and that the overall thing also constitutes another expression. So all of that could be written on the right hand side of an assignment statement. Okay. Another couple of examples. So let's go ahead and I reference a name that Python already knows like sum, the sum built in function we have seen before. That is also an expression. It evaluates to the function. So by writing sum, this is going to evaluate into a reference that refers the object that models the sum function. Another expression. If I go ahead and I call the sum function, let's say I want to sum up the numbers one, two, three in the list. The entire cell here is also an expression. Okay. So that means all of these cells here has no permanent side effect. I can run them as often as I wish without changing anything permanently in the diagram in the memory diagram. And that is important. The emphasis is on permanent. There are all these expressions here, or most of them all except the A here. All of these expressions, they create objects on the fly that are returned as the return value of the expression. And that is what we mean by evaluation. However, we are not storing away the reference to these objects. So in other words, the garbage collector will immediately get rid of them. Therefore, there is no permanent side effect. Okay. That's a big idea, permanent side effect. Okay. And so, yeah, let's see a couple of more examples. So examples or statements that are not expressions. And one of them we have seen above. If I go ahead and assign some number to a variable, that is a statement that is not an expression. But similarly, if I go ahead and I delete the name from the list of all names with the del statement, then this is also not an expression. And we see that because both cells have no output below them. Okay. And that is an important idea. Okay. So know the terms, expressions and statements and know that there are two ways of how people use them. And I'm using them as in the way where statement is the general term and some statements are expressions, but not all statements are expressions. However, the converse is true. All expressions are always statements. Okay. So I'm not using the terms as opposites. Okay. So that is it for this video.