你如何返回Scheme中程序的描述?

时间:2013-12-03 11:11:21

标签: scheme racket

假设我有这样的事情:

(define pair (cons 1 (lambda (x) (* x x))

如果我想返回该对的前方对象,我会这样做:

(car pair)

它返回1.但是当对象是一个过程时,我没有得到它的确切描述。 换句话说:

(cdr pair)

返回#<procedure>而不是(lambda (x) (*x x))

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:6)

虽然通常无法做到这一点,但你可以为你定义的程序安排一些事情。

  1. 球拍struct可以定义prop:procedure,允许将结构应用(调用)作为过程。相同的结构可以包含函数定义的原始语法的副本。这就是sourced结构正在做的事情,如下所示。

  2. write-sourced内容只是为了让输出更清晰(只显示原始的sexpr,而不是其他结构字段)。

  3. define-proc宏使初始化结构更简单 - 您不需要输入两次代码并希望它匹配。它为你做到了这一点。


  4. #lang racket
    
    (require (for-syntax racket/syntax))
    
    ;; Optional: Just for nicer output
    (define (write-sourced x port mode)
      (define f (case mode
                  [(#t) write]
                  [(#f) display]
                  [else pretty-print])) ;nicer than `print` for big sexprs
      (f (sourced-sexpr x) port))
    
    (struct sourced (proc sexpr)
            #:property prop:procedure (struct-field-index proc)
            ;; Optional: Just to make cleaner output
            #:methods gen:custom-write
            [(define write-proc write-sourced)])
    
    ;; A macro to make it easier to use the `sourced` struct
    (define-syntax (define-proc stx)
      (syntax-case stx ()
        [(_ (id arg ...) expr ...)
         #'(define id (sourced (lambda (arg ...) expr ...)
                               '(lambda (arg ...) expr ...)))]))
    
    ;; Example
    (define-proc (foo x)
      (add1 x))
    
    (foo 1) ; => 2
    foo     ; => '(lambda (x) (add1 x))
    

答案 1 :(得分:1)

过程cons评估其参数:1是自我评估为1; (lambda ...)评估匿名过程。如果你想“阻止”评估,你需要quote这个论点:

> (define pair (cons 1 '(lambda (x) (* x x))
> (cdr pair)
(lambda (x) (* x x))