一般来说,我希望在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 可能是什么?
答案 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))
)