[plt-scheme] HtDP 17.7.1-4 - Diff between name-of-function and function-name
Hi All --
Two questions about exercises 17.4.*.
The terms of these exercises suggests a significant difference between
a function-name and name-of-function.
Is a function-name a symbol and a name-of-function a variable, where
A function-definition(fd) is a structure
(make-fd f-name p-name f-body) where
f-name is a symbol, p-name is a symbol and f-body is a scheme-
expression, and;
A name-of-function(fn) is the variable in the sentence
(define fn fd)
where define is a keyword, fn is a variable and fd is function-
definition, and;
A function-application (fa) is a structure, where
(make-fa fn arg)
where fn is a name-of-function and arg is a scheme-expression?
If this is the case, then I have a follow-up question for exercise
17.7.4: what is the meaning of Step 2, which instructs "evaluate-with-
defs" to "look up the definition of P is defs?"
Example:,
(define(f x) (+ 3 x) is translated to name-of-function
(define f (make-fd 'f 'x (make-add 3 'x))), and;
(define (h u) (f (* 2 u))) is translated to name-of-function
(define h(make-fd 'h 'u(make-fa f (make-mul 2 'u))))
;;evaluate-with-defs: scheme-expression list-of-defs > error or number
;;consumes a scheme-expression and a list-of-function-definitions:
returns an error if the ;;original scheme-expression is not numeric,
or if a function found as an arg for a function-;;application is not
listed in the list-of-defs; otherwise, returns a number
Examples:
1. (not(evaluate-with-defs 3 (list h))), since f is embedded in h, and
f is not present in list-of-defs
2. (evaluate-with-defs 3 (list f h)) returns 12
3. (not(evaluate-with-defs (f 3) (list h)))
4. (evaluate-with-defs (f 3) (list f h))) returns 18
My initial solution to this problem is this:
(define(evaluate-with-defs sx lofP)
(cond
[(empty? lofP)(evaluate-expression sx)]
[else (evaluate-with-defs(evaluate-with-one-def sx (first lofP))
(rest lofP)))]))
The second condition would begin by applying f to 3, returning 6, and
then recurring. Next, it would apply h to 6. While doing so, it
would find that h is defined as a function-application of f to (* 2
u). At that point, it would "look-up" f in lofP to find its'
definition. However, f has already been tossed after the first
recursive call, so it would presumably return an error, which is not
correct.
Is the solution to add a second parameter to evaluate-with-defs: "lofP-
index" which would serve as a look-up index for all function-
definitions listed in the original "lofP?" If this is the case, then
all the previous functions would have to be retrofitted to carry this
index parameter. That doesn't seem right.
Further, what is the point of "looking-up" the function-definition f
in lofP when the function-definition is present in the name-of-
function attribute of the function-application? The only way this
would make sense to me is if the name-of-function attribute was meant
to be a symbol, and not a variable. If that's the case, then my
approach to solving this and the previous exercise is wrong.
For completeness, here are the rest of my data-definitions and my
version of the solution to 17.7.3:
Thanks,
Dave Yrueta
Data Defs:
An "add" is a structure
(make-add left right)
where left and right are both Scheme-Expressions
An "mul" is a structure
(make-mul left right)
where left and right are both Scheme-Expressions
A Scheme-Expression (SX) is either
1. a number
2. a symbol
3. an add structure
4. a mul structure
5. a function-application (fa)
;;17.7.3
;;evaluate-with-one-def: sx P > error or Scheme Expression
;;consumes a Scheme Expression and a Function-Definition, and returns
either an 'error ;;or the evaluated Scheme Expression
(define(evaluate-with-one-def sx P)
(cond
[(numeric? sx)
(cond
[(number? sx)(evaluate-expression(subs(fd-p-name P)sx(fd-f-body
P)))]
[else(evaluate-with-one-def (evaluate-expression sx)P)])]
[else 'error]))
;;subst:symbol number scheme-expression > scheme-expression
;;consumes a symbol, number and scheme-expression, substitutes all
instances of the ;;symbol appearing in the scheme-expression with the
number, and then returns a ;;structurally equivalent expression.
(define(subs sym num sx)
(cond
[(mul? sx)(make-mul (subs sym num (mul-left sx))(subs sym num (mul-
right sx)))]
[(add? sx)(make-add (subs sym num (add-left sx))(subs sym num (add-
right sx)))]
[(fa? sx) (evaluate-with-one-def(subs sym num (fa-arg sx))(fa-fn
sx))]
[(number? sx)sx]
[(symbol=? sym sx)num]
[else sx]))
(define(numeric? sx)
(cond
[(number? sx)true]
[(struct? sx)(test-struc sx)]
[else false]))
(define(test-struc sx)
(cond
[(mul? sx)(and(numeric? (mul-left sx))(numeric? (mul-right sx)))]
[else (and(numeric? (add-left sx))(numeric? (add-right sx)))]))
(define(evaluate-expression nx)
(cond
[(boolean=? (numeric? nx)false)'error]
[else (process-nx nx)]))
(define(process-nx nx)
(cond
[(number? nx)nx]
[(mul? nx)(*(evaluate-expression (mul-left nx))(evaluate-
expression (mul-right nx)))]
[else (+(evaluate-expression (add-left nx))(evaluate-expression
(add-right nx)))]))