Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
317 views
in Technique[技术] by (71.8m points)

racket - How do you return the description of a procedure in Scheme?

Suppose I have something like this:

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

If I want to return the front object of the pair I do this:

(car pair)

And it returns 1. However when the object is a procedure I don't get the exact description of it. In other words:

(cdr pair)

returns #<procedure> and not (lambda (x) (*x x)).

How do I fix this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Although there's no way to do this generally, you can rig up something to do it for procedures that you define.

  1. Racket structs can define a prop:procedure that allows the struct to be applied (called) as a procedure. The same struct can hold a copy of your original syntax for the function definition. That's what the sourced struct is doing, below.

  2. The write-sourced stuff is simply to make the output cleaner (show only the original sexpr, not the other struct fields).

  3. The define-proc macro makes it simpler to initialize the struct -- you don't need to type the code twice and hope it matches. It does this for you.


#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))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...