If you export a "getter" function instead of the list, both modules
have the same behavior:
```
#lang racket/base
(module racket_mod racket
(provide (struct-out s))
(provide get-s)
(provide set-list-of-s!)
(struct s (a))
(define list-of-s '())
(define (get-s) list-of-s)
(define (set-list-of-s! los)
(set! list-of-s los)))
(module racket_mod_typed typed/racket
(provide (struct-out s2))
(provide get-s2)
(provide set-list-of-s2!)
(struct s2 ([a : Natural]))
(define list-of-s2 : (Listof s2) '())
(define (get-s2) : (Listof s2) list-of-s2)
(define (set-list-of-s2! [los : (Listof s2)])
(set! list-of-s2 los)))
(require 'racket_mod)
(require 'racket_mod_typed)
(define los (list (s 1) (s 2)))
(set-list-of-s! los)
(displayln (get-s))
;; (#<s> #<s>)
(define los2 (list (s2 1) (s2 2)))
(set-list-of-s2! los2)
(displayln (get-s2))
;; (#<s2> #<s2>)
```
- - -
The issue in the original code comes from Typed Racket's internals.
When you write `(provide x)` in a TR module, the compiler makes 2
kinds of `x`: a plain `x` for typed clients and a contract-protected
`x` for untyped clients.
```
;; source code
(provide x)
(define x : (Listof s2) '())
```
```
;; complied code, approximately
(provide (rename-out safe-x x))
(define-typed/untyped-identifier safe-x typed-x untyped-x)
(define typed-x : (Listof s2) '())
(define untyped-x (contract (listof s2?) typed-x))
```
The contracts make sure that untyped code respects TR types, and
normally nothing else. But your example shows one way that the current
strategy can end up with different behavior. This is unfortunate, but
I'm not sure how TR could do better ... every new element that gets
added to the list needs protection.
- - -
fwiw, you can also see equal behavior from a typed main module:
```
#lang typed/racket
;; typed_racket_main.rkt
(require/typed "racket_mod.rkt"
(#:struct s ((a : Natural)))
(set-list-of-s! (-> (Listof s) Void))
(list-of-s (Listof s)))
(require "racket_mod_typed.rkt")
(define los (list (s 1) (s 2)))
(set-list-of-s! los)
(displayln list-of-s)
(define los2 (list (s2 1) (s2 2)))
(set-list-of-s2! los2)
(displayln list-of-s2)
```
If you were planning to add types everywhere, then maybe its best to
go ahead with that instead of adding getter functions.