Skip to content

Commit 37487cb

Browse files
committed
Dynamic vs Lexical scope: $recursiveRef
This is some groundwork for $recursiveRef/$recursiveAnchor, formalizing lexical and dynamic notions of scope in ways that should be quite intuitive given how the concepts are used in a wide variety of programming languages.
1 parent 0cce8aa commit 37487cb

File tree

1 file changed

+67
-14
lines changed

1 file changed

+67
-14
lines changed

jsonschema-core.xml

+67-14
Original file line numberDiff line numberDiff line change
@@ -570,13 +570,70 @@
570570
As with the root schema, a subschema is either an object or a boolean.
571571
</t>
572572
</section>
573+
<section title="Lexical Scope and Dynamic Scope">
574+
<t>
575+
While most JSON Schema keywords can be evaluated on their own,
576+
or at most need to take into account the values or results of
577+
adjacent keywords in the same schema object, a few have more
578+
complex behavior.
579+
</t>
580+
<t>
581+
The lexical scope of a keyword is deterimined by the nested JSON
582+
data structure of objects and arrays. The largest such scope
583+
is an entire schema document. The smallest scope is a single
584+
schema object with no subschemas.
585+
</t>
586+
<t>
587+
Keywords MAY be defined with a partial value, such as a URI-reference,
588+
which must be resolved against another value, such as another
589+
URI-reference or a full URI, which is found through the lexical
590+
structure of the JSON document. The "$id" core keyword and
591+
the "base" JSON Hyper-Schema keyword are examples of this sort
592+
of behavior. Additionally, "$ref" and "$recursiveRef" from
593+
this specification resolve their values in this way, although
594+
they do not change how further values are resolved.
595+
</t>
596+
<t>
597+
Note that some keywords, such as "$schema", apply to the lexical
598+
scope of the entire schema document, and therefore MUST only
599+
appear in the document's root schema.
600+
</t>
601+
<t>
602+
Other keywords may take into account the dynamic scope that
603+
exists during the evaluation of a schema, typically together
604+
with an instance document. The outermost dynamic scope is the
605+
root schema of the schema document in which processing begins.
606+
<cref>
607+
Or should this be the schema object at which processing
608+
begins, even if it is not a root? This has some implications
609+
for the case where "$recursiveAnchor" is only allowed in the
610+
root schema but processing begins in a subschema.
611+
</cref>
612+
</t>
613+
<t>
614+
Lexical and dynamic scopes align until a reference keyword
615+
is encountered. While following the reference keyword jumps
616+
from one lexical scope into a different one, from the perspective
617+
of dynamic scope, following reference is no different from descending
618+
into a subschema present as a value. A keyword on the far side of
619+
that reference that resolves information through the dynamic scope
620+
will consider the originating side of the reference to be their
621+
dynamic parent, rather than examining the local lexically enclosing parent.
622+
</t>
623+
<t>
624+
The concept of dynamic scope is primarily used with "$recursiveRef"
625+
and "$recursiveAnchor", and should be considered and advanced feature
626+
and used with caution when defining additional keywords.
627+
</t>
628+
</section>
573629
<section title="Referred and Referring Schemas" anchor="referred">
574630
<t>
575631
As noted in <xref target="applicators" />, an applicator keyword may
576632
refer to a schema to be applied, rather than including it as a
577633
subschema in the applicator's value. In such situations, the
578-
schema being applied is known as the referred schema, while
579-
the schema containing the applicator keyword is the referring schema.
634+
schema being applied is known as the referred (or referenced) schema,
635+
while the schema containing the applicator keyword is the referring
636+
(or referencing) schema.
580637
</t>
581638
<t>
582639
While root schemas and subschemas are static concepts based on a
@@ -587,15 +644,11 @@
587644
</t>
588645
<t>
589646
For some by-reference applicators, such as
590-
<xref target="ref">"$ref"</xref>, the referred schema can be determined
591-
by static analysis of the schema document. Others may take evaluation
592-
context into account, and only be resolvable in the process of evaluating
593-
with an instance.
594-
<cref>
595-
Assuming some form of dynamic reference keyword is introduced
596-
related to GitHub issue #558, this section will be updated
597-
to make a concrete reference to that keyword for clarification.
598-
</cref>
647+
<xref target="ref">"$ref"</xref>, the referenced schema can be determined
648+
by static analysis of the schema document's lexical scope. Others,
649+
such as "$recursiveRef" and "$recursiveAnchor", may make use of dynamic
650+
scoping, and therefore only be resolvable in the process of evaluating
651+
the schema with an instance.
599652
</t>
600653
</section>
601654
</section>
@@ -740,9 +793,9 @@
740793
allow tools to follow the correct behaviour.
741794
</t>
742795
<t>
743-
Note that the recursive nature of meta-schemas requires re-defining
744-
recursive keywords in the extended meta-schema, as can be seen in
745-
the JSON Hyper-Schema meta-schema.
796+
The recursive nature of meta-schemas makes the "$recursiveAnchor"
797+
and "$recursiveRef" keywords particularly useful for such extensions,
798+
as can be seen in the JSON Hyper-Schema meta-schema.
746799
</t>
747800
</section>
748801

0 commit comments

Comments
 (0)