#lang scheme/base ;; This module provides a lambda-like expression form whose values have an ;; accessible external representation. (require (for-syntax scheme/base)) ;; printable-lambda: SYNTAX ;; printable-lambda-rep: lambda/rep -> s-expression (provide printable-lambda (rename-out (lambda/rep-rep printable-lambda-rep))) ;; A lambda/rep is a ;; (make-lambda/rep a-proc a-rep) ;; where a-proc is a procedure, and a-rep is an s-expression. (define-struct lambda/rep (proc rep) #:property prop:procedure (struct-field-index proc) #:property prop:custom-write (lambda (l/rep output-port write?) (let ([printer-f (cond [write? write] [else display])]) (printer-f (lambda/rep-rep l/rep) output-port)))) ;; To make it fairly transparent to use, we provide a special form that ;; looks just like lambda. (define-syntax (printable-lambda stx) (syntax-case stx () [(_ args body ...) (syntax/loc stx (make-lambda/rep (lambda args body ...) '(printable-lambda args body ...)))])) ;; Example code (define (example) (define square (printable-lambda (x) (* x x))) (printf "behaves like a procedure: ~a~n" (square 42)) (display square) (newline) (write square) (newline))