正态订单与方案中的应用订单程序

时间:2015-04-15 17:44:16

标签: scheme racket

让我们说我想知道计划/球拍中的口译员是否处于正常顺序或应用顺序。

(define normal?
  (lambda()
    (let ((e (display 'not-)))
      (display 'normal))))

这将按照正常顺序打印正常而不是正常的应用顺序,但是我可以编写一个程序来执行相同的应用程序顺序(意味着在应用程序中显示应用程序并且在正常顺序上显示不适用)?

我的想法是不可能的,因为如果申请订单程序终止,则必须返回与正常订单相同的结果。

2 个答案:

答案 0 :(得分:1)

为什么,这是基本的变异,亲爱的沃森:

(define applicative?
  (lambda ()
   (let ((test #t))
    (let ((e (begin (set! test #f) #f)))
      (if test (display 'normal) (display 'applicative))))))

你没有禁止突变,对吗?但如果你坚持,请使用call/cc仓促退出:

(define applicative?
  (lambda ()
   (call/cc (lambda (exit)
    (let ((e (begin (display 'applicative) (exit #f))))
      (display 'not-applicative))))))

现在你看到Scheme不是lambda演算。

这是第三个解决方案。定义display1仅在第一次调用时打印其参数,并且不对任何后续调用执行任何操作,然后使用

(define applicative?
  (lambda()
    (let ((e (display1 'applicative)))
      (display1 'not-applicative))))

就像你在代码中使用副作用原语一样,我也是如此! :)

答案 1 :(得分:1)

基础分析

适用和正常顺序之间的一个可观察的区别是逻辑dead code路径的行为,其中包含引发错误/异常的过程。

实施

#lang racket中,我们可以使用arity = 2的本地函数foo编写一个简单的测试套件。第一个参数在foo内生效,第二个参数是死的。然后我们传递一个值[`(/ 1 0)],当在死代码路径下进行求值时会引发异常。

将它全部包含在测试框架中让我们养成了良好的习惯:

#lang racket/base

(require rackunit
         rackunit/text-ui
         racket/function)

(define evaluation-order

  (let ((foo (lambda (x y) x)))

    (test-suite
     "Test the evaluation order."

     (test-exn  
       "Applicative Order Test"
        exn:fail?
       (thunk (foo (+ 1 0)
                   (/ 1 0))))

     (test-not-exn
       "Normal Order Test"
       (thunk (foo (+ 1 0)
                   (/ 1 0)))))))

(run-tests evaluation-order)

样本输出

racket@29657169.rkt> ,enter "/media/ben/Data/Programming/StackOverflow/29657169.rkt"
--------------------
Test the evaluation order. > Normal Order Test
Normal Order Test
FAILURE
name:       check-not-exn
location:   /media/ben/Data/Programming/StackOverflow/29657169.rkt:19:5
params:     #<procedure:temp5>
message:    "Exception raised"
exception-me"/: division by zero"
exception:  #(struct:exn:fail:contract:divide-by-zero "/: division by zero" #<continuation-mark-set>)
Check failure
--------------------
1 success(es) 1 failure(s) 0 error(s) 2 test(s) run
1