Procedures that return procedures as values are also
higher-order procedures.
Recall: If
g is a function whose values are
acceptable as arguments to
f, then
the
composition of f and g is:
f(g(x))
Exercise 5.16: Write a procedure that takes two
procedures as arguments and returns the
procedure that is their composition as a
result.
(define compose
(lambda (f g)
_______________))
-
(define compose
(lambda (f g)
(lambda (x) (f (g x)))))
Q: How to define sqrt_abs (using compose) so that
(sqrt_abs -16) ⇒ 4 ?
-
A:
(define sqrt_abs (compose sqrt abs))
- Turing machines
- Role in breaking German "Enigma" codes
- Role in designing digital electronic
stored-program computer
- Computing machinery and intelligence:
the Turing Test
- Tragic personal life
- Assume halts? exists.
- Then it must return #t or #f for any procedure
given it as an argument.
- Consider the following procedure:
(define debunk-halts?
(lambda ()
(if (halts? debunk-halts?)
(loop-forever)
(return-seven))))
- Now we have both:
- (halts? debunk-halts) loops forever if
debunk-halts halts
- (halts? debunk-halts) halts with 7 if
debunk-halts does not halt
- Since 4 is a contradiction, the assumption (1) must be false.
- Moral of the story: "mathematically specifiable" and
"computable" are different things.
If
halts? were to exist, then it could be used
to solve problems that mathematicians have
not been able to solve. For example:
Q: Are there any odd perfect numbers?
-
If there are any, then the following procedure would
eventually find it and halt:
(define find-perfect-odd
(lambda (n) ; start n at 1
(if (perfect? n)
n
(find-perfect-odd (+ n 2)))))
Since there may not be enough time left in the universe to wait,
we could ask:
(halts? find-perfect-odd) ⇒ <the magic answer>
While halts? sounds too good to be true, this is not a proof that it
doesn't exist.
Even if we don't know how to write
halts?, we know
how it would behave if it were to exist.
Consider:
(define return-seven
(lambda () 7))
(define loop-forever
(lambda () (loop-forever)))
If
halts? exists and works as it should, then we know:
(halts? return-seven) ⇒ #t
(halts? loop-forever) ⇒ #f
Q: How could
halts? work?
-
Not by checking to see if a procedure halts,
because if it doesn't halt it may just need
a few thousand more years before it
finishes.
Q: So, could halts? exist?
The power of computational processes has led
computer scientists to speculate on the
following:
Q: Is it possible for
any mathematically
specified function to be computed by some procedure?
-
If the answer to this question is "yes", then
the mathematically precise function h below should be computable:
- Let P = the set of all procedures.
- Let h: P → {true,false}.
- For all p ∈ P, define:
h(p) | = |
true if p eventually halts |
| = | false otherwise |
If all mathematically precise functions are computable, then there must be a
procedure to compute h.
Call it halts?.
Suppose we want a procedure called
arithmetic to take three arguments: an
arithmetic operator and two operands:
(arithmetic + 3 4) ⇒ 7
(arithmetic * 3 4) ⇒ 12
(arithmetic remainder 30 4) ⇒ 2
- arithmetic takes an arithmetic operator as an argument,
so it is a higher-order procedure.
- equal? is a more general equality predicate than
=, which works only on numbers.
- This use of equal? has a procedure as its second
argument, so equal? is also a higher-order procedure.
Q: Why is
arithmetic inconvenient?
-
Not flexible: allowing a new operation requires adding another
cond clause:
Recall a Scheme procedure application:
(procedure arg1 arg2 ... argn )
All elements of the application,
including the procedure itself, are evaluated.
(define operate +)
(operate 3 4) ⇒ 7
Thus a procedure can be given to another
procedure as an argument (as data), and then
applied to other data (as a program):
Now
any of the following will work:
(arithmetic + 3 4) → 7
(arithmetic * 3 4) → 12
(arithmetic remainder 30 4) → 2
(arithmetic / 45 17) → 2 11/17
(arithmetic expt 3 4) → 81
Q: Will only arithmetic procedures work?
-
Any procedure taking two arguments will work:
(arithmetic stack (filled-triangle -1 -1 0 1 1 -1)
(filled-triangle -1 -1 0 1 1 -1)) ;; returns an image
-
If together-copies-of is ever changed or improved,
both stack-copies-of and power benefit.
For example, together-copies-of could be modified to perform
linear iteration (Ex. 5.1) or take logarithmic time (Ex. 5.2).