# Typed Struct Property: Problem with prop:custom-write

**URL:** <https://racket.discourse.group/t/typed-struct-property-problem-with-prop-custom-write/3419>\
**Category:** Questions & Answers\
**Tags:** typed-racket\
**Created:** [December 15, 2024, 10:48am UTC](https://racket.discourse.group/t/typed-struct-property-problem-with-prop-custom-write/3419 "2024-12-15T10:48:23Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![wurmli](https://avatars.discourse-cdn.com/v4/letter/w/dbc845/32.png) [@wurmli](https://racket.discourse.group/u/wurmli)\
**Post date:** [December 15, 2024, 10:48am UTC](https://racket.discourse.group/t/typed-struct-property-problem-with-prop-custom-write/3419/1 "2024-12-15T10:48:23Z")

</div>

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

```racket
#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:

```scheme
> 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`?

---

<div class="post-metadata">

**Author:** ![bakgatviooldoos](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/bakgatviooldoos/32/1381_2.png) [@bakgatviooldoos](https://racket.discourse.group/u/bakgatviooldoos)\
**Post date:** [December 15, 2024, 11:07am UTC](https://racket.discourse.group/t/typed-struct-property-problem-with-prop-custom-write/3419/2 "2024-12-15T11:07:16Z")

</div>

Hi, @wurmli.

No idea about the type properties, but on the question about `custom-write`, from [the docs](https://docs.racket-lang.org/reference/Printer_Extension.html#(part._.Printer_.Extension)):

> 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.

---

<div class="post-metadata">

**Author:** ![wurmli](https://avatars.discourse-cdn.com/v4/letter/w/dbc845/32.png) [@wurmli](https://racket.discourse.group/u/wurmli)\
**Post date:** [December 16, 2024, 5:34am UTC](https://racket.discourse.group/t/typed-struct-property-problem-with-prop-custom-write/3419/3 "2024-12-16T05:34:37Z")

</div>

Thank you!

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

```racket
#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:

```scheme
> 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.

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [December 16, 2024, 7:00am UTC](https://racket.discourse.group/t/typed-struct-property-problem-with-prop-custom-write/3419/4 "2024-12-16T07:00:26Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![wurmli](https://avatars.discourse-cdn.com/v4/letter/w/dbc845/32.png) [@wurmli](https://racket.discourse.group/u/wurmli)\
**Post date:** [December 16, 2024, 8:10am UTC](https://racket.discourse.group/t/typed-struct-property-problem-with-prop-custom-write/3419/5 "2024-12-16T08:10:25Z")

</div>

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

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

```

```scheme
> p
- : point

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

```

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [December 16, 2024, 8:32am UTC](https://racket.discourse.group/t/typed-struct-property-problem-with-prop-custom-write/3419/6 "2024-12-16T08:32:15Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![wurmli](https://avatars.discourse-cdn.com/v4/letter/w/dbc845/32.png) [@wurmli](https://racket.discourse.group/u/wurmli)\
**Post date:** [December 16, 2024, 12:01pm UTC](https://racket.discourse.group/t/typed-struct-property-problem-with-prop-custom-write/3419/7 "2024-12-16T12:01:38Z")

</div>

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.
