# A new way to type mutable data structures with opposite variance in typed racket

**URL:** <https://racket.discourse.group/t/a-new-way-to-type-mutable-data-structures-with-opposite-variance-in-typed-racket/1846>\
**Category:** Show & Tell\
**Tags:** typed-racket\
**Created:** [March 30, 2023, 5:37am UTC](https://racket.discourse.group/t/a-new-way-to-type-mutable-data-structures-with-opposite-variance-in-typed-racket/1846 "2023-03-30T05:37:12Z")\
**Posts on this page:** 1\
**Showing post:** 7

<div class="post-metadata">

**Author:** ![NoahStoryM](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/noahstorym/32/17_2.png) [@NoahStoryM](https://racket.discourse.group/u/NoahStoryM)\
**Post date:** [November 23, 2024, 5:32pm UTC](https://racket.discourse.group/t/a-new-way-to-type-mutable-data-structures-with-opposite-variance-in-typed-racket/1846/7 "2024-11-23T17:32:43Z")

</div>

After further analysis, it seems the root of this issue lies in how Typed Racket's  
type checker works. When a function is called, the type checker knows the types  
of both the arguments and parameters, so it can verify that the input matches the  
expected type. However, after the function call, the type checker only knows the  
declared return type, not the actual runtime type, since functions are treated as  
"black boxes" in this context.

The `Parameterof` in Typed Racket addresses this issue in two ways:

1. Static Type Enforcement in Typed Modules:  
In a Typed Racket module, `make-parameter` enforces that the "write type" must  
always be a subtype of the "read type":

```scheme
Welcome to Racket v8.15 [cs].
> (: p (Parameter Any Number))
> (define p (make-parameter 'hi))
string:1:10: Type Checker: Polymorphic function `make-parameter' could not be applied to arguments:
Types: a -> (Parameterof a)
       b (-> a b) -> (Parameterof a b)
Arguments: 'hi
Expected result: (Parameterof Any Number)
  in: (make-parameter (quote hi))
 [,bt for context]
> (:print-type make-parameter)
(All (a b) (case-> (-> a (Parameterof a)) (-> b (-> a b) (Parameterof a b))))

```

Here, `make-parameter` ensures that `'hi` cannot be used as an initial value for  
a `(Parameter Any Number)`.

1. Contracts for Untyped Modules:  
For parameters imported from an untyped module, Typed Racket adds a contract to  
enforce the type at runtime. This ensures that any violation of the declared type  
is caught dynamically:

```scheme
> (module m racket/base
    (provide q)
    (define q (make-parameter 'hi)))
> (require/typed 'm
    [q (Parameter Any Number)])
> (q)
q: broke its own contract
  promised: number?
  produced: 'hi
  in: the parameter of
      (parameter/c any/c number?)
  contract from: (interface for q)
  blaming: (interface for q)
   (assuming the contract is correct)
  at: string:2:3
 [,bt for context]
> (q 123)
> (q)
- : Number
123
> (q 'hi)
> (q)
q: broke its own contract
  promised: number?
  produced: 'hi
  in: the parameter of
      (parameter/c any/c number?)
  contract from: (interface for q)
  blaming: (interface for q)
   (assuming the contract is correct)
  at: string:2:3
 [,bt for context]

```

Here, the contract ensures that `'hi` is flagged as invalid because it does not  
conform to the expected `Number` type.

These two mechanisms together ensure that Parameter behaves correctly in both  
typed and mixed-typed contexts.

---

_[View the full topic](https://racket.discourse.group/t/a-new-way-to-type-mutable-data-structures-with-opposite-variance-in-typed-racket/1846)._
