Scheme 如何在Racket中自定义程序的打印?

Scheme 如何在Racket中自定义程序的打印?,scheme,racket,Scheme,Racket,假设我使用以下过程来实现一个基本类: ;;; Constructor. (define (make-pos x y) (lambda (msg) (cond [(eq? msg 'get-x) x] [(eq? msg 'get-y) y] [(eq? msg 'set-x) (lambda (v) (set! x v))] [(eq? msg 'set-y) (lambda (v) (set! y v))]

假设我使用以下过程来实现一个基本类:

;;; Constructor.
(define (make-pos x y)
  (lambda (msg)
    (cond [(eq? msg 'get-x) x]
          [(eq? msg 'get-y) y]
          [(eq? msg 'set-x) (lambda (v) (set! x v))]
          [(eq? msg 'set-y) (lambda (v) (set! y v))]
          [else (error "POS invalid msg" msg)])))

;;; Getters and setters.
(define (pos-x pos) (pos 'get-x))
(define (pos-y pos) (pos 'get-y))
(define (set-pos-x! pos x) ((pos 'set-x) x))
(define (set-pos-y! pos y) ((pos 'set-y) y))
我知道球拍有一个物体系统,但我做这个只是为了教育目的。我的问题是:如何自定义过程的打印/显示?例如:

(define mypos (make-pos 1 2))
(displayln mypos)
这会显示类似于
#
的内容,这并不理想。有没有办法自定义输出

编辑:我想
(displayln mypos)
显示
(POS(x1)(y2))

有三种方法:

  • 静态命名lambda
  • 动态命名过程
  • 使用
    prop:procedure
  • 方法(1)非常有限,您可以通过命名lambda将
    #
    更改为
    #

    (定义我的常量名称
    (兰姆达(味精)…)
    我不变的名字
    ; #
    
    方法(2)使用
    procedure rename
    可以动态更改名称,但不允许删除
    部分:

    (procedure-rename
     (lambda (msg) ....)
     'my-new-name)
    ; #<procedure:my-new-name>
    
    如果要显示lambda的s表达式表示,可以执行以下操作:

    (结构程序/sexpr[proc sexpr]
    #:属性属性:过程(结构字段索引过程)
    #:方法gen:自定义写入
    [(定义(写入过程自输出模式)
    (写(proc/sexpr sexpr sexpr self)out)))
    (定义简单宏(lam stuff…)
    (程序/sexpr(lambda stuff…)(lam stuff…)
    (林(味精)…)
    ; (林(味精)…)
    
    更新:显示
    (位置(x1)(y2))
    使用方法(3)和
    proc/get-sexpr
    struct(与上面的
    proc/sexpr
    struct类似,但有一个额外的lambda),您可以让它显示为
    (POS(x1)(y2))
    ,如下所示:

    (struct proc/get sexpr[proc get sexpr]
    #:属性属性:过程(结构字段索引过程)
    #:方法gen:自定义写入
    [(定义(写入过程自输出模式)
    (写入((proc/get sexpr get sexpr self))out])
    (确定位置x和y)
    (proc/get sexpr)
    (兰姆达(味精)
    (条件[(等式?msg'get-x)x]
    [(eq?msg'get-y)y]
    [(等式?msg'set-x)(λ(v)(set!x v))]
    [(等式?msg'set-y)(lambda(v)(set!y v))]
    [其他(错误“POS无效消息”消息)])
    (lambda()`(POS(x,x)(y,y)()))
    ;;; 能手和二传手。
    (定义(pos-x pos)(pos'get-x))
    (定义(pos-y pos)(pos'get-y))
    (定义(位置集合x!位置x)((位置集合x)x))
    (定义(集合位置y!集合位置y)((集合位置y)y))
    
    使用该函数,调用
    (make pos 1 2)
    生成一个值,该值显示为
    (pos(x 1)(y 2))

    >(定义x(制作位置1和位置2))
    >x
    (职位(x1)(y2))
    >((x'组-x)10)
    >x
    (职位(x10)(y2))
    
    那么,您希望它如何显示?如果你想看lambda的尸体,请看谢谢你的回答。我已编辑了问题,以显示我希望如何显示
    mypos
    。我不明白方法(3)。你能用我编辑中的信息提供一个具体的例子吗?好的。我已经更新了我的答案,以显示如何将其显示为
    (POS(x1)(y2))
    ,尽管我认为它在突变后不会更新…好的,我已经修复了它,因此它现在可以与突变一起工作。