diff --git a/docs/collections/_other/doc-history.md b/docs/collections/_other/doc-history.md
index 9a60c3d..be05b54 100644
--- a/docs/collections/_other/doc-history.md
+++ b/docs/collections/_other/doc-history.md
@@ -13,7 +13,8 @@ The following table tracks changes to the Cedar language version. The language v
| Cedar
Version | Description | Cedar SDK
Version(s) | Date |
| --- | --- | --- | --- |
-| 4.1 | Entity tags [rfc#82](https://github.com/cedar-policy/rfcs/blob/main/text/0082-entity-tags.md)
Annotations without values [cedar#1231](https://github.com/cedar-policy/cedar/pull/1231) | 4.2.0 | October 7, 2024
+| 4.2 | `isEmpty` operator [cedar#1358](https://github.com/cedar-policy/cedar/pull/1358) | 4.3.0 | TBD
+| 4.1 | Entity tags [rfc#82](https://github.com/cedar-policy/rfcs/blob/main/text/0082-entity-tags.md)
Annotations without values [cedar#1231](https://github.com/cedar-policy/cedar/pull/1231) | 4.2.0 - 4.2.2 | October 7, 2024
| 4.0 | Reserve `__cedar` identifier for internal use [rfc#52](https://github.com/cedar-policy/rfcs/blob/main/text/0052-reserved-namespaces.md)
Remove unspecified entities [rfc#55](https://github.com/cedar-policy/rfcs/blob/main/text/0055-remove-unspecified.md)
Disallow shadowing definitions in the empty namespace [rfc#70](https://github.com/cedar-policy/rfcs/blob/main/text/0070-disallow-empty-namespace-shadowing.md)
Allow `EntityOrCommon` field in JSON schema [cedar#1060](https://github.com/cedar-policy/cedar/pull/1060)
Disallow `Bool`, `Boolean`, `Entity`, `Extension`, `Long`, `Record`, `Set`, and `String` as common type names in schemas [cedar#1150](https://github.com/cedar-policy/cedar/pull/1150) | 4.0.0 - 4.1.0 | September 16, 2024 |
| 3.4 | JSON format for policy sets [cedar#549](https://github.com/cedar-policy/cedar/issues/549) | 3.3.0 - 3.4.0 | August 19, 2024 |
| 3.3 | References between common types [cedar#154](https://github.com/cedar-policy/cedar/issues/154) | 3.2.0 - 3.2.4 | May 17, 2024 |
diff --git a/docs/collections/_policies/json-format.md b/docs/collections/_policies/json-format.md
index 3f824b1..5f9d00e 100644
--- a/docs/collections/_policies/json-format.md
+++ b/docs/collections/_policies/json-format.md
@@ -610,7 +610,7 @@ An JsonExpr object is an object with a single key that is any of the following.
+ [`Var`](#JsonExpr-Var)
+ [`Slot`](#JsonExpr-Slot)
+ [`Unknown`](#JsonExpr-Unknown)
-+ [`!` or `neg` operators](#JsonExpr-neg)
++ [`!`, `neg`, and `isEmpty` operators](#JsonExpr-neg)
+ [Binary operators: `==`, `!=`, `in`, `<`, `<=`, `>`, `>=`, `&&`, `||`, `+`, `-`, `*`, `contains`, `containsAll`, `containsAny`, `hasTag`, `getTag`](#JsonExpr-binary)
+ [`.`, `has`](#JsonExpr-has)
+ [`is`](#JsonExpr-is)
@@ -811,7 +811,7 @@ The value of this key is one of the strings `?principal` or `?resource` and act
The value of this key is an object with a single key name, whose value is the name of the unknown. This is used for partial-evaluation. In particular, these values may appear in the JSON rendering of residuals.
-#### `!` or `neg` operators {#JsonExpr-neg}
+#### `!`, `neg`, and `isEmpty` operators {#JsonExpr-neg}
The value of this key is an object with a single key argument, whose value is itself an [JsonExpr object](#JsonExpr-objects).
diff --git a/docs/collections/_policies/syntax-operators.md b/docs/collections/_policies/syntax-operators.md
index 50ef560..a308e12 100644
--- a/docs/collections/_policies/syntax-operators.md
+++ b/docs/collections/_policies/syntax-operators.md
@@ -1036,6 +1036,22 @@ In the examples that follow, those labeled `//error` both evaluate and validate
The examples that evaluate to a result but fail to validate reference the empty-set literal `[]`. See [valid sets](syntax-datatypes.html#datatype-set) for more info.
+### `.isEmpty()` \(set emptiness test\) {#function-isEmpty}
+
+**Usage:** `.isEmpty()`
+
+Function that evaluates to `true` if the set is empty.
+The receiver must be of type `set` or evaluation produces an error.
+
+#### Examples:
+{: .no_toc }
+
+```cedar
+[1, -22, 34].isEmpty() // Evaluates to false
+[].isEmpty() // Evaluates to true
+"".isEmpty() // Error - operand is a string, not a set
+```
+
## IP address functions {#functions-ipaddr}
Use these functions to test characteristics of IP addresses and ranges.
diff --git a/docs/js/hljs-cedar.min.js b/docs/js/hljs-cedar.min.js
index 2d7c6e9..5bef108 100644
--- a/docs/js/hljs-cedar.min.js
+++ b/docs/js/hljs-cedar.min.js
@@ -1,3 +1,3 @@
-(()=>{function t(e){let s={match:/\b(?:ip|decimal)(?=\()/,scope:"built_in"},n={match:/\b(?=","<=",">","<","\\+","-","\\*","in","like","has","is"].join("|")+")"+/(?!\w)/.source,scope:"operator",relevance:0},p={scope:"number",begin:"0|-?[1-9](_?[0-9])*",relevance:0},E={match:/(?=\b)(([_a-zA-Z][_a-zA-Z0-9]*::)*[_a-zA-Z][_a-zA-Z0-9]*)(?=::)/,scope:"title.class"},T={match:[/is/,/\s+/,/([_a-zA-Z][_a-zA-Z0-9]*::)*[_a-zA-Z][_a-zA-Z0-9]*/],scope:{1:"operator",3:"title.class"}},b={scope:"title.function.invoke",begin:"(?=.)(contains|containsAll|containsAny)(?=\\()",relevance:0},_={scope:"title.function.invoke",begin:"(?=.)(lessThan|lessThanOrEqual|greaterThan|greaterThanOrEqual)(?=\\()",relevance:0},O={scope:"title.function.invoke",begin:"(?=.)(isIpv4|isIpv6|isLoopback|isMulticast|isInRange)(?=\\()",relevance:0};return{name:"Cedar",aliases:["cedar"],case_insensitive:!1,keywords:o,contains:[e.QUOTE_STRING_MODE,e.C_LINE_COMMENT_MODE,s,n,c,p,r,E,T,l,b,_,O,a]}}function i(e){let s={match:/\b(?:namespace|type|entity|action)(?=\s+)/,scope:"keyword"},n={begin:"\\b(?:in)\\b|\\b(?:appliesTo)(?=\\s*{)",scope:"keyword"},a={begin:"=",scope:"operator"},c={begin:"{|}|\\[|]|;",scope:"punctuation"},o={begin:/\b(?:[_a-zA-Z][_a-zA-Z0-9]*)(?=[?]?:(?!:))/,scope:"property"};return{name:"Cedar schema",aliases:["cedarschema"],case_insensitive:!1,contains:[e.QUOTE_STRING_MODE,e.C_LINE_COMMENT_MODE,s,n,a,c,o]}}window.hljsCedar=t;window.hljsCedarschema=i;})();
+(()=>{function t(e){let s={match:/\b(?:ip|decimal)(?=\()/,scope:"built_in"},n={match:/\b(?=","<=",">","<","\\+","-","\\*","in","like","has","is"].join("|")+")"+/(?!\w)/.source,scope:"operator",relevance:0},p={scope:"number",begin:"0|-?[1-9](_?[0-9])*",relevance:0},E={match:/(?=\b)(([_a-zA-Z][_a-zA-Z0-9]*::)*[_a-zA-Z][_a-zA-Z0-9]*)(?=::)/,scope:"title.class"},T={match:[/is/,/\s+/,/([_a-zA-Z][_a-zA-Z0-9]*::)*[_a-zA-Z][_a-zA-Z0-9]*/],scope:{1:"operator",3:"title.class"}},b={scope:"title.function.invoke",begin:"(?=.)(contains|containsAll|containsAny|isEmpty)(?=\\()",relevance:0},_={scope:"title.function.invoke",begin:"(?=.)(lessThan|lessThanOrEqual|greaterThan|greaterThanOrEqual)(?=\\()",relevance:0},O={scope:"title.function.invoke",begin:"(?=.)(isIpv4|isIpv6|isLoopback|isMulticast|isInRange)(?=\\()",relevance:0};return{name:"Cedar",aliases:["cedar"],case_insensitive:!1,keywords:o,contains:[e.QUOTE_STRING_MODE,e.C_LINE_COMMENT_MODE,s,n,c,p,r,E,T,l,b,_,O,a]}}function i(e){let s={match:/\b(?:namespace|type|entity|action)(?=\s+)/,scope:"keyword"},n={begin:"\\b(?:in)\\b|\\b(?:appliesTo)(?=\\s*{)",scope:"keyword"},a={begin:"=",scope:"operator"},c={begin:"{|}|\\[|]|;",scope:"punctuation"},o={begin:/\b(?:[_a-zA-Z][_a-zA-Z0-9]*)(?=[?]?:(?!:))/,scope:"property"};return{name:"Cedar schema",aliases:["cedarschema"],case_insensitive:!1,contains:[e.QUOTE_STRING_MODE,e.C_LINE_COMMENT_MODE,s,n,a,c,o]}}window.hljsCedar=t;window.hljsCedarschema=i;})();
//! Copyright Cedar Contributors
//! SPDX-License-Identifier: Apache-2.0