去掉列表中的外括号
Getting rid of outer parentheses on a list
我遇到的特殊问题是为 question 4.16b of Structure and Interpretation of Computer Programs 创建解决方案。这里需要创建一个过程来转换
(lambda (a b)
(define u 'u)
(define v 'v)
'e1))
进入:
(lambda (a b)
(let ((u '*unassigned*)
(v '*unassigned*))
(set! u 'u)
(set! v 'v)
'e1))
我的程序(见下文)不这样做,而是将其转换为:
(lambda (a b)
(let ((u *unassigned*)
(v *unassigned*))
((set! u 'u)
(set! v 'v))
('e1)))
make-sets
生成的 sets!
列表(见下文)和 [=19= 生成的其余正文(('e1)
以上)存在问题] (见下文)。它们被添加到列表中,而我希望将它们作为单个语句,即 (set! u 'u) (set! v 'v)
而不是 ((set! u 'u) (set! v 'v))
和 'e1
而不是 `('e1).
程序:
;; b. Write a procedure scan-out-defines that takes a procedure body and returns an
;; equivalent one that has no internal definitions, by making the transformation
;; described above.
(define (scan-out expr)
(let ((vars (cadr expr))
(body (cddr expr)))
(make-lambda vars
; loop over body,
; store all definition names and bodies of the defines
; once finished looping transform those into lets
; where the rest is added to the body
(let body-transform ((body-elements body)
(definition-names '())
(definition-bodies '())
(rest-of-body '()))
(if (null? body-elements)
(transform-define-into-let definition-names
definition-bodies
rest-of-body)
(let ((current-element (car body-elements)))
(if (tagged-list? current-element 'define)
(body-transform (cdr body-elements)
(cons (get-definition-name current-element)
definition-names)
(cons (get-definition-body current-element)
definition-bodies)
rest-of-body)
(body-transform (cdr body-elements)
definition-names
definition-bodies
(cons current-element rest-of-body)))))))))
(define (tagged-list? exp tag)
(if (pair? exp)
(eq? (car exp) tag)
false))
(define (get-definition-name expr)
(cadr expr))
(define (get-definition-body expr)
(caddr expr))
(define (transform-define-into-let vars vals rest-of-body)
(list (list 'let (make-unassigned-vars vars)
(make-sets vars vals)
rest-of-body)))
(define (make-unassigned-vars vars)
(let aux ((var-elements vars)
(unassigned-vars '()))
(if (null? var-elements)
unassigned-vars
(aux (cdr var-elements)
(cons (list (car var-elements) '*unassigned*) unassigned-vars)))))
(define (make-sets vars vals)
(let aux ((var-elements vars)
(val-elements vals)
(sets '()))
(if (null? var-elements)
sets
(aux (cdr var-elements)
(cdr val-elements)
(cons (list 'set! (car var-elements) (car val-elements)) sets)))))
(define (make-lambda parameters body)
(cons 'lambda (cons parameters body)))
; testing
(scan-out '(lambda (a b)
(define u 'u)
(define v 'v)
'e1))
; Should be transformed into:
; => (lambda (a b)
; (let ((u '*unassigned*)
; (v '*unassigned*))
; (set! u 'u)
; (set! v 'v)
; 'e1))
; But is transformed into:
; => (lambda (a b)
; (let ((u *unassigned*)
; (v *unassigned*))
; ((set! u (quote u))
; (set! v (quote v)))
; ((quote e1))))
我尝试的是像这样展平列表:
(define (transform-define-into-let definition-names definition-bodies rest-of-body)
(list (list 'let (make-unassigned-vars definition-names)
(append* (make-sets definition-names definition-bodies))
(append* rest-of-body))))
但是只有 rest-of-body
被去掉了它的外括号,make-sets
仍然是一个列表:例如,
(lambda (a b)
(let ((u *unassigned*)
(v *unassigned*))
((set! u 'u)
(set! v 'v))
'e1))
去掉外括号的正确方法是什么?
如果有人能帮我解决这个问题,我将不胜感激。
你应该改变:
(define (transform-define-into-let vars vals rest-of-body)
(list (list 'let (make-unassigned-vars vars)
(make-sets vars vals)
rest-of-body)))
进入:
(define (transform-define-into-let vars vals rest-of-body)
(list (append (list 'let (make-unassigned-vars vars))
(append (make-sets vars vals)
rest-of-body))))
还有:
(define (make-unassigned-vars vars)
(let aux ((var-elements vars)
(unassigned-vars '()))
(if (null? var-elements)
unassigned-vars
(aux (cdr var-elements)
(cons (list (car var-elements) '*unassigned*) unassigned-vars)))))
进入
(define (make-unassigned-vars vars)
(let aux ((var-elements vars)
(unassigned-vars '()))
(if (null? var-elements)
unassigned-vars
(aux (cdr var-elements)
(cons (list (car var-elements) ''*unassigned*) unassigned-vars)))))
最后请注意 'u
与 (quote u)
相同。
我遇到的特殊问题是为 question 4.16b of Structure and Interpretation of Computer Programs 创建解决方案。这里需要创建一个过程来转换
(lambda (a b)
(define u 'u)
(define v 'v)
'e1))
进入:
(lambda (a b)
(let ((u '*unassigned*)
(v '*unassigned*))
(set! u 'u)
(set! v 'v)
'e1))
我的程序(见下文)不这样做,而是将其转换为:
(lambda (a b)
(let ((u *unassigned*)
(v *unassigned*))
((set! u 'u)
(set! v 'v))
('e1)))
make-sets
生成的 sets!
列表(见下文)和 [=19= 生成的其余正文(('e1)
以上)存在问题] (见下文)。它们被添加到列表中,而我希望将它们作为单个语句,即 (set! u 'u) (set! v 'v)
而不是 ((set! u 'u) (set! v 'v))
和 'e1
而不是 `('e1).
程序:
;; b. Write a procedure scan-out-defines that takes a procedure body and returns an
;; equivalent one that has no internal definitions, by making the transformation
;; described above.
(define (scan-out expr)
(let ((vars (cadr expr))
(body (cddr expr)))
(make-lambda vars
; loop over body,
; store all definition names and bodies of the defines
; once finished looping transform those into lets
; where the rest is added to the body
(let body-transform ((body-elements body)
(definition-names '())
(definition-bodies '())
(rest-of-body '()))
(if (null? body-elements)
(transform-define-into-let definition-names
definition-bodies
rest-of-body)
(let ((current-element (car body-elements)))
(if (tagged-list? current-element 'define)
(body-transform (cdr body-elements)
(cons (get-definition-name current-element)
definition-names)
(cons (get-definition-body current-element)
definition-bodies)
rest-of-body)
(body-transform (cdr body-elements)
definition-names
definition-bodies
(cons current-element rest-of-body)))))))))
(define (tagged-list? exp tag)
(if (pair? exp)
(eq? (car exp) tag)
false))
(define (get-definition-name expr)
(cadr expr))
(define (get-definition-body expr)
(caddr expr))
(define (transform-define-into-let vars vals rest-of-body)
(list (list 'let (make-unassigned-vars vars)
(make-sets vars vals)
rest-of-body)))
(define (make-unassigned-vars vars)
(let aux ((var-elements vars)
(unassigned-vars '()))
(if (null? var-elements)
unassigned-vars
(aux (cdr var-elements)
(cons (list (car var-elements) '*unassigned*) unassigned-vars)))))
(define (make-sets vars vals)
(let aux ((var-elements vars)
(val-elements vals)
(sets '()))
(if (null? var-elements)
sets
(aux (cdr var-elements)
(cdr val-elements)
(cons (list 'set! (car var-elements) (car val-elements)) sets)))))
(define (make-lambda parameters body)
(cons 'lambda (cons parameters body)))
; testing
(scan-out '(lambda (a b)
(define u 'u)
(define v 'v)
'e1))
; Should be transformed into:
; => (lambda (a b)
; (let ((u '*unassigned*)
; (v '*unassigned*))
; (set! u 'u)
; (set! v 'v)
; 'e1))
; But is transformed into:
; => (lambda (a b)
; (let ((u *unassigned*)
; (v *unassigned*))
; ((set! u (quote u))
; (set! v (quote v)))
; ((quote e1))))
我尝试的是像这样展平列表:
(define (transform-define-into-let definition-names definition-bodies rest-of-body)
(list (list 'let (make-unassigned-vars definition-names)
(append* (make-sets definition-names definition-bodies))
(append* rest-of-body))))
但是只有 rest-of-body
被去掉了它的外括号,make-sets
仍然是一个列表:例如,
(lambda (a b)
(let ((u *unassigned*)
(v *unassigned*))
((set! u 'u)
(set! v 'v))
'e1))
去掉外括号的正确方法是什么?
如果有人能帮我解决这个问题,我将不胜感激。
你应该改变:
(define (transform-define-into-let vars vals rest-of-body)
(list (list 'let (make-unassigned-vars vars)
(make-sets vars vals)
rest-of-body)))
进入:
(define (transform-define-into-let vars vals rest-of-body)
(list (append (list 'let (make-unassigned-vars vars))
(append (make-sets vars vals)
rest-of-body))))
还有:
(define (make-unassigned-vars vars)
(let aux ((var-elements vars)
(unassigned-vars '()))
(if (null? var-elements)
unassigned-vars
(aux (cdr var-elements)
(cons (list (car var-elements) '*unassigned*) unassigned-vars)))))
进入
(define (make-unassigned-vars vars)
(let aux ((var-elements vars)
(unassigned-vars '()))
(if (null? var-elements)
unassigned-vars
(aux (cdr var-elements)
(cons (list (car var-elements) ''*unassigned*) unassigned-vars)))))
最后请注意 'u
与 (quote u)
相同。