Skip to content
Matúš Láslofi edited this page Mar 16, 2015 · 3 revisions

Problem

HMaps do not integrate well with the core clojure.lang.* persistent map classes. HMaps are arbitrarily an APersistentMap just to make them more useful.

They should work with any subtype of IPersistentMap and facilitate downcasts to more specific map classes.

Solution

One idea is to follow intersection types reminiscent of Forsythe's.

We would have several special type constructors that can wrap a class (or other specials).

eg. (Key (IPersistentMap Any Any) ':a Number) is an IPersistentMap with an :a entry. eg. (NoKey (IPersistentMap Any Any) ':b) is an IPersistentMap without a :b entry.

How to handle complete/partial maps?

By utilising type variable bounds, we can assert that the first argument to Key is always an IPersistentMap.

eg. (All [ [x :< (IPersistentMap Any Any)] ] (Key x ':a Number))

By combining these special types we can build up expressive HMaps. Order matters!

eg. (Key (Key (IPM Any Any) ':a Number) ':b Number) would be similar to (HMap {:a Number :b Number}) eg. (NoKey (Key (IPM Any Any) ':a Number) ':a) is equivalent to (NoKey (IPM Any Any) ':a)

Clone this wiki locally