简体   繁体   English

在球拍中实施自己的排序

[英]Implementing own sequencing in racket

I need to implement a function that takes one or more expressions and executes those expressions in order. 我需要实现一个接受一个或多个表达式并按顺序执行这些表达式的函数。

This is what I have so far: 这是我到目前为止的内容:

(define (foo exp0 exp1 ) exp0 exp1)

Assuming you have the following expression 假设您具有以下表达式

(sequence form1 form2 form3)

and you want the forms to be evaluated in order, then you can't pass them to a function as Josuha explained. 并且您希望按顺序评估表单,那么就不能如Josuha所解释的那样将它们传递给函数。 The easiest transformation would be to change the above to 最简单的转换是将以上内容更改为

((lambda () form1 form2 form3))

since the forms in a lambda expression are executed sequentially and the result is the value of the last form. 因为lambda表达式中的表单是顺序执行的,所以结果是最后一个表单的值。 Since this transformation has to be done at the source code level, you have to use a macro such as: 由于此转换必须在源代码级别完成,因此必须使用一个宏,例如:

(define-syntax-rule (sequence form1 form2 ...)
  ((lambda () form1 form2 ...)))

which will transform an expression such as 它将转换一个表达式,例如

(sequence (display "a") (display "b") (display "c"))

into 进入

((lambda () (display "a") (display "b") (display "c")))

which will execute the forms in sequence. 它将按顺序执行表格。

Scheme doesn't specify any particular argument evaluation order. Scheme没有指定任何特定的参数评估顺序。 This means that if you have a display-and-return function: 这意味着如果您具有display-and-return功能:

(define (display-and-return x)
  (display x)
  x)

and you then call, for instance, 然后您打电话给

(list (display-and-return 1) (display-and-return 2))

you're guaranteed to get the result (1 2) , but you could see the output produced by display as either 12 or 21 . 您肯定会得到结果(1 2) ,但是您可能会看到display产生的输出1221 However, Scheme does specify that the arguments to a function will be evaluated before the body of the function is evaluated. 但是,Scheme确实指定了在评估函数主体之前先评估函数的参数。 So, you could sequence two expressions by making them arguments to functions: 因此,您可以通过使两个表达式成为函数的参数来对它们进行排序:

((lambda (val1)
   ((lambda (val2)
      (list val1 val2))
    (display-and-return 2)))
 (display-and-return 1))

In general, you could use a transformation like this to turn (seq exp1 exp2 ... expm expn) into 通常,您可以使用这样的转换将(seq exp1 exp2 ... expm expn)转换为

((lambda (val1)
   ((lambda (val2)
      ...
        ((lambda (valm)
           expn)        ; or ((lambda (valn) valn) expn)
         expm) ... )
    exp2))
 exp1)

You can define that sort of transformation using define-syntax-rule . 您可以使用define-syntax-rule定义这种转换。

You need something that takes 'one or more expressions' and then evaluates them and returns the last one. 您需要使用“一个或多个表达式”,然后对其求值并返回最后一个表达式的东西。 This could be defined with: 可以这样定义:

(define (sequence exp1 . exps)
  (car (reverse (cons exp1 exps))))       ; (if (null? exps) exp1 ...)

You would then invoke it as: 然后,您将其调用为:

> (sequence (+ 1 2) (* 1 2) 17)
17

Using define-syntax stuff isn't needed as standard function application will 'execute those expressions in order' 不需要使用定义语法的东西,因为标准函数应用程序将“按顺序执行那些表达式”

If you need the order to be guaranteed as left-to-right, then you'll need: 如果您需要保证从左到右的订单,则需要:

(define-syntax sequence
  (syntax-rules ()
    ((sequence exp exps ...)
     (begin exp expos ...))))

but if you can't use begin , but can use lambda , then: 但是,如果您不能使用begin ,但是可以使用lambda ,则:

(define-syntax sequence
  (syntax-rules ()
    ((sequence exp exps ...)
     ((lambda () exp exps ...)))))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM