Download CSE_341_Unit_01_Func..

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

C Sharp syntax wikipedia , lookup

Functional programming wikipedia , lookup

Subroutine wikipedia , lookup

Go (programming language) wikipedia , lookup

Dirac delta function wikipedia , lookup

Corecursion wikipedia , lookup

APL syntax and symbols wikipedia , lookup

Recursion (computer science) wikipedia , lookup

C syntax wikipedia , lookup

Function object wikipedia , lookup

C++ wikipedia , lookup

Standard ML wikipedia , lookup

Transcript
CSE_341_Unit_01_Functions_Informally
[00:00:00.00]
[00:00:05.38] OK, in this segment we're going to start studying functions. These are a new kind
of binding. So we're going to change our definition of program to not just be a sequence of
variable bindings, but to allow both variables and functions.
[00:00:18.83] If you haven't heard of the term function, it's a lot like a method in an object
oriented language. This is something that's going to take arguments, compute some result, and
return that result. That's all it does. So it's in many ways, simpler than a method, and we're
always going to call these things functions.
[00:00:35.09] So why don't I just flip over to [? EMax ?] here and show you a first example.
How about I write a little function for exponentiation or raising something to the power of
something else? So here is most of what I need to write. OK, so I have the keyword fun, the
name of the function I'm defining, pow, the arguments it takes. Here, x and y, separated by
commas. I've written their types with a colon and then the type name. Then an equals and then I
have my function body.
[00:01:07.54] OK, so that body can just be any expression I want and what happens when you
call the function, it is we are going to evaluate that expression, and then the result will be the
result of the function. So for exponentiation, what I want is something like a conditional
expression that says if y is 0, than 1.
[00:01:26.89] Otherwise, how about x times this other expression, which is to call the pow
function with x and y minus 1. And that will work as long as y is greater than or equal to zero.
And I'll make no attempt to be correct for negative y, since this is just an example.
[00:01:46.67] So this is a program. This can be included in my sequence of bindings. I could
have a val binding before. Maybe afterwards I could have another function binding. How about
something that takes its argument and cubes it? So I could define this as x times x times x, or I
could use any previous bindings, since it'll be in my environment, and I could instead implement
this as pow(x,3).
[00:02:11.08] So the body of this cube function is itself a function call that calls pow with x,
which is the argument to cube, and the constant 3. So I could use these functions. I could say val
sixtyfour. That should just equal cube of 4. You don't actually need these parentheses, but it
looks a little more like other languages if I put them in, at least for now. Or I could have
something that uses more nested expressions.
[00:02:40.75] You can call a function with an expression, in which case I'll evaluate this 2 plus 2
to 4, and then pass 4 as the second argument to pow. Here, I could add another 16, and another 8,
and another 2. You could even have nested calls if you wanted. So you could say pow(2,2) in
there, and so on.
[00:03:04.42] When you want to test something out, just like always, go over here to the REPL.
We can say use "functions.sml". See all of our bindings there? You'll notice that pow and cube
print differently than variable bindings. In terms of the value, they just say I'm a function. We
don't print out the body of the function or anything. The REPL will always just say, here is a
function, and here is it's type.
[00:03:30.25] So you see with pow that it has type int star int arrow int. So the way function
types are written in ML is we write down the types of the arguments separated by a star. So it
takes two int arguments, int star int, and then a hyphen, and angle bracket, and arrow, and then
the result type, which is an int.
[00:03:54.28] Notice we didn't have to write down that result type. ML figured it out by looking
at the function body, that conditional that we had up here, and realizing that if x and y have type
int, the conditional have type int. And so, the function when called with two ints, will return an
int. Similarly, cube is a function that takes one int and returns one int. 64 and 42 are as usual and
we can try things out at the REPL now. So we could cube 7, and we would get 343, and so on.
[00:04:27.65] So that's the informal idea of functions. Let me make a few points here back with
the slides, since this is a new thing we're learning. The first thing is that the body of the pow
function, itself, can use pow. So that's how we implement recursive algorithms, as we did here.
So all this is showing is that inside a function body, you can call the function itself.
[00:04:51.46] There's a few gotchas when you start writing things out. We have all the sources of
potential error messages, especially if you leave that colon off between the name of the variable
and the type, or if like in other languages, you try to write int x instead of x colon int. All of
these things are syntax errors and you're going to get error messages as a result.
[00:05:11.02] I would also point out that when we wrote out those function types in the REPL,
we saw that pow had type int star int arrow int. That star is different than the star for
multiplication. So it's just a reuse of the same character. In expressions, star means multiply. In
types, at least as we've seen so far, it's just separating the types of multiple arguments.
[00:05:36.32] And finally, just like variable bindings, function bindings can use earlier bindings
in the file, but they can't use later bindings in the file, and that's again, just ML's rule. So any
helper functions you want, if you want to define one function like cube, in terms of another
function like pow, then you have to put cube second. Now, this does raise an interesting
question. What if you had two or three functions that all wanted to call each other? There would
be no good order to put them in and I'll show you in some future segments some special support
in ML for that case of mutual recursion.
[00:06:10.51] If you're not yet comfortable with recursion, hopefully you've at least seen it
before. You will be soon. On the first homework assignment, pretty much every function you
write will be recursive, and we're going to see a bunch more examples. So don't panic if the
algorithm for pow looked a little too magical, but there's really absolutely nothing magical to it.
[00:06:30.25] So let me flip back here and just show you this pow function. The reason why we
can define pow in terms of pow, there's nothing circular here. What we did is we defined raising
something to the yth power in terms of raising something to the y minus 1th power, and that is a
perfectly reasonable definition. A recursive call is solving a simpler problem, and if that simpler
problem is that y is zero, then we don't use recursion at all, and we just returned the answer one.
So we'll get very comfortable with this idea as we move forward.
[00:07:02.89] And in ML we're always going to use recursion for these sorts of things. If you're
used to writing things like pow with while loops or for loops, we're not going to use them. They
often obscure what are simpler, more elegant algorithms, and recursion is more powerful. So
often, while loops and for loops are more convenient, or the idiom in many programming
languages.
[00:07:25.09] In many programming languages, they're more efficient, but anything you can do
with a loop, I promise you, you can do with recursion. And we're going to focus on that approach
in ML. And really most of the programming we do in the class.