如何返回Scheme中的过程描述?
假设我有这样的东西:如何返回Scheme中的过程描述?,scheme,racket,Scheme,Racket,假设我有这样的东西: (define pair (cons 1 (lambda (x) (* x x)) 如果要返回该对的前对象,请执行以下操作: (car pair) 它返回1。然而,当对象是一个过程时,我没有得到它的确切描述。 换言之: (cdr pair) 返回#而不是(lambda(x)(*x)) 如何解决此问题?过程cons评估其参数:1是自评估为1(lambda…计算为匿名过程。如果要“阻止”求值,则需要引用参数,如下所示: > (define pair (cons 1
(define pair (cons 1 (lambda (x) (* x x))
如果要返回该对的前对象,请执行以下操作:
(car pair)
它返回1。然而,当对象是一个过程时,我没有得到它的确切描述。
换言之:
(cdr pair)
返回#
而不是(lambda(x)(*x))
如何解决此问题?过程
cons
评估其参数:1是自评估为1<代码>(lambda…计算为匿名过程。如果要“阻止”求值,则需要引用参数,如下所示:
> (define pair (cons 1 '(lambda (x) (* x x))
> (cdr pair)
(lambda (x) (* x x))
虽然一般来说没有办法做到这一点,但是您可以为您定义的过程装配一些东西来完成它
struct
s可以定义一个prop:procedure
,允许将该结构作为过程应用(调用)。同一结构可以保存函数定义的原始语法副本。下面的sourceed
struct就是这么做的write-sourceed
只是为了使输出更清晰(只显示原始的sexpr,而不显示其他结构字段)define proc
宏使初始化结构变得更简单——您不需要键入两次代码并希望它匹配。这是为你做的您想这样做有什么特别的原因吗?或者只是出于好奇?我想确认这是不可能的,因为
lambda
表达式已经编译,并且源代码没有与编译后的代码一起存储。您可能会发现使用racket/decompiler
的方法很复杂,但我也想知道您为什么需要这样做(pp(cdr对))-->(lambda(x)(*x))至少在mit方案中是这样。不知道球拍。可能是重复的
#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))