Conversation
Edited 1 month ago

here’s a great example of the problems that I always run into with static typing

so I’m playing with Typed Racket and I have a function called hash-invert which takes a hash table (a dictionary) and returns a version with the keys and values flipped:

(define (hash-invert [h : (HashTable Any Any)]) : (HashTable Any Any)
  (for/hash ([(k v) (in-hash h)])
    (values v k)))

currently I have it annotated as taking a (HashTable Any Any) and returning a (HashTable Any Any) - but that’s not as specific as I’d like it to be. because actually, if K and V are generic types then it takes a (HashTable K V) and returns a (HashTable V K) (it flips the keys and values)

but if I try annotating the function like this, Typed Racket complains because I guess it thinks that the result of (for/hash) must always be a (HashTable Any Any) for some reason?? and I don’t know how to convince it otherwise, or even why it thinks that at all. so if I were using a statically typed language right now, I would be screwed because I wouldn’t have Any to fall back on

1
0
3

@kasdeya I don't know if you were looking for counterexamples generically in statically typed languages or if this was Racket issues specifically (I apologise if it is the latter), but I made this in Haskell (entities surprised by language of choice may raise their hand-purpose-serving appendage of choice).

import Data.Tuple (swap)
import Data.Map (Map)
import qualified Data.Map as M

main :: IO ()
main = print . invertHash $ M.fromList [(18,"foo"),(22,"bar"),(-3,"baz")]

invertHash :: (Ord k, Ord v) => Map k v -> Map v k
invertHash = M.fromList . map swap . M.toList

I'm sure it could be more robust, have less of "make it a list and go back again" and whatnot, but it type checks and makes the String values into the keys and puts the Int keys into the value spot as was desired in your example. Though as per Haskell's constraints for HashMaps, it needs the values to also be of Ord typeclass for the transformation to be viable. Map keys need to be of Ord.

1
0
1

@fargate ooh! I’m glad that there’s a language where this is possible, and in a way that seems simple to me too (at least in terms of the type annotations)

0
0
1