in-nest-sequence是一个序列生成器,它接受函数和初始值,调用当前值的返回值被用作后续值。例如,(in-nest-sequence add1 0)返回序列(0 1 2 3 4 ...)。
最近,苏加德要求我编写define-sequence-syntax版本的in-nest-sequence,即基于宏的版本。我决定试一试
#lang racket
(require (for-syntax unstable/syntax))
(provide (rename-out [*in-nest-sequence in-nest-sequence]))
(define in-nest-sequence
(case-lambda
[(func init)
(make-do-sequence
(thunk (values identity func init #f #f #f)))]
[(func . inits)
(make-do-sequence
(thunk (values (curry apply values)
(lambda (args)
(call-with-values (thunk (apply func args)) list))
inits #f #f #f)))]))
(define-sequence-syntax *in-nest-sequence
(lambda () #'in-nest-sequence)
(lambda (stx)
(syntax-case stx ()
[[(x ...) (_ func init ...)]
(unless (= (syntax-length #'(x ...)) (syntax-length #'(init ...)))
(raise-syntax-error 'in-nest-sequence
(format "~a values required" (syntax-length #'(x ...)))
stx #'(init ...)))
(with-syntax ([for-arity (syntax-length #'(init ...))]
[(value ...) (generate-temporaries #'(init ...))]
[(y ...) (generate-temporaries #'(init ...))])
#'[(x ...) (:do-in ([(f) func])
(unless (procedure-arity-includes? f for-arity)
(raise-arity-error f (procedure-arity f) init ...))
([value init] ...)
#t
([(x ...) (values value ...)]
[(y ...) (f value ...)])
#t
#t
(y ...))])])))我是一个使用define-sequence-syntax的新手,所以我欣赏所有关于我的代码的风格、性能和/或一般反馈。(有关一些用法示例,请参见原来的职位。)
发布于 2015-10-07 12:24:15
对于用户遵循语法和函数返回并接收正确数量的值的情况,这很好。
尽早发现错误是一个很好的原则。
考虑一下这个例子:
(in-iterate add1)
在这里,用户提供一个函数add1,该函数具有1,但不提供任何参数。这最终会导致“结果不匹配;”错误,当add1。在早期使用procedure-arity检查是否提供了足够的init值时,可以捕获此错误。提供给用户的错误消息可以是“预期的1初始值,但接收到0”。
在*in-iterate中考虑:[(x ...) (_ func init ...)]。在这里,绑定标识符( xs)的数量必须与init表达式的数目相同。如果它们不是,则可以使用以raise-syntax-error作为错误源的stx。
一个应该是语法错误(而不是运行时错误)的示例:
(define (add1/2 x y) (values (+ x 1) (+ y 2)))
(for/list ([n 10]
[(x y) (in-iterate add1/2 0)])
(list x y))构造的名称有点偏离。在in-list和in-sequence中,我们有模式in-noun,因此表明in-iteration可能更好。然而,iteration有点模糊。也许一个in-nested-sequence或in-nest-sequence是基于Mathematica?http://reference.wolfram.com/language/ref/NestList.html中的名称的。
https://codereview.stackexchange.com/questions/106806
复制相似问题