我有一个由这个方法定义的文字:
(define right-hand-rule-prg
'(
(procedure start
( turn-right
(if wall?
( turn-left
(if wall?
(turn-left
(if wall?
turn-left
step
)
)
step
)
)
step
)
put-mark
start
)
)
(procedure turn-right (turn-left turn-left turn-left turn-left turn-left))
)
)
我必须解析并定义过程start
和turn-right
。
我设法通过名称使用此方法获取过程:
(define (get-procedure procedure program)
(if (null? program)
'(procedure-not-found)
(if (eq? procedure (cadar program))
(caddar program)
(get-procedure procedure (cdr program))
)
)
)
所以在打电话后我得到了:
(get-procedure 'turn-right right-hand-rule-prg)
'(turn-left turn-left turn-left turn-left turn-left)
但不知何故,我必须设法找到所有程序名称并定义此程序,如下所示:
(define (name-of-procedure) (get-procedure name-of-procedure-program))
我该怎么做?
答案 0 :(得分:2)
我不确定我理解动机/背景,你在这里想做什么。但是你所勾勒出来的东西似乎“正在削减粮食”。
在Scheme和Racket中,函数是一流的对象 - 您可以将它们放在列表中,传递它们,等等。它会更简单,并且“用粒度切割”来翻转它:像往常一样定义函数,并使right-hand-rule-prg
成为函数的list
。
(define (turn-left)
...)
(define (turn-right)
...)
(define (start)
...)
(define right-hand-rule-prg
(list start turn-right))
要执行right-hand-rule-prg
,您可以执行以下操作来运行列表中的过程:
(for ([f (in-list right-hand-rule-prg)])
(f))
请注意right-hand-rule-prg
之类的内容是list
,可以在运行时构建或修改。所以你可以让...用户修改它,或从文件中读取它。然而,构建块 - 像start
和turn-right
这样的原语 - 通常是定义的函数。
如果真正需要在运行时定义基元,那么可以在用户提供的s-expression上使用eval
。但这是最不可取的选择。您应该尽量避免使用eval
。如果您希望用户在运行时提供任意Racket功能,最好使用dynamic-require
之类的功能。或者更好的是,反转控件 - 您的代码是用户程序的库(而不是您在运行时使用用户代码的代码)。