开发者

Scheme: Proper application of the eval function?

at work I encountered a basic problem when trying to implement a configuration script with Scheme. To avoid the need of inventing an artificial and restricted language the script should contain actual cod开发者_如何学JAVAe. This code shall be evaluated later on. To make the configuration work as desired it has to have access to certain variables. These variables are only known in the context of the evaluation. Therefore the configuration script has to be evaluated in the current environment. Here is a primitive example of what I am talking about:

(let ((a #t))
  (wr "a is ..."
    (eval '(if a "true" "false"))))

When running this code I'd always get an error message telling me that the variable 'a' is unknown. So the question is: Do you know how to evaluate frozen code inside the current environment?

P.S.: I use the bigloo compiler.

///////////////////////////////////////////// EDIT: //////////////////////////////////////////////////////

When using the approach suggested by Chris I came to another interesting problem, the usage of the case keyword. The following two examples both use the same case construction which should trigger the output of a "yes!" line. Unfortunately they behave differently.

Usual -> output is "yes!" as expected:

  (define testit "test")
  (case testit
    (("test")
     (begin (newline) (write "yes!") (newline)))
    (else
      (begin (newline) (write "no!") (newline)))))

With eval -> output is surprisingly "no":

  (define env (null-environment 5))
  (eval '(define testit "test") env)
  (eval '(case testit
           (("test")
            (begin (newline) (write "yes!") (newline)))
           (else
            (begin (newline) (write "no!") (newline))))) 

Does that make any sense?


eval cannot access lexical variables, such as those defined using let.

Instead, you have to create an environment, and populate it with the variables you want to make available. For example:

(define env (null-environment 5))
(eval '(define a #t) env)
(wr "a is ..."
    (eval '(if a "true" "false") env))


To answer your edit, you aren't passing env as an argument to the last eval. testit doesn't exist in the environment that eval creates if that argument isn't given.

That may be a typo, but if not, that's your problem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