Scheme / Drracket,避免使用let,仍然没有两次评估相同的功能

时间:2016-12-01 19:05:00

标签: lambda scheme racket let

我有一个我无法解决的编码类作业:(

(define f
  (lambda (x)
    (i (g x) (h (g x)))))

i,g和h只是任意函数名称。 这是代码,我需要重写它,以便(g x)仅评估一次但不使用let(或其任何变体)仅使用definelambda作为预定义函数。我也不被允许从f中进行计算,也就是说,所有计算必须在该函数内部进行。

2 个答案:

答案 0 :(得分:2)

简单的方法是

(define f
  (lambda (x)
    (define intermediary (g x))
    (i intermediary (h intermediary))))

,更复杂的是

(define f
  (lambda (x)
    ((lambda (intermediary) ; anonymous procedure
       (i intermediary (h intermediary)))
     (g x))))

或者,避免使用匿名程序并将其命名为 sub

(define f
  (lambda (x)
    (define sub
      (lambda (intermediary)
       (i intermediary (h intermediary))))
    (sub (g x))))

答案 1 :(得分:2)

有趣的是,在letdefine允许的情况下,您不允许使用lambda的任何变体,我当然会说这是let的真实变体(或反之亦然。)

(let ((v1 expr1) ...)
  body ...)

相同
((lambda (v1 ...)
   body ...) expr1 ...)

所以letlambda的变体。因此:

(define f
  (lambda (x)
    (let ((gx (g x)))
      (i gx (h gx)))))

当然可以改写为:

(define f
  (lambda (x)
    ((lambda (gx)
       (i gx (h gx)))
     (g x))))

现在想象一下,在(define f ..)之前我们定义了其他的freee变量。这可以改写为:

((lambda (i)
   ((lambda (h)
      ((lambda (g)
         ((lambda (f)
            rest-of-program ...)
          (lambda (x)
            ((lambda (gx)
               (i gx (h gx)))
             (g x)))))
       (lambda (v) g-expression)))
    (lambda (v) h-expression)))
 (lambda (v1 v2) i-expression))

如果其中一个绑定变量实际上需要在其闭包中进一步使用绑定变量,那么真正的扩展可能会稍微复杂一些,但对于基元来说,它可以工作。