如何在不使用eval string的情况下在scheme中创建符号和命令的动态列表?

如何在不使用eval string的情况下在scheme中创建符号和命令的动态列表?,scheme,eval,Scheme,Eval,我试图使用从输入文件读取的数据进行函数调用。我有下面的函数,它接受顶点列表和任意数量的命令。(我在这里稍微简化了函数) 我的输入文件将有如下内容: (2 (vertex-create "Paris") (vertex-create "London")) 其中2是顶点数 有了这个输入,我想调用creategraph作为 (create-graph '(v1 v2) (set! v1 (vertex-create "Paris")) (set! v2 (vertex-create "L

我试图使用从输入文件读取的数据进行函数调用。我有下面的函数,它接受顶点列表和任意数量的命令。(我在这里稍微简化了函数)

我的输入文件将有如下内容:

(2
(vertex-create "Paris")
(vertex-create "London"))
其中2是顶点数

有了这个输入,我想调用creategraph作为

(create-graph
  '(v1 v2)
  (set! v1 (vertex-create "Paris"))
  (set! v2 (vertex-create "London"))
)
其中v1和v2是为每个顶点创建的符号

我现在要做的是将整个函数构造成一个字符串,并使用eval字符串。但是有没有一种方法可以不使用eval字符串进行函数调用呢?对某些零件使用eval应该可以。更具体地说,我认为我需要能够动态地执行这些操作:

  • 创建符号列表,然后
  • 创建命令(例如(set!v1(顶点创建“Paris”))

我将感谢你的意见。谢谢

是的,您可以不用评估就可以完成此操作。是的,这是一个更好的主意。理解每个程序都可以被视为输入的解释器是很重要的,但一旦理解了eval,就不应该再使用它了

您的程序最终可能会出现以下情况:

#lang racket

(define cmds (file->value input-file))

(define vertex-names (for ([i (in-range (length cmds))])
                       (string->symbol (format "v~s" i))))

(create-graph
 (for/list ([v (in-list vertex-names)]
            [cmd (in-list cmds)])
   (list
    v
    (match cmd
      [(list 'vertex-create str) (vertex-create str)]
      ... other choices? ...
      ))))
我假设您只需从命令列表的长度推断顶点数,而不是指定顶点数。而且,我看不出还有什么其他的“命令”。也,
你的布景!是不必要的,而且很恶心:)

可用于创建此类列表的宏:

(define-syntax make-create-graph-call
  (syntax-rules ()
    ((_ symbol-count commands) 
     (let* ((sym-list (create-sym-list symbol-count))
            (cmds (let loop ((slist sym-list) 
                             (cms commands)
                             (res '()))
                    (if (not (null? slist))
                        (loop (cdr slist) (cdr cms)
                              (cons `(set! ,(car slist) ,(car cms)) res))
                        (reverse res)))))
       `(create-graph ',sym-list ,@cmds))))) 
其中
create sym list
定义为:

(define (create-sym-list count)
  (let loop ((c 0) (res '()))
    (if (< c count)
        (loop (+ 1 c) (cons (string->symbol 
                             (string-append "v" (number->string (+ 1 c)))) res))
        (reverse res))))

谢谢这段代码是我为简化问题而编写的一个示例,因此没有多大意义:)谢谢,我是scheme的新手,所以您的代码非常有用。我本想早些时候问一下创建sym列表的问题,结果帖子没了。哈哈,我想你是editing@umberto如果我的答案是有用的,考虑一下投票:
(define (create-sym-list count)
  (let loop ((c 0) (res '()))
    (if (< c count)
        (loop (+ 1 c) (cons (string->symbol 
                             (string-append "v" (number->string (+ 1 c)))) res))
        (reverse res))))
(make-create-graph-call 2 '((vertex-create "Paris") (vertex-create "London")))

=> (create-graph '(v1 v2) (set! v1 (vertex-create "Paris")) 
                          (set! v2 (vertex-create "London")))