当我们调用顶级环境的父级在(environment-lookup system-global-environment name)
哪里时,它是否也会在其子环境中查找?system-global-environment
从文档上看,它们似乎是分开的。如果是这样,为什么我们在这里定义父环境?
本节中的操作允许您单独检查特定环境与其父环境的绑定,从而揭示环境的框架结构。
Ps:SO 中是否有适合env
此问题的标签?(此处的建议environment-variables
不合适。)
我正在尝试在 Chez 方案中创建一个符号派生函数。它运行良好(尚未进行简化):
(define (derive var expr)
;; var is the direction in which you would like to derive
(if (list? expr)
(case (car expr)
('+ (sum-rule var expr))
('- (sub-rule var expr))
('* (prod-rule var expr))
;; other rules
(else (atomic-rule var expr )))
(atomic-rule var expr)))
(define (atomic-rule var expr)
(if (list? expr)
expr
(if (eqv? var expr)
1
0)))
(define (sum-rule var expr)
(let ((args (cdr expr)))
`(+ ,@(map (lambda (e) (derive var e)) args))))
(define (sub-rule var expr)
(let ((args (cdr expr)))
`(- ,@(map (lambda (e) (derive var e)) args))))
(define (prod-rule var expr)
(let* ((args (cdr expr))
(f (car args))
(g (cadr args)))
`(+ (* ,f ,(derive var g))
(* ,g ,(derive var f)))))
我可以执行(derive 'x '(+ (* x x) (* x y)))
并得到(+ (+ (* x 1) (* x 1)) (+ (* x 0) (* y 1)))
正确的结果。但我还想以编程方式创建从这些表达式返回数值的函数。
我的尝试失败了:
(define (lambda-derive var expr)
(let ([derivative (derive var expr)])
(lambda (var) derivative)))
((lambda-derive 'x '(* x x)) 2) => (+ (* x 1) (* x 1)) ;; should be 4
(define-syntax lbd-macro
(lambda (context)
(syntax-case context ()
[(k expr var )
(with-syntax ([new-var (datum->syntax #'k (syntax->datum #'var))])
#'(lambda (new-var) expr))])))
((lbd-macro (derive 'x '(* x x)) x) 2) => (+ (* x 1) (* x 1)) ;; should be 4
我感觉我忽略了一些非常明显的东西。有人能提供一些启示吗?(是的,我知道这些尝试没有涵盖多变量情况)
==编辑==
我睡了一个坏觉并决定继续工作,我找到了与 @ignis volens 描述的类似的解决方案,尽管使用了哈希表并且更加黑客化:
(define (lambda-aux variables vals expr)
(let ((ht (make-eqv-hashtable (length variables))))
(for-each (lambda (k v) (hashtable-set! ht k v)) variables vals)
(let loop ((expr expr))
(if (list? expr)
(let ((op (car expr))
(args (map loop (cdr expr))))
(cons op args))
(let ((variable (hashtable-ref ht expr #f)))
(if variable
variable
(if (number? expr)
expr
(error "variable not found"))))))))
(define-syntax lambda-derive
(syntax-rules ()
[(_ expr var var* ...)
(lambda (var var* ...) (eval (lambda-aux '(var var* ...) (list var var* ...) (derive 'var 'expr) )))]))
可以像这样使用:
(define my-test-derivative
;;f(x,y) = x^2 + x * y
;;df/dx (x,y) = 2*x + y
(lambda-derive (+ (* x y) (* x x)) x y))
(my-test-derivative 2 2) => 6
(my-test-derivative 8 2) => 18
;; ...
我正在阅读 ChezScheme 中的《小阴谋家》,在第 2 章中我遇到了以下问题。我写了lat的定义?根据书上的说法。
(define lat?
(lambda (l)
(cond
((null? l) #t)
((atom? (car l)) (lat? (cdr l)))
(else #f)
)
)
)
然后定义一个列表
(define l '('bacon 'and 'eggs))
进而
(lat? l)
评估为#f
.
问题似乎在于,虽然(car l)
评估为'bacon
并atom? 'bacon
评估为#t
,(atom? (car l))
但评估为#f
。
在 Emacs Lisp 和 Common Lisp 中,返回以下内容nil
(let (x y z)
x)
但在我尝试过的每个方案中,它都会引发错误。
上述内容在任何计划标准下是否可以接受?
> (equal? '(1 4) (car '('(1 4))))
#f
哎呀,上面的结果应该是#t,因为这些片段的结果是#t
如下:
> (car '('(1 4)))
'(1 4) ; Scheme doesn't get confused by list of a single list
> (equal? '(1 4) '(1 4))
#t. ; Scheme can see the equality of lists
这一定是一些疯狂的范围界定事物或相同的地址事物?测试同一地址的东西?如果我们把它分解,我们仍然得到#f,这表明相等?s-表达式有自己的作用域吗?
> (define piece (car '('(1 4))))
> piece
'(1 4)
> (equal? '(1 4) piece)
#f
平等的?应该迭代每个正在比较的列表的成员,如果所有成员对都相等(事实确实如此),则返回#t。所以,这很奇怪,我一定从根本上不理解 car 或嵌套 s 表达式。
它在 sbcl 中也失败了,所以发生了一些我不明白的黑暗神秘的事情:
* (equalp '(1 4) (car '('(1 4))))
NIL
* (car '('(1 4)))
'(1 4)
* (equalp '(1 4) '(1 4))
T
*
它在 Racket 中也失败了:
Welcome to DrRacket, version 8.9 [cs].
Language: racket/base, with debugging; memory limit: 128 MB.
> (equal? '(1 4) (car '('(1 4))))
#f
这里是成员的定义?Abelson 和 Sussman SICP 的函数:
(define (member? x list)
(if (null? list) #f
(if (equal? x (car list)) #t
(member? x (cdr list)))))
我想我写了完全相同的东西:
(define (my-member item lst)
(if (null? lst)
#f
(if (equal? item (car lst))
#t
(my-member item (cdr lst)))))
所以,我是问题所在,但我不明白。这在语义上似乎很明显。