Thanks Alexis, I now see why the subtyping doesn't work and why mutability
is the issue. So when using mutable data structures, I really have to use
the largest possible type everywhere or add annotations or similar - making
types on immutable data more flexible. That's interesting.

Thanks for pointing out the REPL tools for looking at types Ben, I'll check
those out.

I've now worked around having to put annotations everywhere by making some
custom constructors with type signatures. That obviously requires direct
annotations still, but at least my code isn't sprinkled with `(ann
(make-hash ...) DB)` anymore, instead it has `(make-db ...)`.

Maybe I missed this (subtle, to me) point in the documentation, but somehow
highlighting the issue of mutability and subtyping may be worth it. In
https://docs.racket-lang.org/ts-guide/more.html, the docs mention the need
to annotate mutable data, but this seems somewhat different from the "It's
mutable, so you need to annotate", especially as the problem was lack of
precision, rather than overly conservative type inference. I would suggest
adding it as a point 5, or a variation of point 4, using Alexis' example
with `(f v)` as to why it fails.

Cheers,
Marc

On Wed, Nov 6, 2019 at 2:05 PM Ben Greenman <benjaminlgreen...@gmail.com>
wrote:

> On 11/6/19, Marc Kaufmann <marc.kaufman...@gmail.com> wrote:
> > I assumed it was something to do with mutability, but I don't understand
> > what you mean when you say there is a two-way channel. The reference in
> > typed racket (
> >
> https://docs.racket-lang.org/ts-reference/type-ref.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types..rkt%29._.Hash.Table%29%29
> )
> > says this:
> >
> > ```
> >
> > (HashTable
> > <
> https://docs.racket-lang.org/ts-reference/type-ref.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types..rkt%29._.Hash.Table%29%29
> >
> >  k v)
> >
> > is the type of a mutable or immutable hash table
> > <
> https://docs.racket-lang.org/reference/hashtables.html#%28tech._hash._table%29
> >
> > with key type k and value type v.
> > Example:
> >
> >> (make-hash
> > <
> https://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28quote._~23~25kernel%29._make-hash%29%29
> >
> >  '((a . 1) (b . 2)))
> >
> > - : (HashTable Symbol Integer) [more precisely: (Mutable-HashTable Symbol
> > Integer)]
> >
> > '#hash((a . 1) (b . 2))
> >
> > ```
> >
> > That suggests to me that HashTable includes both Mutatable-HashTable and
> > Immutable-HashTable. The example given even states that the HashTable
> > Symbol Integer is more precisely of Mutable-HashTable Symbol Integer
> type -
> > does that *not* mean that (Mutable-HashTable Symbol Integer) is a subtype
> > of (HashTable Symbol Integer) in the reference example?
>
> Right --- (Mutable-HashTable Symbol Integer) is a subtype of
> (HashTable Symbol Integer).
>
> > I now tried to redefine DB as Mutable-HashTable to avoid this issue, but
> > that doesn't work either. It still doesn't accept `(make-hash (list (cons
> > 'study-type study-type)))` as something of type DB. How is
> > (Mutable-HashTable Symbol Symbol) not a subtype of DB, which is
> > (Mutable-HashTable DBKey (U DB DBValue)), and DBKey is (U Symbol ...
> ;other
> > stuff) and same for DBValue?
>
> See Alexis's reply.
>
> For a small example,  (Mutable-HashTable Symbol Symbol) is NOT a
> subtype of (Mutable-HashTable Symbol (U Symbol String))
>
> ```
> #lang typed/racket/base
>
> (define-type (M-HT A B) (Mutable-HashTable A B))
>
> (define (f (x : (M-HT Symbol (U Symbol String))))
>   (void))
>
> (define h : (M-HT Symbol Symbol)
>   (make-hash '((A . X))))
>
> (f h) ;; type error
> ```
>
> > You wrote that make-hash is of type `(Listof (Pairof Symbol Symbol))`. Is
> > there a way to expand and print the type of something in terms of
> primitive
> > types (well, or maybe step through one layer of abstraction) so that I
> > could play around with some toy examples to get a sense of what types are
> > returned? I am clearly confused by what type `make-hash` returns and what
> > `hash-ref` expects.
>
> The blue boxes in Dr. Racket might help. There are also a few tools
> for looking at types in the REPL:
>
> https://docs.racket-lang.org/ts-reference/Exploring_Types.html
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO7MNPVctku-mZQddNO5PXEwy1Wv6CDL4vxVZ3iQMoQ%3Dtw%40mail.gmail.com.

Reply via email to