I would like to use Clojure hashmaps to define generalized vectors. In this picture, the hashmap {:x 3 :y 2 :z (- 3)} represents the symbolic expression 3x + 2y - 3z. 

I would like a function gen+ which acts as an addition operation on hashmaps, and which satisfies the following constraints:

* Applying gen+ to two hashmaps with overlapping keys returns a hashmap with those key values summed. e.g.,

`(gen+ {:x 1} {:x 2})`

`;= {:x 3}`

* Applying gen+ to two hashmaps with distinct keys returns a hashmap with those key-values combined. e.g.,

`(gen+ {:x 1} {:y 2})`

`;= {:x 1 :y 2}`

* The empty hashmap {} is an additive identity for the gen+ function. e.g.,

`(gen+ {:x 1} {})`

`:= {:x 1}`

* By the above constraints, any hashmap with zero entries is also an additive identity. For example, {:z 0}. Owing to this redundancy, the gen+ function should always return hashmaps without any 0 values. e.g.,

`(gen+ {:x 1 :y 0} {:z 0})`

`;= {:x 1}`

* Clojure interprets missing keys as having value nil, rather than 0, as with `({:x 3} :y) ;= nil`. Consequently, gen+ should treat nil values the same way as 0. e.g.,

`(gen+ {:x 1 :y 0} {:x nil :y nil})`

`{:x 1}`

* **My Question:** How can we write a function gen+ which satisfies the above constraints? Once this is in place, is it possible to overload the + operator with the gen+ function, enabling elementary addition with hashmaps?

---

It should be apparent why this formalism treats hashmaps as generalized vectors. Clojure interprets a vector like [x0 x1 x2] almost the same as the hashmap {:0 x0 :1 x1 :2 x2}, with a slight difference that I don't quite understand. Consequently, if we apply gen+ to two vectors, then it should be effectively the same as + applied to them. This empowers us to easily work with *sparse* vectors, as well as add vectors of different sizes. e.g.,

`(gen+ [0 0 0 4] [0 0 0 0 0 0 0 0 0 9])`

`;= {:4 4 :9 9}`

Here's what I don't understand about hashmaps and vectors. If I call a hashmap as a function, I need to apply a key argument like :2. On the other hand, if I call a vector as a function, I need to apply an index argument like 2. e.g.,

`({:2 2} :2)`

`;= 2`

`([0 1 2] 2]`

`;= 2`

Even if you can't help with the gen+ function, could you please explain why hashmaps and vectors behave differently when called as functions?