53
six compound procedures and higher-order procedures

Six compound procedures and higher-order procedures

  • View
    220

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Six compound procedures and higher-order procedures

six

compound proceduresand higher-order procedures

Page 2: Six compound procedures and higher-order procedures

A box figure

► [group [box 400 400]

[translate [point 100 100]

[box 70 70]]

[translate [point 100 −100]

[box 70 70]]

[translate [point −100 −100]

[box 70 70]]

[translate [point −100 100]

[box 70 70]]]

Page 3: Six compound procedures and higher-order procedures

Simplifying with names

► [define frame [box 400 400]]

► [define little [box 70 70]]

► [group frame

[translate [point 100 100]

little]

[translate [point 100 −100]

little]

[translate [point −100 −100]

little]

[translate [point −100 100]

little]]

Page 4: Six compound procedures and higher-order procedures

What’s wrong with this?

Defining little and frame saves us a little bit of work, but …

What we really want to do is to name the whole pattern of making shifted boxes…

We need abstraction

Page 5: Six compound procedures and higher-order procedures

What we want to be able to say

► [define frame [box 400 400]]

► [group frame [shifted 100 100] [shifted 100 −100] [shifted −100 −100] [shifted −100 100]]

Page 6: Six compound procedures and higher-order procedures

What kind of a thing is shifted?

Well, it takes inputs It returns an output It must be a procedure…

In fact, we even know what it should do It should make a point from its two arguments Make a box Translate the box by the point And return it

Page 7: Six compound procedures and higher-order procedures

Compound procedures

[arg1 arg2 … argn → exp]

Procedures are just another data object You can construct new procedures from old using the → symbol When called, the procedure

Sets the local names arg1 arg2 … argn to the arguments passed to the procedure

Computes the value of exp using the values of the arguments Returns the value of exp

Note: you type the → symbol by first typing – and then >

Page 8: Six compound procedures and higher-order procedures

Defining shifted

► [define shifted [x y → [translate [point x y] little]]]

► [group frame [shifted 100 100] [shifted 100 −100] [shifted −100 −100] [shifted −100 100]]

Page 9: Six compound procedures and higher-order procedures

A boring example

Square is a compound procedure built from ×

Polynomial is a compound procedure built from ×, +, and square

Notice they both use the name n for their argument But it’s okay because

they’re local names

► [define square [n → [× n n]]]► [square 2]4► [square 58.7]3445.69► [define polynomial [n → [+ [square n] [× n 2] 4]]]► [polynomial 32]1092►

Page 10: Six compound procedures and higher-order procedures

A more interesting procedure

We haven’t taught you enough at this point to understand how iterated-group works

You’ll understand in a few weeks For the moment, just copy it from

this slide and use it

But the thing we do want you to understand is that

You give it a procedure that makes pictures

And a number of times to call it And it gives you a group of all the

results of calling the procedure with the arguments 0, 1, 2, etc.

► [define iterated-group [proc count → [apply group [up-to count proc]]]]

Page 11: Six compound procedures and higher-order procedures

Using iterated-group

[iterated-group[n → [line [point [× n 20] 0] [point [× n 20] 300]]]10]

Page 12: Six compound procedures and higher-order procedures

Using iterated-group

