Transcript from the "Expressions" Lesson
>> Kyle Simpson: Now statements are comprised of phrases like they are in English, and these phrases are what we call expressions. So going back to this A = B times 2, there are essentially several expressions going on. The first expression is that literal value, a literal value expressed is a literal value expression, okay?
[00:00:24] And then there's an identifier expression, which is the character b. And then we take b times 2. We put those things together, there's an operator in between and two things on either side. And that is called an arithmetic expression. In this case, a multiplication expression. So you can see there was an inner expression, an outer expression, and I could sort of make that more obvious if I used the parentheses as sort of a grouping thing.
[00:00:49] So I'm gonna use parentheses to illustrate this idea of where the expressions are. So there is an expression here, the parentheses wrapping around 2. There is an expression here, the parentheses wrapping around b. There's another set of parentheses that wrap around this expression, which is a mathematic, an arithmetic expression, a multiplication expression.
[00:01:11] And there's one more expression which is called an assignment expression. So all of this stuff, you notice I did not include the semicolon, all of that stuff is both an expression and a statement. It's an expression from here to here and then it's the last thing to go out.
[00:01:29] There's nothing else outside of it. So it's also a statement. Does that make sense? There's an expression, an expression, an expression. And finally, we get to what we would call an expression statement. Where they become one and the same. So this grouping can kind of help you visualize where those things are.
[00:01:44] And that's actually a good practice. So that's the first thing that we'll try to do. I'm going to write a slightly more complex statement. And don't let it intimidate you if you're just starting out programming. But just from the perspective of trying to get your feet wet with understanding the difference between statements and expressions, kinda like when your English teacher had you go up on the board and underline all the verbs and circle all the nouns or whatever.
[00:02:07] I'm gonna have you do that with this. I'm gonna write a slightly more complex statement. I'm literally just gonna make it up on the fly, so it might make no sense at all. But I'm gonna write a statement, and then I want you to take that same statement and put in those parentheses like I just did, identifying all the different places that there are expressions.
[00:02:22] So let me just start out by saying something like,
>> Kyle Simpson: a = b * 2 +, then I'm gonna make a function call, which you haven't seen those before, and then I'm going to pass in an argument c * 3, and there's my statement. So copy that down first.
[00:02:49] You can copy this into your own code editor. You can type it into your console or something like that. It's a nonsense statement because we haven't assigned values to foo, b and c yet, but just from the perspective of finding those expressions. Go in and put your parenthesis or brackets or whatever if you want.
[00:03:05] But take just a moment and try to find all the different places where there are expressions, and then we'll come back and solidify that. All right, so, hopefully you had a chance to try your hand at that. Let's see how you did. So, I'm gonna walk through from the smallest to the sort of outer and identify all those different places that are expressions that make up this statement.
[00:03:25] So, because I already have a set of parentheses in here that means syntax, I'm actually gonna use brackets instead of parentheses, the square brackets. But conceptually, again, we're not doing anything syntactic. What we're doing here is just identifying visually. So, I'm gonna put square brackets around all of our expressions.
[00:03:42] So here We know that we have an expression for the literal value three. I'm not making that an array 3 I'm just identifying that things as a three. We also have another expression value 2 and we have another expression for b and we have another expression for a.
[00:03:59] I think in my previous example I forgot to indicate that the left hand side is also its own expression. So the left hand side is an expression. The c is an expression. The foo of course is an expression. So all of those are sort of our first level expressions.
[00:04:13] Now let's start doing some grouping of stuff. We know that the c times 3 is an expression. It's a multiplication expression, so we should put a bracket around that to identify that that is an expression. We know that this thing, we haven't really talked about what a function call is but we know that its an inseparable unit there is, there is this whole thing like when we put the parenthesis together with the identifier in front of it, that's called a call expression.
[00:04:38] So there's a set of brackets that need to go around the call expression, because that's one coherent unit of stuff that happens. So, we've got our bracket around those. We do a little clean up of my whitespace here so that's an expression. Now we've kind of an interesting question to ask, which is, would the programming language would the computer think of these two things as an expression first or would it think of these two things as an expression?
[00:05:07] Cuz we have two different operators. They're called binary operators. It's a fancy way of saying it's an operator that requires two different sides. So it's a binary operator plus that requires one thing on the left and one thing on the right and puts them together. And then the multiplication operator's the same way.
[00:05:23] So it can't do both of them at the same time. It's gotta do one and then the other. And that leads us into a discussion of what we'd call operator precedence, okay? Now this is not necessarily a critical set of rules that you have to learn, but awareness that there is such a thing is the important part.
[00:05:40] Not actually knowing each individual nuanced thing. There's a set of rules that tells the programming language how to know what to do first. It doesn't always work in left to right fashion. Sometimes, it could work from the right hand side and over it's way backwards. Now, I accidentally, literally just made it up and I accidentally chose this multiplication to happen first.
[00:06:02] Which, happens to matter because multiplication is what is said to be more precedent. Multiplication happens before addition. If there's a question as to which one should happen first, pick multiplication before addition, and that's what we mean by precedence. So, we could say that this thing is an expression because it is the thing the computer would do first, before considering what's happening on the plus.
[00:06:30] So now, if you're not getting lost in this sea of brackets, you can see that I have one expression here, and I have one expression here. Those two are the binary operands, other fancy word, to say the values that go into the plus operator. So now we have one more wrapping of brackets.
[00:06:47] This is getting out of hand of course but we now have a wrapping around that entire thing, now this is one big complicated evaluation to take b times two and add it to the result of calling foo with c times 3 pass down. So we'll put all of that together to be a, an expression value and that expression value of course then gets assigned to the left hand side to the a variable that's over there and finally one last set of crazy brackets.
[00:07:14] Around the entire assignment expression. And now we've identified all those different little pieces that nest themselves together to become what we call a statement. Of course, it looks a lot easier to read when we don't have all those brackets in, right?. So if I go back to the original statement without all those crazy brackets in.
>> Kyle Simpson: We can come back to that same understanding. We can say hey, I know I need to do c times 3 cuz that's gotta get passed in. so find out what c is currently, whatever value it is, and multiply it by 3 and then pass that into the function too.
[00:07:50] And again we'll cover call expressions, what functions are, we'll cover that in a little bit And then whatever that value is, add that to the value of b times 2. So compute b times 2. Now I have two different things. Add those together, and whatever that final result is, assign it into a.
[00:08:07] By the way, the reason why operator precedence matters is because mathematically. This could mean two different things. If I were to simplify it and say 2 times 3 plus 4, mathematically it matters which one you do first. 2 times 3 plus 4 is 10. 2 times 3 plus 4 is 14, so mathematically, it matters and that's why this ambiguity has to be resolved by the programming language.
[00:08:36] The way we resolve that in programming languages is to understand a basic concept of operator precedence. Now, what if you were in the scenario where you wanted to sort of override that precedence? Yeah?
>> Speaker 2: You'd wanna add parentheses.
>> Kyle Simpson: You'd wanna add parentheses, exactly.
>> Speaker 2: In fact, you'd wanna add them in your code just so that you could Accentuate what you're trying to do.
>> Kyle Simpson: That's exactly the point that I was going to, great segueway. So, if I wanted to suggest that this program should do 2 + foo and then multiply that by b, then I could forcibly do that by putting in the parentheses. These here are not made up visual things.
[00:09:17] These are actually things that matter to the program. The parentheses here says, do the stuff inside of the parentheses first before working your way out. So now, I have forcibly changed that rule, if you will, of precedence by forcibly saying that the plus should happen before the multiplication.
[00:09:33] Exactly the same as in the 2 times 3 plus 4. I could have done that by saying, no, what I really want you to do is come up with 7 first and then multiply it by 2. So those parentheses in this case, they matter. They matter to the end result.
[00:09:48] But what if I did want the b times 2 and I didn't want the 2 plus? I want it to happen the same way as operator precedence to the point that was just brought up. I can still put in a set of parentheses here. They're not necessary to the functioning of the program.
[00:10:06] They don't change the outcome of the program. It's still gonna do exactly the same thing as if I left them out. But here is that point that we were talking about earlier where it's this balance, this goal to try to make sure that your code is understandable. If we put something into a program that the computer doesn't care about, then the only other reason for it could be that a developer cares about it.
[00:10:29] So developer here not needing to know the rules of operator precedence doesn't have to understand whether times or plus happens first. If all they understand is the fact that parenthesis wrap together then they can process through this program and say clearly I should do this thing first and this thing, and then add them together.
[00:10:51] So for readability's sake, you would probably tend to wanna put the parenthesis in. Basically the takeaway here is that, even if you know intricately all the rules of operator precedence, you don't always wanna write a program that relies on it. Sometimes it's helpful but sometimes it's more appropriate to add additional things to your program.
[00:11:14] Like in this case, an optional set of parentheses, to make the code make more sense. Question.
>> Speaker 2: The question was, without the parentheses, will it get the value of the function first or the variable b?
>> Kyle Simpson: That's a great question. So, if I didn't put this parentheses here, what's gonna actually happen?
[00:11:31] Well the rules of operator precedents say which operator, if two different operators show up in a line like this without any other kind of grouping, it's gonna say which thing happens first? So from a left to right perspective, the b times two is gonna happen first before calling the foo function.
[00:11:50] If the foo function had been in the left position, then the foo function would have been called, and then the b times 2 would have happened. So the programming language does typically and generally move in a left to right fashion. Meaning that something on the left is typically gonna happen before something on the right.
[00:12:07] Even if we looked only at this expression right here, the b * 2 expression, we could say that the programming language will evaluate the thing on the left first before evaluating the thing on the right. So typically it's gonna work in left to right fashion. The only time when that is broken is if there's something like operator precedence or there's another related concept called associativity which we don't need to get into.
[00:12:28] But if precedence or associativity overrides left to right behavior. And in those cases, it could force something to happen. So if I were to simply reverse these two, and say b plus 2 times foo. Now we know that operator precedence is gonna say, don't, I mean, we are gonna evaluate the b part first, and evaluate the two part first, but here we're going to call this foo function before we add it to b.
[00:13:01] Because we gotta compute that whole expression first. So operator precedence can work to sort of tweak the way this normal left to right processing happens. But overall you still see that even inside of each expression it still works in a left to right fashion. So that's a great question.
[00:13:19] Yeah I like what's said in the chat room, be kind to your future, more elderly self. That's definitely true.
>> Speaker 2: I don't want to get way ahead of myself but is there any difference between specifying as 2 and 2.0, does it matter?