anchor.diff:  ** ds/name
   ** ds/id
   ****
  -
  -=== constructors
  -
  -We have three ways to construct PersistentEntityMap objects:
  -
  -* local constructor:  `(entity-map <keychain> <map>)`
  -* push constructor:   `(entity-map! <keychain> <map>)` - construct locally and push to datastore
  -* pull constructor:   `(entity-map* <keychain> <map>)` - pull matching entities from datastore and construct corresponding PersistentEntityMap objects locally
  -
  -Push: by default the push ctor `entity-map!` first checks to see if an entity with that key already exists, and throws an exception if so; otherwise it constructs the PersistentEntityMap and saves the underlying Entity to the datastore.  This default behavior can be overriden by using the `:force` key, which will make the ctor save the construction absolutely, thus overwriting anything that might have previously been stored with that key.
  -
  -[[app-listing]]
  -[source,clojure]
  -----
  -(entity-map! [:A/B] {:a 1 :b 2})        ;; std local ctor expression
  -(entity-map! [:A/B C/D] {:a 1 :b 2})    ;; ditto
  -(entity-map! [:A] {:a 1 :b 2})          ;; kinded ctor (see below)
  -(entity-map! [:A/B :C] {:a 1 :b 2})          ;; kinded ctor (see below)
  -(entity-map! :force [:A/B] {:a 9 :b 10}) ;; force replacement
  -----
  -==== [[reader]] reader syntax
  -
  -tagged literals?  I can never manage to get them to work, but maybe:
  -
  -[[app-listing]]
  -[source,clojure]
  -----
  -#entity-map [[:A/B] {:a 1}]
  -#emap [[:A/B] {:a 1}]
  -----
  -
  -=== co-constructors (aka eliminators)
  -
  -Constructors and co-constructors must "harmonize":
  -
  -[[app-listing]]
  -[source,clojure]
  -----
  -(is (= (ds/keychain (ds/entity-map k m)) k))
  -(is (= (ds/entity-map (ds/keychain (ds/entity-map k m)) m)))
  -----
  -
  -== [[[axioms]]structural axioms
  -
  -[[app-listing]]
  -[source,clojure]
  -----
  -(def em (entity-map [:A/B C/D] {:a 1 :b 2}))
  -(coll? em)
  -(map? em)
  -(entity-map? em)
  -(= (key  em) [:A/B :C/D])
  -(= (val  em) {:a 1 :b 2})
  -(= (keys em) [:a :b])
  -(= (vals em) [1 2])
  -(= (:a (into em {:a 3}) (:a em)))
  -----
  -etc.  More to come.
  -
  -
  -== [[keys]] keys, keychains, keylinks, and dogtags
  -
  -A keylink is a namespaced keyword, e.g. `:Foo/Bar`.  A vector of
  -keylinks is a keychain, which corresponds to a datastore Key, which
  -has a Kind of type String, an Identifier (either a String name or a
  -long Id), and (optionally) a parent Key.  See
  -link:doc/Keychains.adoc[Keychains] for more detail.
  -
  -**_Caveat_**: note the difference between a datastore Key and a
  -  clojure key.  The former is a type (class), the latter is a
  -  structural role (first element of a mapentry).
  -
  -A proper keychain is a vector of namespaced keywords.  To use numeric
  -Ids, include a notational prefix, 'd' for decimal and 'x' for
  -hexadecimal.  E.g. `[:Foo/d11]` or `[:Foo/x0B]`.
  -
  -The last link in the chain is the _dogtag_, so named because it serves
  -as a (quasi-) identifier for its entity-map.  A dogtag is just a
  -Clojure keyword with namespace (e.g. :A/B); it corresponds to the
  -datastore Key of the underlying datastore Entity.  The Key of an
  -Entity does identify it, because it contains a link to its parent
  -key; but a dogtag does not completely identify its entity-map, since
  -it contains no link to its predecessor.  In migae, the "key" of an
  -entity-map is the entire keychain.  However, the kind and identifier
  -(name or id) of the dogtag do characterize the entity-map.
  -
  -Note that a dogtag predicate `(dogtag? x)` doesn't make sense - it's
  -not a type.  What makes a keyword a dogtag is its position in a
  -keychain.
  -
  -[source,clojure]
  -----
  -user=> (ds/to-ekey :A/b)  ; migae keylink to datastore entity Key (ekey)
  -#object[com.google.appengine.api.datastore.Key 0x6c4f881d "A(\"b\")"]
  -(ds/ekey? (ds/to-ekey :A/B))
  -(= (ds/dogtag [:A/B]) (ds/dogtag [:X/Y :A/B])) ;; dogtag is last link in chain :A/B
  -(= (ds/keychain (ds/to-ekey :A/B)) [:A/B])
  -(= (ds/kind [:A/B]) (ds/kind [:X/Y :A/B]))
  -(= (ds/name e1) (ds/name e2) (ds/name e3))
  -----
  -
  -== [[kinds]] kinds
  -
  -In the datastore, every Entity has a "Kind", which is a string.  A
  -Kind is effectively a tag that you attach to an Entity in order to
  -categorize it; a Kind is not a class.  Two objects of the same Kind
  -may have absolutely nothing in common except for their Kind.
  -
  -The datastore supports what I'm calling "kinded construction": you
  -specify a Kind in your constructor, and the datastore autogens an Id.
  -You can also retrieve entities by Kind; querying for Kind "Foo" will
  -return all Entities of Kind "Foo".  You can narrow this by specifying
  -an "ancestor key", so only kinded Entities having that key as parent
  -will be fetched.
  -
  -The migae api makes both of these operations simple and transparent.
  -To do a kinded construction, just use an improper keychain with the
  -push constructor, like so: `(entity-map! [:A] {:a 1})`; to fetch
  -Entities by kind, do the same with the pull constructor: `(entity-map*
  -[:A])`.  Kinded construction is not supported for the local
  -constructor (`entity-map`); the datastore can only generate Ids for
  -stored entities.
  -
  -[source,clojure]
  -----
  -(= (kind (entity-map [:Foo/Bar] {:a 1})) :Foo)
  -(= (kind (entity-map [:Foo/Bar :X/d3] {:a 1})) :X)
  -----
  -
  -== [[autogen]] autogenned ids
  -
  -Use a partial ("improper") keychain to have the datastore autogen Id
  -values.  All but the last links in the vector must be namespaced;
  -e.g. `[:A/B :C/D :E]`.  Only valid for push ctor, since the datastore
  -can only autogen an Id on saved entities.
  -
  -[source,clojure]
  -----
  -(def em1 (entity-map! [:Foo] m)) ;; kind="Foo", id is autogenned.
  -(def em2 (entity-map! [:Foo] m)) ;; em1 and em2 have different key ids
  -(def em2 (entity-map! [:A/B :C/D Foo] m)) ;; long keychains ok too
  -----
   
   == [[fields]] field types
   
  
positive.code:      (= (ds/kind k) (keyword (.getKind k))))
  ----
  
  .TODO: documentation
  ****
  *Key interface:*
  
negative.code: * <<testing,testing>>
  * <<types,types>>
  * <<ctors,constructors and co-constructors>>
  * <<axioms,structural axioms>>
  * <<keys,Keys, keychains, keylinks, dogtags>>
  * <<kinds,kinds>>
  * <<autogen,autogenned ids>>
  