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

rhd*_*rhd 4 scheme racket

假设我有这样的事情:

(define pair (cons 1 (lambda (x) (* x x))
Run Code Online (Sandbox Code Playgroud)

如果我想返回对的前端对象,我这样做:

(car pair)
Run Code Online (Sandbox Code Playgroud)

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

(cdr pair)
Run Code Online (Sandbox Code Playgroud)

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

我该如何解决?

Gre*_*ott 7

虽然通常无法做到这一点,但您可以为您定义的过程进行操作.

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

  2. 这些write-sourced东西只是为了使输出更清晰(只显示原始的sexpr,而不是其他结构域).

  3. define-proc宏可以更容易初始化结构-你不需要两次输入代码,并希望它匹配.它为你做到了这一点.


#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))
Run Code Online (Sandbox Code Playgroud)


GoZ*_*ner 1

该过程cons评估其参数:1 自评估为 1;(lambda ...)评估为匿名过程。如果你想“阻止”评估,你需要quote参数,如下所示:

> (define pair (cons 1 '(lambda (x) (* x x))
> (cdr pair)
(lambda (x) (* x x))
Run Code Online (Sandbox Code Playgroud)