Scheme(Pretty Big):使用列表定义参数

时间:2013-02-11 23:42:58

标签: functional-programming scheme variadic-functions

所以我是Scheme的新手。我正在尝试使用表单的规范((name:name)(args:args)(body:body))来创建一个定义全局函数的函数,例如

    (fn-maker '((name: mult5) (x) (* x 5)))

会全球化,我可以打电话给

    (mult5 3)

并获得15。

这是我到目前为止所拥有的:

    (define (fn-maker fn-spec)
        (let* (spec (map cdr fn-spec))
              (name (caar spec))
              (args (cadr fn-spec))
              (body (caaddr (cdaddr fn-spec))))
        (lambda (args)
          body)))

目前我最担心的是如何让lambda使用那些args。就目前而言,lambda创建了一个名为“args”的新局部变量,而不是评估args背后的列表。有没有解决的办法?我目前的思考过程是我应该在args提供的列表中使用某种形式,但我不确定它会是什么样的,甚至不知道如何构建它。

这是作业,所以我绝对不是在寻找代码(欺骗和所有这些),而是在正确的方向和一些批评中找到一点。谢谢。

更新:对于将来发生这种情况的任何人,可以使用一些聪明的引用非常简单地执行此代码。不需要宏。另外,事实证明,Pretty Big中的eval默认情况下会在全局范围内进行评估。

2 个答案:

答案 0 :(得分:1)

有一个名为eval的Scheme过程可用于评估您构造的任意源代码。

通常不鼓励使用它(就像在JavascriptRuby中一样),因为很多时候使用它,当有更强大的替代品可用时,它被用作不安全的捷径。 (一个简单的例子是当有人可能使用(eval name)查找与全局环境中的符号相关联的值时,其中name是从一组预定符号中提取的;在这种情况下,构造通常是更好的样式一个单独的查找表,包含所有感兴趣的符号,而不是为此目的破坏全局环境。

无论如何,在一些 Scheme系统中,eval可用于将新定义注入全局环境。我必须添加限定符“some”,因为在R5RS中,eval过程同时使用表达式和环境来评估该表达式,并且不需要实现来提供交互式全局环境这个目的。 (即interaction-environment可选程序。)

以下是eval 提供时通过interaction-environment注入全局变量的说明:

(define (make-it-three name) (eval (list 'define name '3) (interaction-environment)))

;; At the REPL now

> (make-it-three 'x)

> x
3

> (map make-it-three '(a b c))
(#!unspecified #!unspecified #!unspecified)

> (+ a b c)
9

Racket(我认为也是Pretty Big)中,他们没有提供interaction-environment。但我认为有一个不同的程序可以用来实现这个目标;检查文档。

无论如何,这只是一种尝试在一种策略上提供一个小注释的方式,可能会或可能不会引导您朝着正确的方向前进。强调“可能没有。”

答案 1 :(得分:0)

您需要一种方法来“导出”在过程中创建的函数定义,以使定义存在于全局环境之外。到目前为止,您的实现只会返回lambda表单。提示:有一种方法可以做到这一点(我记得在Racket中看过它),但它可能是特定于使用的Scheme解释器;我不确定它是否以Pretty Big语言提供。

作为旁注 - 如果fn-spec参数将接收带有新函数名称和正文的列表,那么请确保只传递一个参数在致电fn-maker时,会发生以下情况:

(fn-maker '((name: mult5) (x) (* x 5)))

另外,考虑使用宏而不是普通的程序......

相关问题