[iterated-group[n → [ink [pen 'black n] [line [point [× n 20] 0] [point [× n 20] 300]]]]21]

Page 13: Six compound procedures and higher-order procedures

Using iterated-group

► [iterated-group [n → [translate [point [× n 20] [× n 20]] [box 10 10]]]

5]

Page 14: Six compound procedures and higher-order procedures

Using iterated-group

► [iterated-group [n → [translate [point 0 [× n 10]] [box 10 10]]]

5]

Page 15: Six compound procedures and higher-order procedures

Using iterated-group

► [iterated-group [n → [translate [point [× n 10] [× [sin [ ⁄ n 2]] 30]] [box 10 10]]] 20]

Page 16: Six compound procedures and higher-order procedures

What about this one?

► [iterated-group [m → [iterated-group [n → [translate [point [× m 10] [× n 10]] [box 10 10]]]

5] 5]

?►

Page 17: Six compound procedures and higher-order procedures

What about this one?

► [iterated-group [m → [iterated-group [n → [translate [point [× m 10] [× n 10]] [box 10 10]]]

5] 5]

Makes one block

Page 18: Six compound procedures and higher-order procedures

What about this one?

► [iterated-group [m → [iterated-group [n → [translate [point [× m 10] [× n 10]] [box 10 10]]]

5] 5]

Makes one block Iterates it vertically to make a stack of blocks

Page 19: Six compound procedures and higher-order procedures

What about this one?

► [iterated-group [m → [iterated-group [n → [translate [point [× m 10] [× n 10]] [box 10 10]]]

5] 5]

Makes one block Iterates it vertically to make a stack of blocks Iterates the whole stack horizontally

Page 20: Six compound procedures and higher-order procedures

What about this one?

► [iterated-group [m → [iterated-group [n → [translate [point [× m 10] [× n 10]] [box 10 10]]]

5] 5]

Page 21: Six compound procedures and higher-order procedures

What about this one?

► [iterated-group [n → [rotate [× 10 n] [translate [point n 0] [paint [color [× n 10] [− 256 [× n 10]] 0] [box 100 50]]]]] 25]

Page 22: Six compound procedures and higher-order procedures

What about this one?

► [iterated-group [n → [rotate [× 10 n] [translate [point n 0] [paint [color [× n 10] [− 256 [× n 10]] 0] [box 100 50]]]]] 25]

Page 23: Six compound procedures and higher-order procedures

Making a variant of iterated-group

Iterated-group always counts from 0 to count-1 by 1

What if we wanted different ranges? different steps?

[define iterate-in-range[proc start end count → ???]]

Page 24: Six compound procedures and higher-order procedures

Making a variant of iterated-group

We want to write something that acts just like iterated-group, but Counts from start to end

instead of 0 to count-1 Does it in count steps

How do we write something like that?

[define iterate-in-range[proc start end count → ???]]

Page 25: Six compound procedures and higher-order procedures

Making a variant of iterated-group

How about using iterated-group?

Constructive laziness: Get as much mileage

as you can from your existing tools

[define iterate-in-range[proc start end count → [iterated-group ??? ???]]]

Page 26: Six compound procedures and higher-order procedures

Making a variant of iterated-group

Okay, so what arguments do we pass to iterated group?

[define iterate-in-range[proc start end count → [iterated-group ??? ???]]]

Page 27: Six compound procedures and higher-order procedures

Making a variant of iterated-group

The easy one is the count We know that we still

want to run count times

So we just pass the count parameter on

[define iterate-in-range[proc start end count → [iterated-group ??? count]]]

Page 28: Six compound procedures and higher-order procedures

Making a variant of iterated-group

The procedure argument is harder

[define iterate-in-range[proc start end count → [iterated-group ??? count]]]

Page 29: Six compound procedures and higher-order procedures

Making a variant of iterated-group

The procedure argument is harder

We could just pass proc on But then it gets called with

numbers between 0 and count …

… and we want it to get called with numbers between start and end

[define iterate-in-range[proc start end count → [iterated-group proc count]]]

Page 30: Six compound procedures and higher-order procedures

Making a variant of iterated-group

The procedure argument is harder

We could just pass proc on [Can’t]

But sooner or later, we do need to call proc The question is what we

pass to it Can’t be n because n goes

from 0 to count…

[define iterate-in-range[proc start end count → [iterated-group [n → [proc ???]] count]]]

Page 31: Six compound procedures and higher-order procedures

Making a variant of iterated-group

We need an expression that converts n

(a number from 0 to count) Into a number from start to

end

[define iterate-in-range[proc start end count → [iterated-group [n → [proc ???]] count]]]

Page 32: Six compound procedures and higher-order procedures

Making a variant of iterated-group

We need an expression that converts n

(a number from 0 to count) Into a number from start to

end

Here’s a trick: Add start

Now it at least starts at start

[define iterate-in-range[proc start end count → [iterated-group [n → [proc [+ start

n]]] count]]]

Page 33: Six compound procedures and higher-order procedures

Making a variant of iterated-group

We need an expression that converts n

(a number from 0 to count) Into a number from start to

end

Here’s a trick: Add start

Now it at least starts at start

And multiply n by a fudge factor to make it work out to end when n=count

[define iterate-in-range[proc start end count → [iterated-group [n → [proc [+ start

[× n ???]]]] count]]]

Page 34: Six compound procedures and higher-order procedures

Making a variant of iterated-group

We need an expression that converts n

(a number from 0 to count) Into a number from start to

end

Here’s a trick: Add start

Now it at least starts at start And multiply n by a fudge

factor to make it work out to end when n=count

It’s not obvious, but the right fudge factor turns out to be:

(end-start)/count

[define iterate-in-range[proc start end count → [iterated-group [n → [proc [+ start

[× n [ ∕ [- end start]

count]]]]] count]]]

Page 35: Six compound procedures and higher-order procedures

Common errrors

See if you can identify the bugs in this code

Page 36: Six compound procedures and higher-order procedures

Code:[iterated-group [box 10 10] 10]

Error message:Argument Type Exception

Page 37: Six compound procedures and higher-order procedures

Getting the types wrong

Code:[iterated-group [box 10 10] 10]

Iterated-group needs a procedure as its first argument

Page 38: Six compound procedures and higher-order procedures

Getting the types wrong

Code:[iterated-group [n → [box 10 10]] 10]

This runs, but it produces 10 boxes of the same size in the same position, piled on top of one another

Page 39: Six compound procedures and higher-order procedures

Code:[iterated-group [n → [translate [point [n] 0] [box 10 10]]] 5]

Error message:Tried to call something that wasn’t a procedure

Page 40: Six compound procedures and higher-order procedures

Don’t write all your code on one line

Code:[iterated-group [n → [translate [point [n] 0] [box 10 10]]] 5]

Error message:Tried to call something that wasn’t a procedure

Page 41: Six compound procedures and higher-order procedures

Don’t write all your code on one line

Code:[iterated-group [n → [translate [point [n] 0] [box 10 10]]] 5]

Error message:Tried to call something that wasn’t a procedure

Page 42: Six compound procedures and higher-order procedures

Gratuitous bracketing

Code:[iterated-group [n → [translate [point [n] 0] [box 10 10]]] 5]

Adding brackets means “call this as a procedure” But it’s not a procedure

Page 43: Six compound procedures and higher-order procedures

Code:[iterated-group [n → [translate [point 0 n [box 10 10]]]] 10]

Error message:Wrong number of arguments

Page 44: Six compound procedures and higher-order procedures

Missing bracket

Code:[iterated-group [n → [translate [point 0 n] [box 10 10]]]] 10]

Forgetting the bracket at the end of the point call makes the box an argument to point

Page 45: Six compound procedures and higher-order procedures

Missing bracket

Code:[iterated-group [n → [translate [point 0 n] [box 10 10]]] 10]

Fixing the bracketing also fixes the indenting Notice that box and point are now indented

together Meaning they are both arguments to translate

Page 46: Six compound procedures and higher-order procedures

Code:[iterated-group [n → [translate [point n × 7 0] [box 10 10]]] 10]

Error message:Wrong number of arguments

Page 47: Six compound procedures and higher-order procedures

Brackets missing entirely

Code:[iterated-group [n → [translate [point [n × 7] 0] [box 10 10]]] 10]

Error message:Attempt to call something that isn’t a procedure

Page 48: Six compound procedures and higher-order procedures

Brackets missing entirely

Code:[iterated-group [n → [translate [point [× n 7] 0] [box 10 10]]] 10]

The procedure always has to come first

Page 49: Six compound procedures and higher-order procedures

Code:[iterated-group [n → [translate [rotate 30 [box 10 10]] [point n 10]]] 10]

Error message:Argument type exception

Page 50: Six compound procedures and higher-order procedures

Arguments out of order

Code:[iterated-group [n → [translate [point n 10] [rotate 30 [box 10 10]]]] 10]

Page 51: Six compound procedures and higher-order procedures

Conditionals: the if operator

[if test consequent alternative] If test is true,

Then evaluate and return consequent

Otherwise, evaluate and return alternative

Some useful tests [= a b]

Checks if a and b are the same [> a b], [≤ a b], etc.

Compares numbers [and test1 test2 … testn]

[or test1 test2 … testn][not test]

Combines tests into more complicated tests

► [define abs [n → [if [> n 0] n

[- n]]]]<Procedure abs>► [abs 5]5► [abs -5]5►

Page 52: Six compound procedures and higher-order procedures

Boolean objects

Everything in Meta is an expression, And (almost) all expressions have values,

So then what kind of value is [= a b] ?

Answer: true or false

The system includes two magic data objects, true and false, which are used to represent the answers to tests

Page 53: Six compound procedures and higher-order procedures

Final rules of computation

If it’s a word (i.e. a name) Look up its value in the dictionary Return (output) it

If it’s a constant It’s its own value Return it

If it says [define name value] Find the value of value Update the dictionary entry for name

If it looks like: [name … name → expression]

Make a procedure Whose arguments have the specified name And whose return value is expression

If it says [if test consequent alternative] Compute the value of test If it’s the magic value true, compute and return the

value of consequent Otherwise, compute and return the value of

alternative

If it says [with name = value … expression]

Find the values of all the value expresions Update their respective names in the dictionary Compute expression using the revised dictionary Set the dictionary back

If it otherwise has brackets (i.e. it looks like “[a b c …]”)

Find the values of subexpressions Call first one with others as inputs Return its output