Update change in coercion moving @coerce into separate properties of an expanded term definition using @datatype and @list.
authorGregg Kellogg <gregg@kellogg-assoc.com>
Wed, 14 Dec 2011 22:28:00 -0800
changeset 293 6a9bb1a6bae4
parent 292 d9b21c6285a8
child 294 efe036bef662
Update change in coercion moving @coerce into separate properties of an expanded term definition using @datatype and @list.
Define an expanded version of the term definition. This resolves issues #34, #40 and #41.
spec/latest/json-ld-api/index.html
spec/latest/json-ld-syntax/index.html
--- a/spec/latest/json-ld-api/index.html	Wed Dec 14 16:34:04 2011 -0800
+++ b/spec/latest/json-ld-api/index.html	Wed Dec 14 22:28:00 2011 -0800
@@ -490,7 +490,7 @@
         <dl class="exception" title="InvalidContext">
          <dt>INVALID_SYNTAX</dt>
          <dd>A general syntax error was detected in the <code>@context</code>.
-         For example, if a <code>@coerce</code> key maps to anything other than
+         For example, if a <code>@datatype</code> key maps to anything other than
          a string or an array of strings, this exception would be raised.</dd>
          <dt>MULTIPLE_DATATYPES</dt>
          <dd>There is more than one target datatype specified for a single
@@ -518,7 +518,7 @@
         <dl class="exception" title="InvalidContext">
           <dt>INVALID_SYNTAX</dt>
           <dd>A general syntax error was detected in the <code>@context</code>.
-            For example, if a <code>@coerce</code> key maps to anything other than
+            For example, if a <code>@datatype</code> key maps to anything other than
             a string or an array of strings, this exception would be raised.</dd>
           <dt>MULTIPLE_DATATYPES</dt>
           <dd>There is more than one target datatype specified for a single
@@ -584,7 +584,7 @@
         <dl class="exception" title="InvalidContext">
           <dt>INVALID_SYNTAX</dt>
           <dd>A general syntax error was detected in the <code>@context</code>.
-            For example, if a <code>@coerce</code> key maps to anything other than
+            For example, if a <code>@datatype</code> key maps to anything other than
             a string or an array of strings, this exception would be raised.</dd>
           <dt>MULTIPLE_DATATYPES</dt>
           <dd>There is more than one target datatype specified for a single
@@ -615,7 +615,7 @@
         <dl class="exception" title="InvalidContext">
           <dt>INVALID_SYNTAX</dt>
           <dd>A general syntax error was detected in the <code>@context</code>.
-            For example, if a <code>@coerce</code> key maps to anything other than
+            For example, if a <code>@datatype</code> key maps to anything other than
             a string or an array of strings, this exception would be raised.</dd>
           <dt>MULTIPLE_DATATYPES</dt>
           <dd>There is more than one target datatype specified for a single
@@ -676,7 +676,6 @@
   in all algorithms described in this section:</p>
 
   <dl>
-  <dt><code>@coerce</code></dt><dd>Used to specify type coercion rules.</dd>
   <dt><code>@context</code></dt><dd>Used to set the <tref>local context</tref>.</dd>
   <dt><code>@datatype</code></dt><dd>Used to specify the datatype for a literal.</dd>
   <dt><code>@id</code></dt><dd>Sets the active subject.</dd>
@@ -771,7 +770,9 @@
     If a <tref>local context</tref> is encountered,
     information from the <tref>local context</tref> is merged into the <tref>active context</tref>.</p>
   <p>The <tref>active context</tref> is used for expanding keys and values of a <tref>JSON object</tref> (or elements
-    of a list (see <span a="#list-processing">List Processing</span>)).</p>
+    of a list (see <span a="#list-processing">List Processing</span>)). It is also used to maintain
+    <tdef>coercion mapping</tdef>s from IRIs associated with terms to datatypes, and
+    <tdef>list mapping</tdef>s for IRIs associated with terms.</p>
   <p>A <tref>local context</tref> is identified within a <tref>JSON object</tref> having a key of
     <code>@context</code> with <tref>string</tref>, <tref>array</tref> or a <tref>JSON object</tref> value.
     When processing a <tref>local context</tref>, special processing rules apply:</p>
@@ -796,63 +797,43 @@
     </li>
     <li>If <em>value</em> is a <tref>JSON object</tref>, perform the following steps:
       <ol class="algorithm">
