假设我有这样的事情:
(define pair (cons 1 (lambda (x) (* x x))
如果我想返回该对的前方对象,我会这样做:
(car pair)
它返回1.但是当对象是一个过程时,我没有得到它的确切描述。 换句话说:
(cdr pair)
返回#<procedure>
而不是(lambda (x) (*x x))
。
我该如何解决这个问题?
答案 0 :(得分:6)
虽然通常无法做到这一点,但你可以为你定义的程序安排一些事情。
球拍struct
可以定义prop:procedure
,允许将结构应用(调用)作为过程。相同的结构可以包含函数定义的原始语法的副本。这就是sourced
结构正在做的事情,如下所示。
write-sourced
内容只是为了让输出更清晰(只显示原始的sexpr,而不是其他结构字段)。
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))
答案 1 :(得分:1)
过程cons
评估其参数:1是自我评估为1; (lambda ...)
评估匿名过程。如果你想“阻止”评估,你需要quote
这个论点:
> (define pair (cons 1 '(lambda (x) (* x x))
> (cdr pair)
(lambda (x) (* x x))