Typed Struct Property: Problem with prop:custom-write

This is probably a question for Suzanne Soy. I tried her struct type properties, but the result is not exactly what I expected.

#lang typed/racket

(: display-point (-> Point Output-Port (U #t #f 0 1) Any))

(define (display-point p o-p opt)
  (display (format "(~a, ~a)" (point-x p) (point-y p))))

(struct point ([x : Number] [y : Number])
  #:type-name Point
  #:transparent
  #:property prop:custom-write display-point
  )

(define p (point 1 2))

My output at the REPL looks like this:

> p
- : Point
(1, 2)(1, 2)
> (display-point p (current-output-port) #t)
(1, 2)- : Any

What, by the way, is the meaning of the third argument for the custom-write?

Hi, @wurmli.

No idea about the type properties, but on the question about custom-write, from the docs:

A write-proc method takes three arguments: the structure to be printed, the target port, and an argument that is #t for write mode, #f for display mode, or 0 or 1 indicating the current quoting depth for print mode. The procedure should print the value to the given port using write, display, print, fprintf, write-special, etc.

Also, do note:

Using the prop:custom-write property is discouraged; use the gen:custom-write generic interface instead.

Thank you!

I tried to follow Suzanne Soy's " Struct type properties for Typed/Racket", but made mistakes. The definitions could look like this

#lang typed/racket

(require typed-struct-props)

(: display-point (-> point Output-Port (U #t #f 0 1) Any))

(define (display-point p o-p opt)
  (case opt
    [(#t) (display (format "(~a, ~a)" (point-x p) (point-y p)))]
    [(#f) (write `(point ,(point-x p) ,(point-y p)))]
    ))

(struct/props point ([x : Number] [y : Number])
  #:transparent
  #:property prop:custom-write display-point
  )

(define p (point 1 2))

but still produce errors:

> p
- : point

> (write p)
(1, 2)(1, 2)
> (display p)
(point 1 2)(point 1 2)

As using "struct/props" instead of "struct" would disallow, for example, #:type-name, it wouldn't serve my purpose anyway. Still, I wonder why the doubling of output happens.

The code needs to write to o-p, not the current output port.

Thank you, that almost works. What is still missing is the printing of a value by the REPL:

#lang typed/racket
 
(require typed-struct-props)
   
(: display-point (-> point Output-Port (U #t #f 0 1) Any))
   
(define (display-point p o-p opt)
  (case opt
    [(#f) (display (format "(~a, ~a)" (point-x p) (point-y p)) o-p)]
    [(#t) (write `(pt ,(point-x p) ,(point-y p)) o-p)]
    ))
   
(struct/props point ([x : Number] [y : Number])
              #:transparent
              #:property prop:custom-write display-point
              )
   
(define p (point 1 2))
> p
- : point

> (write p)
(pt 1 2)
> (display p)
(1, 2)

See @bakgatviooldoos's post and the example code in it:

A write-proc method takes three arguments: the structure to be printed, the target port, and an argument that is #t for write mode, #f for display mode, or 0 or 1 indicating the current quoting depth for print mode.

So case opt has to handle all four of #f, #t, 0, and 1.

Thank you! I think I got it now.

What is described in " Struct type properties for Typed/Racket" seems to be implemented for structs in typed/racket, but not documented, at least it produces identical results.