Given these definitions in an imaginary, dynamically scoped variant of Scheme...
(define m 50) (define n 100) (define (hardy) (display (list "In Hardy, n=" n)) (newline)) (define (laurel n) (display (list "In Laurel, m=" m)) (newline) (display (list "In Laurel, n=" n)) (newline) (foo!) (hardy)) (define (foo!) (set! n (+ 1 n)))
...what would this code output using dynamic scoping rules?
(display (list "In main program, n=" n)) (newline) (laurel 1) (hardy)
Select below to reveal answer:
(In main program, n= 100) (In Laurel, m= 50) (In Laurel, n= 1) (In Hardy, n= 2) (In Hardy, n= 100)
For simplicity's sake, your function definitions may assume that their arguments are non-empty lists, i.e., no error-checking.
Write a function dupe-first
in pure functional
style that takes a list and returns a copy of the list with
the first element duplicated, e.g., (dupe-first '(1 2 3)) =>
(1 1 2 3)
.
hidden answer:
(define (dupe-first l) ;; prepend copy of first element to list (cons (car l) l))
Write a side-effecting version dupe-first!
of the
same function that modifies the actual analogously. Refer to
this sample usage:
(define x '(1 2 3)) x => (1 2 3) (dupe-first! x) x => (1 1 2 3)
hidden answer:
(define (dupe-first! l) (define n (list (car l))) ; create new list node... (set-cdr! n (cdr l)) ; w/ next pointing at l's second node (set-cdr! l n) ; splice new node after first l) ; return modified list (though not necessary)
Write similar pure functional and side-effecting versions of a function that removes the second element of the list, as in these examples:
(define x '(1 2 3)) (remove-second x) => (1 3) x => (1 2 3) (remove-second! x) => (1 2 3) ;; or "Unspecified return value" is OK x => (1 3)
hidden answer:
(define (remove-second l) ;; prepend first element to cdr of (cons (car l) (cddr l))) (define (remove-second! l) ;; splice out second node by setting first node's cdr to third node (set-cdr! l (cddr l)) l)
It would not be very easy to write a side-effecting function
remove-first!
that removes the first element of a
list. Explain why this is the case.
hidden hint:
It has to do with the way parameters are passed in Scheme.
By the way, the pure functional version is easy to write. Don't run your brain too hard: It rhymes with "footer."