如何在方案中打印用户定义的环境?

时间:2014-01-04 15:57:46

标签: scheme environment

一般来说,我希望在REPL中编写代码,有时将自己定义的符号保存到文件中。

例如 - 输入REPL后:

]=> (define (square x) (* x x))
]=> (define sizes '(5 10 15))

我需要调用一些东西来接收先前定义的对象列表。 在这种情况下,它可以用这种方式表示:

]=> (define get-user-defined-environment 
      (list (list 'sizes sizes) (list 'square square)))

然后可以调用这样的东西:

]=> (map 
      (lambda (lst) (begin 
         (display "(define ") 
         (pp (first lst)) 
         (pp (second lst)) 
         (display ")\n\n"))) 
      get-user-defined-environment)

(define sizes
(5 10 15)
)

(define square
(named-lambda (square x)
  (* x x))
)

并且,也许,以某种方式将输出保存到文件。

那么, get-user-defined-environment 可能是什么?

2 个答案:

答案 0 :(得分:1)

标准Scheme中没有允许您记录环境的内容。但是,您可以定义自己的define - 类似于您的语法。

> (define *env* '())
> (define-syntax def&rec
    (syntax-rules ()
      ((_ name init)
       (define name
         (let ((value init))
           (set! *env* (cons (cons 'name value) *env*))
           value)))))
> (def&rec foo 1)
> (def&rec bar (lambda (x) x))
> *env*
((bar . #<procedure value>) (foo . 1))

如果您打算将此内容写入文件,比如希望将其重新读入,则需要在上面的语法中记录init表单,而不是value。这是记录init

的另一种语法形式
> (define-syntax def&rec2
    (syntax-rules ()
      ((_ name init)
       (define name
         (let ((value init))
           (set! *env* (cons (list 'name value 'init) *env*))
           value)))))
> (def&rec2 equal-to (lambda (x) (lambda (y) (equal? x y))))
> *env*
((equal-to #<procedure value>
   (lambda (x) (lambda (y) (equal? x y))))
  (bar . #<procedure value>) (foo . 1))

答案 1 :(得分:0)

感谢uselpa指向How can find all functions and bounded symbols in an "environment"

(environment-bound-names(the-environment)) - 返回用户定义名称列表。

然后(环境查找(环境)名称) - 返回当前环境中名称的值。

这是方法:

]=> (define (p1 name env) (begin (display "(define ") (pp name) (pp (environment-lookup env name)) (display ")\n\n")))

]=> (define (p2 lst env) (for-each (lambda (name) (p1 name env)) lst))

]=> (p2 (reverse (environment-bound-names (the-environment))) (the-environment))

(define p1
(named-lambda (p1 name env)
  (display "(define ")
  (pp name)
  (pp (environment-lookup env name))
  (display ")\n\n"))
)

(define p2
(named-lambda (p2 lst env)
  (for-each (lambda (name) (p1 name env)) lst))
)