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

前端 未结 2 1321
时光取名叫无心
时光取名叫无心 2020-12-11 06:28

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:

相关标签:
2条回答
  • 2020-12-11 06:44

    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))
    
    0 讨论(0)
  • 2020-12-11 07:03

    The procedure cons evaluates its arguments: 1 is self-evaluating to 1; (lambda ...) evaluates to an anonymous procedure. If you want to 'prevent' evaluation, you need to quote the argument, as such:

    > (define pair (cons 1 '(lambda (x) (* x x))
    > (cdr pair)
    (lambda (x) (* x x))
    
    0 讨论(0)
提交回复
热议问题