-        <li>If <em>value</em> has a <code>@coerce</code> key, it MUST have a value of a
-          <tref>JSON object</tref>. Add the <code>@coerce</code> mapping to the <tref>local context</tref>
-          performing <a href="#iri-expansion">IRI Expansion</a> on the associated value(s).</li>
         <li>If <em>value</em> has a <code>@language</code> key, it MUST have a value of a
           simple <tref>string</tref> or <code>null</code>. Add the language to the <tref>local context</tref>.</li>
         <li>Otherwise, for each key in <em>value</em> having the lexical form of <cite><a
           href="http://www.w3.org/TR/2009/REC-xml-names-20091208/#NT-NCName">NCName</a></cite> (see [[XML-NAMES]]),
           or is an empty string,
-          it's value MUST have be a simple <tref>string</tref> with the lexical form of absolute IRI. Merge the
-          key-value pair into the <tref>local context</tref>.</li>
+          <ol class="algorithm">
+            <li>If the key's value is a simple <tref>string</tref> it MUST have the lexical form of absolute IRI.
+              Merge the key-value pair into the <tref>local context</tref>.</li>
+            <li>Otherwise, the key's value MUST be a <tref>JSON object</tref>, having a <code>@id</code> key
+              with a value having the lexical form of absolute IRI. Merge the key-value pair into the
+              <tref>local context</tref>.</li>
+          </ol>
+        </li>
+        <li>Merge the of <tref>local context</tref>'s <tref>term</tref> mapping into  the
+          <tref>active context</tref>'s <tref>term</tref> mapping.</li>
+        <li>For each key in <em>value</em> having the lexical form of <code>NCName</code> or an empty string,
+          with a value that is a <tref>JSON object</tref>
+          <ol class="algorithm">
+            <li>If the value has a <code>@datatype</code> key, the value MUST have the form of <tref>term</tref>,
+              <tref>prefix</tref>:suffix, absolute IRI or the keyword <code>@id</code>. Add a <tref>coercion
+              mapping</tref> for the term to the <tref>local context</tref> performing <a href="#iri-expansion">IRI
+              Expansion</a> on the associated value using the <tref>active context</tref> as necessary.</li>
+            <li>If the value has a <code>@list</code> key, the value MUST be <code>true</code> Add a
+              <tref>list mapping</tref> for the term to the <tref>local context</tref>.</li>
+          </ol>
+        </li>
       </ol>
     </li>
-    <li>Merge the of <tref>local context</tref>'s <code>@coerce</code> mapping into  the
-      <tref>active context</tref>'s <code>@coerce</code> mapping as described <a href="#coerce">below</a>.</li>
-    <li>Merge all entries other than the <code>@coerce</code> mapping from the <tref>local context</tref> to the
-      <tref>active context</tref> overwriting any duplicate values.</li>
+    <li>Merge the of <tref>local context</tref>'s <tref>coercion mapping</tref> into  the
+      <tref>active context</tref>'s <tref>coercion mapping</tref>.</li>
+    <li>Merge the of <tref>local context</tref>'s <tref>list mapping</tref> into  the
+      <tref>active context</tref>'s <tref>list mapping</tref>.</li>
   </ol>
-
-  <section>
-    <h3>Coerce</h3>
-    <p>Map each key-value pair in the <tref>local context</tref>'s
-      <code>@coerce</code> mapping into the <tref>active context</tref>'s
-      <code>@coerce</code> mapping, overwriting any duplicate values in
-      the <tref>active context</tref>'s <code>@coerce</code> mapping.
-      The <code>@coerce</code> mapping has either a single
-      <code>prefix:suffix</code> value, a single <tref>term</tref> value or an
-      <tref>array</tref> of <code>prefix:suffix</code> or <tref>term</tref> values.
-      When merging with an existing mapping in the <tref>active context</tref>,
-      map all <tref>term</tref> values to
-      <tref>array</tref> form and replace with the union of the value from
-      the <tref>local context</tref> and the value of the
-      <tref>active context</tref>. If the result is an <tref>array</tref>
-      with a single value, the processor MAY represent this as a string value.</p>
-    <p class="issue">
-      There is active discussion on merging the @coerce mappings into <tref>term</tref>
-      definitions, in which case <tref>term</tref> or <tref>prefix</tref> expansion cannot
-      take place unless they are in the active context when processing a context
-      definition (i.e., they were previously defined in a context definition prior to
-      parsing a new context definition).
-    </p>
-  </section>
-
-  <section>
-    <h3>Initial Context</h3>
-    <p>The <tref>initial context</tref> is initialized as follows:</p>
-    <ul>
-      <li><code>@coerce</code> is set with a single mapping from <code>@id</code> to <code>@type</code>.</li>
-    </ul>
-    <pre class="example" data-transform="updateExample">
-<!--
-{
-  "@coerce": {
-    "@id": "@type"
-  }
-}
---></pre>
-  </section>
+  
+  <p class="note">Rules for looking up <code>@datatype</code> coercion is performed
+    after merging local term definitions into the <tref>active context</tref>. This allows datatype
+    IRIs to be specified using <tref>term</tref> or <tref>prefix</tref> defined within the same context.</p>
 </section>
 
 <section>
@@ -973,10 +954,9 @@
    "@context":
    {
       "name": "http://xmlns.com/foaf/0.1/name",
-      "homepage": "http://xmlns.com/foaf/0.1/homepage",
-      "@coerce":
-      {
-         "@id": "homepage"
+      "homepage": {
+        "@id": "http://xmlns.com/foaf/0.1/homepage",
+        "@datatype", "@id"
       }
    },
    "name": "Manu Sporny",
@@ -992,8 +972,7 @@
 <!--
 {
    "http://xmlns.com/foaf/0.1/name": "Manu Sporny",
-   "http://xmlns.com/foaf/0.1/homepage":
-   {
+   "http://xmlns.com/foaf/0.1/homepage": {
       "@id": "http://manu.sporny.org/"
    }
 }
@@ -1049,11 +1028,10 @@
 <pre class="example" data-transform="updateExample">
 <!--
 {
-   "http://xmlns.com/foaf/0.1/name": "Manu Sporny",
-   "http://xmlns.com/foaf/0.1/homepage":
-   {
-      "@id": "http://manu.sporny.org/"
-   }
+  "http://xmlns.com/foaf/0.1/name": "Manu Sporny",
+  "http://xmlns.com/foaf/0.1/homepage": {
+    "@id": "http://manu.sporny.org/"
+  }
 }
 -->
 </pre>
@@ -1063,12 +1041,11 @@
 <pre class="example" data-transform="updateExample">
 <!--
 {
-   "name": "http://xmlns.com/foaf/0.1/name",
-   "homepage": "http://xmlns.com/foaf/0.1/homepage",
-   "@coerce":
-   {
-      "@id": "homepage"
-   }
+  "name": "http://xmlns.com/foaf/0.1/name",
+  "homepage": {
+    "@id": "http://xmlns.com/foaf/0.1/homepage",
+    "@datatype": "@id"
+  }
 }
 -->
 </pre>
@@ -1080,17 +1057,15 @@
 <pre class="example" data-transform="updateExample">
 <!--
 {
-   "@context":
-   {
-      "name": "http://xmlns.com/foaf/0.1/name",
-      "homepage": "http://xmlns.com/foaf/0.1/homepage",
-      "@coerce":
-      {
-         "@id": "homepage"
-      }
-   },
-   "name": "Manu Sporny",
-   "homepage": "http://manu.sporny.org/"
+  "@context": {
+    "name": "http://xmlns.com/foaf/0.1/name",
+    "homepage": {
+      "@id": "http://xmlns.com/foaf/0.1/homepage",
+      "@datatype": "@id"
+    }
+  },
+  "name": "Manu Sporny",
+  "homepage": "http://manu.sporny.org/"
 }
 -->
 </pre>
@@ -1123,7 +1098,6 @@
 
 </section>
 
-
 <section>
 <h2>Framing</h2>
 
@@ -1150,15 +1124,14 @@
   "@context": {
     "Book":         "http://example.org/vocab#Book",
     "Chapter":      "http://example.org/vocab#Chapter",
-    "contains":     "http://example.org/vocab#contains",
+    "contains":     {
+      "@id": "http://example.org/vocab#contains",
+      "@datatype": "@id"
+    },
     "creator":      "http://purl.org/dc/terms/creator",
     "description":  "http://purl.org/dc/terms/description",
     "Library":      "http://example.org/vocab#Library",
-    "title":        "http://purl.org/dc/terms/title",
-    "@coerce":
-    {
-      "@id": "contains"
-    },
+    "title":        "http://purl.org/dc/terms/title"
   },
   "@id":
   [{
@@ -1451,18 +1424,16 @@
 <pre class="example" data-transform="updateExample">
 <!--
 {
-   "@context":
-   {
-      "name": "http://xmlns.com/foaf/0.1/name",
-      "homepage": "http://xmlns.com/foaf/0.1/homepage",
-      "xsd": "http://www.w3.org/2001/XMLSchema#",
-      "@coerce":
-      {
-         "@id": ["homepage"]
-      }
-   },
-   "name": "Manu Sporny",
-   "homepage": "http://manu.sporny.org/"
+  "@context": {
+    "name": "http://xmlns.com/foaf/0.1/name",
+    "homepage": {
+      "@id": "http://xmlns.com/foaf/0.1/homepage",
+      "@datatype": "@id"
+    },
+    "xsd": "http://www.w3.org/2001/XMLSchema#"
+  },
+  "name": "Manu Sporny",
+  "homepage": "http://manu.sporny.org/"
 }
 -->
 </pre>
@@ -1476,12 +1447,11 @@
 <pre class="example" data-transform="updateExample">
 <!--
 [{
-    "@id": "_:c14n0",
-    "http://xmlns.com/foaf/0.1/homepage":
-    {
-        "@id": "http://manu.sporny.org/"
-    },
-    "http://xmlns.com/foaf/0.1/name": "Manu Sporny"
+  "@id": "_:c14n0",
+  "http://xmlns.com/foaf/0.1/homepage": {
+    "@id": "http://manu.sporny.org/"
+  },
+  "http://xmlns.com/foaf/0.1/name": "Manu Sporny"
 }]
 -->
 </pre>
@@ -2490,15 +2460,15 @@
 forward slashes.</p>
 
 <p class="issue">Round-tripping data can be problematic if we mix and
-match @coerce rules with JSON-native datatypes, like integers. Consider the
+match coercion rules with JSON-native datatypes, like integers. Consider the
 following code example:</p>
 
 <pre class="example" data-transform="updateExample">
 <!--
 var myObj = { "@context" : {
-                "number" : "http://example.com/vocab#number",
-                "@coerce": {
-                   "xsd:nonNegativeInteger": "number"
+                "number" : {
+                  "@id": "http://example.com/vocab#number",
+                  "@datatype": "xsd:nonNegativeInteger"
                 }
               },
               "number" : 42 };
@@ -2515,7 +2485,7 @@
 values for the "number" value. myObj will be the number 42, while
 myObj2 will be the string "42". This type of data round-tripping
 error can bite developers. We are currently wondering if having a
-"coerce validation" phase in the parsing/normalization phases would be a
+"coercion validation" phase in the parsing/normalization phases would be a
 good idea. It would prevent data round-tripping issues like the
 one mentioned above.</p>
 
--- a/spec/latest/json-ld-syntax/index.html	Wed Dec 14 16:34:04 2011 -0800
+++ b/spec/latest/json-ld-syntax/index.html	Wed Dec 14 22:28:00 2011 -0800
@@ -412,7 +412,6 @@
   in all algorithms described in this section:</p>
 
   <dl>
-  <dt><code>@coerce</code></dt><dd>Used to specify type coercion rules.</dd>
   <dt><code>@context</code></dt><dd>Used to set the <tref>local context</tref>.</dd>
   <dt><code>@datatype</code></dt><dd>Used to specify the datatype for a literal.</dd>
   <dt><code>@id</code></dt><dd>Sets the active subject.</dd>
@@ -773,31 +772,16 @@
 
 <ol>
   <li>Except within a <tref>context</tref> definition, <tref>term</tref>s in the key position in
-    a <tref>JSON object</tref> that have a mapping to an <tref>IRI</tref> or another key in the
+    a <tref>JSON object</tref> that have a mapping to an <tref>IRI</tref> or another <tref>term</tref> in the
     <tref>active context</tref> are expanded to an IRI by JSON-LD processors.</li>
   <li>An <tref>IRI</tref> is generated for the <tref>string</tref> value specified using
     <code>@id</code> or <code>@type</code>.</li>
-  <li>An <tref>IRI</tref> is generated for any key or <tref>string</tref> value with the <code>@coerce</code>,
-    section of a <tref>context</tref> definition.
-  <li>An <tref>IRI</tref> is generated for the value of any other key if there are <code>@coerce</code> rules in
-    effect for that key that identify it as a <code>@id</code>.</li>
+  <li>An <tref>IRI</tref> is generated for the value of any key if there are <tref>coercion</tref> rules in
+    effect for that key that identify it as an <code>@id</code>.</li>
 </ol>
 
 <p>IRIs may be represented as an absolute IRI, a <tref>term</tref>, or a <tref>prefix</tref>:suffix construct.</p>
 
-<p class="note">
-  As there it is possible to confuse <tref>term</tref>s or <tref>prefix</tref>es with relative IRIs, as
-  a best practice, relative IRIs SHOULD begin with './', '#' or '/', as these are not valid for use within
-  <tref>term</tref> definitions.
-</p>
-
-<p class="issue">
-  There is active discussion on merging the @coerce mappings into <tref>term</tref> definitions, in which case
-  <tref>term</tref> or <tref>prefix</tref> expansion cannot take place unless they are in the active context when processing
-  a context definition (i.e., they were previously defined in a context definition prior to parsing
-  a new context definition).
-</p>
-
 <p>IRIs can be expressed directly in the key position like so:</p>
 
 <pre class="example" data-transform="updateExample">
@@ -863,19 +847,18 @@
   This is an example of <tref>chaining</tref> in JSON-LD, an issue covered further in <a
   href="#chaining">Chaining</a>.</p>
 
-<p>If type coercion rules are specified in the <code>@context</code> for
+<p>If type <tref>coercion</tref> rules are specified in the <code>@context</code> for
 a particular <tref>term</tref> or property IRI, an IRI is generated:</p>
 
 <pre class="example" data-transform="updateExample">
 <!--
 {****
-  "@context":
-  {
+  "@context": {
     ...
-    "@coerce":
-    {
-      "@id": "homepage"
+    "homepage": {
+      "@id": "http://xmlns.com/foaf/0.1/homepage", "@datatype": "@id"
     }
+    ...
   }****
 ...
   "homepage": "http://manu.sporny.org/",
@@ -885,7 +868,7 @@
 </pre>
 
 <p>Even though the value <code>http://manu.sporny.org/</code> is a <tref>string</tref>,
-the type coercion rules will transform the value into an IRI when processed
+the type <tref>coercion</tref> rules will transform the value into an IRI when processed
 by a JSON-LD Processor</p>
 
 </section>
@@ -1023,24 +1006,22 @@
 </p>
 
 <ol>
-  <li>By utilizing the <code>@coerce</code> keyword.</li>
+  <li>By utilizing the <code>@datatype</code> keyword when defining a <tref>term</tref> within a
+    <code>@context</code> section.</li>
   <li>By utilizing the expanded form for specifying objects.</li>
   <li>By using a native JSON datatype.</li>
 </ol>
 
-<p>The first example uses the <code>@coerce</code> keyword to express a
-typed literal:</p>
+<p>The first example uses the <code>@datatype</code> keyword to express a typed literal:</p>
 
 <pre class="example" data-transform="updateExample">
 <!--
-{****
-  "@context":
-  {
-    "modified":  "http://purl.org/dc/terms/modified",
-    "dateTime": "http://www.w3.org/2001/XMLSchema#dateTime"
-    "@coerce":
+{
+  ****"@context": {
+    "modified":
     {
-      "dateTime": "modified"
+      "@id": "http://purl.org/dc/terms/modified",
+      "@datatype": "http://www.w3.org/2001/XMLSchema#dateTime"
     }
   }****
 ...
@@ -1208,28 +1189,30 @@
   <p>
     This describes the use of this <tref>array</tref> as being ordered, and order is maintained through normalization
     and RDF conversion as described in [[JSON-LD-API]]. If every use of a given multi-valued property is a list, this
-    may be abbreviated by adding an <code>@coerce</code> term:
+    may be abbreviated by adding an <code>@datatype</code> <tref>coercion</tref>:
   </p>
   <pre class="example" data-transform="updateExample">
   <!--
   {
-    ****"@context": {****
+    ****"@context": {
       ...
-      ****"@coerce": {****
-        ****"@list": [ "foaf:nick" ]****
-      ****}****
-    ****}****,
+      "nick": {
+        "@id": "http://xmlns.com/foaf/0.1/nick",
+        "@list": true
+      }
+  }****,
   ...
     "@id": "http://example.org/people#joebob",
-    "foaf:nick": ****[ "joe", "bob", "jaybee" ]****,
+    "nick": ****[ "joe", "bob", "jaybee" ]****,
   ...
   }
   -->
   </pre>
-  <p>
-    The @list keyword can be used within the <code>@coerce</code> section of a <code>@context</code> to
-    cause value arrays to be coerced into an ordered list.
-  </p>
+  <p>List coercion is specified within an expanded <tref>term</tref> definition using the <code>@list</code> key.
+    The value of this key, if present, MUST be <code>true</code>.
+    This indicates that array values of keys coerced as <code>@list</code> are to be serialized
+    as a <a href="#rdf-collection">List</a>.</p>
+
   <p>
     In RDF, a list is described as an <cite><a href="http://www.w3.org/TR/rdf-schema/#ch_collectionvocab">RDF
     Collection</a></cite> as defined in [[!RDF-SCHEMA]].
@@ -1247,7 +1230,7 @@
 </p>
 
 <section>
-<h2>Contexts</h2>
+<h2>External Contexts</h2>
 
 <p>Authors may choose to declare JSON-LD <tref>context</tref>s in external
 documents to promote re-use of contexts as well as reduce the size of JSON-LD
@@ -1348,6 +1331,36 @@
 </section>
 
 <section>
+  <h3>Expanded Term Definition</h3>
+  <p>Within a context definition, <tref>term</tref>s MAY be defined using an expanded notation to allow
+    for additional information associated with the term to be specified (see <a href="#type-coerceion">Type
+    Coercion</a> and <a href="#rdf-collection">Lists</a>).</p>
+    
+  <p>Instead of using a string representation of an IRI, the IRI is specified using an object having
+    an <code>@id</code> key. The value of this key MUST be an absolute IRI.</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+{
+  "@context": {
+    "name": ****{"@id": "http://xmlns.com/foaf/0.1/name"}****,
+    "homepage": ****{"@id": "http://xmlns.com/foaf/0.1/homepage"}****,
+    "avatar": ****{"@id": "http://xmlns.com/foaf/0.1/avatar"}****
+  },
+  "name": "Manu Sporny",
+  "homepage": "http://manu.sporny.org/",
+  "avatar": "http://twitter.com/account/profile_image/manusporny"
+}
+-->
+</pre>
+
+  <p class="issue">There is an open issue
+    (<a href="https://github.com/json-ld/json-ld.org/issues/43" target="_blank">#43</a>)
+    on allowing non-terms in the key position to allow <tref>coercion</tref> to be specified
+    for CURIEs or absolute IRIs.</p>
+</section>
+
+<section>
 <h3>Default Language</h3>
 
 <p>JSON-LD allows a default value to use as the language for <tref>plain literal</tref>s.
@@ -1583,24 +1596,22 @@
 <h2>Type Coercion</h2>
 
 <p>JSON-LD supports the coercion of values to particular data types.
-Type coercion allows someone deploying JSON-LD to coerce the incoming or
+Type <tdef>coercion</tdef> allows someone deploying JSON-LD to coerce the incoming or
 outgoing types to the proper data type based on a mapping of data type <tref>IRI</tref>s to
 property types. Using type coercion, one may convert simple JSON data to
 properly typed RDF data.</p>
 
-<p>Keys within a <code>@coerce</code> definition represent datatype IRIs and MUST take the form
-  of <tref>term</tref>, <tref>prefix</tref>:suffix, absolute IRI or the keywords <code>@id</code> or <code>@list</code>.
-  Specifying <code>@id</code> indicates that within the body of a JSON-LD document, string values of keys coerced as
-  <code>@id</code> are to be interpreted as <tref>IRI</tref>s, and are subject to IRI expansion. Specifying
-  <code>@list</code> indicates that array values of keys coerced as <code>@list</code> are to be serialized
-  as a <a href="#rdf-collection">List</a>.</p>
+<p>Type coercion is specified within an <a href="#expanded-term-definition">expanded term definition</a>
+  using the <code>@datatype</code> key. The values of this key represent datatype IRIs and MUST take the form of
+  <tref>term</tref>, <tref>prefix</tref>:suffix, absolute IRI or the keyword <code>@id</code>. Specifying
+  <code>@id</code> indicates that within the body of a JSON-LD document, string values of keys coerced as
+  <code>@id</code> are to be interpreted as <tref>IRI</tref>s, or labeled nodes and are subject to IRI expansion.</p>
 
-<p>Values within a <code>@coerce</code> definition represent property IRIs and MUST take the form
-  of <tref>term</tref>, <tref>prefix</tref>:suffix or <tref>array</tref>. Multiple values may be represented using
-  array form, where each element of the <tref>array</tref> must be a <tref>string</tref> interpreted as <tref>term</tref> or <tref>prefix</tref>:suffix.</p>
+<p><tref title="term">Terms</tref> or <tref title="prefix">prefixes</tref> used as the value of a
+  <code>@datatype</code> key MAY be defined within the same context.</p>
 
 <p>The example below demonstrates how a JSON-LD author can coerce values to
-<tref>plain literal</tref>s, <tref>typed literal</tref>s and IRIs.</p>
+<tref>plain literal</tref>s, <tref>typed literal</tref>s, IRIs and lists.</p>
 
 <pre class="example" data-transform="updateExample">
 <!--
@@ -1610,13 +1621,8 @@
      "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
      "xsd": "http://www.w3.org/2001/XMLSchema#",
      "name": "http://xmlns.com/foaf/0.1/name",
-     "age": "http://xmlns.com/foaf/0.1/age",
-     "homepage": "http://xmlns.com/foaf/0.1/homepage",
-****     "@coerce":
-     {
-        "xsd:integer": "age",
-        "@id": "homepage"
-     }****
+     "age": ****{"@id": "http://xmlns.com/foaf/0.1/age", "@datatype": "xsd:integer"}****,
+     "homepage": ****{"@id": "http://xmlns.com/foaf/0.1/homepage", "@datatype": "@id"}****
   },
   "name": "John Smith",
   "age": ****"41"****,
@@ -1625,67 +1631,19 @@
 -->
 </pre>
 
-<p>The example above would generate the following triples:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-_:bnode1
-   <http://xmlns.com/foaf/0.1/name>
-      "John Smith" .
-_:bnode1
-   <http://xmlns.com/foaf/0.1/age>
-      "41"^^http://www.w3.org/2001/XMLSchema#integer .
-_:bnode1
-   <http://xmlns.com/foaf/0.1/homepage>
-      <http://example.org/home/> .
--->
-</pre>
-
-<div class="issue">
-  <p>The mechanism for type coercion is still being debated. It may be that the key/value
-    positions are swapped, yielding a <code>@context</code> such as the following:</p>
+<p>The example above would generate the following turtle:</p>
 
 <pre class="example" data-transform="updateExample">
 <!--
-{
-  "@context": {
-    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
-    "xsd": "http://www.w3.org/2001/XMLSchema#",
-    "name": "http://xmlns.com/foaf/0.1/name",
-    "age": "http://xmlns.com/foaf/0.1/age",
-    "homepage": "http://xmlns.com/foaf/0.1/homepage",
-    "currentProject": "http://xmlns.com/foaf/0.1/currentProject",
-    ****"@coerce": {
-      "age": "xsd:integer",
-      "homepage": "@id",
-      "currentProject": [ "@id", "@list" ]
-     }****
-  },
-  ...
-}
+@prefix rdf: <> .
+@prefix xsd: <> .
+
+[ foaf:name "John Smith";
+  foaf:age  "41"^^xsd:integer;
+  foaf:homepage <http://example.org/home>
+] .
 -->
 </pre>
-
-<p>An alternative is to merge the coercion into term definitions:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-{
-  "@context":
-  {
-    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
-    "xsd": "http://www.w3.org/2001/XMLSchema#",
-    "name": "http://xmlns.com/foaf/0.1/name",
-    "age": ****{ "@id": "http://xmlns.com/foaf/0.1/age", "@coerce": "xsd:integer" }****,
-    "homepage": ****{ "@id": "http://xmlns.com/foaf/0.1/age", "@coerce": "@id" }****,
-    "currentProject": ****{ "@id": "http://xmlns.com/foaf/0.1/currentProject", "@coerce": [ "@id", "@list" ] }****,
-  },
-  ...
-}
--->
-</pre>
-</div>
-
 </section>
 
 <section>
@@ -2008,9 +1966,8 @@
   "@context":
   {
     "vcard": "http://microformats.org/profile/hcard#vcard",
-    "url": "http://microformats.org/profile/hcard#url",
-    "fn": "http://microformats.org/profile/hcard#fn",
-    "@coerce": { "@id": "url" }
+    "url": {"@id": "http://microformats.org/profile/hcard#url", "@datatype": "@id"},
+    "fn": "http://microformats.org/profile/hcard#fn"
   },
   "@id": "_:bnode1",
   "@type": "vcard",