-This ADT is a bounded Merkle tree of depth nat where 2 <= nat <= 32 containing values of type value_type, with history.
+This ADT is a bounded Merkle tree of depth nat where 2 `<=` nat `<=` 32 containing values of type value_type, with history.
### checkRoot
diff --git a/sidebars.compact.js b/sidebars.compact.js
index ae5cd48d..76ce89c8 100644
--- a/sidebars.compact.js
+++ b/sidebars.compact.js
@@ -10,7 +10,7 @@ const sidebars = {
"writing", // docs/develop/reference/compact/writing.md(x)
"lang-ref", // docs/develop/reference/compact/lang-ref.md(x)
"compact-grammar", // docs/develop/reference/compact/compact-grammar.md(x)
- "all-keywords", // docs/develop/reference/compact/all-keywords.md(x)
+ "compact-keywords", // docs/develop/reference/compact/compact-keywords.md(x)
"ledger-adt", // docs/develop/reference/compact/ledger-adt.md(x)
"opaque_data", // docs/develop/reference/compact/opaque_data.md(x)
"explicit-disclosure", // docs/develop/reference/compact/explicit-disclosure.md(x)
diff --git a/src/css/custom.css b/src/css/custom.css
index 35a5a5f0..fbc9ee72 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -484,7 +484,6 @@ a:hover {
code {
font-family: var(--ifm-font-family-monospace);
font-variant-ligatures: none;
- word-break: break-all;
overflow-wrap: break-word;
white-space: pre-wrap;
vertical-align: baseline !important;
diff --git a/static/language/all-keywords.html b/static/language/all-keywords.html
deleted file mode 100644
index d648abd7..00000000
--- a/static/language/all-keywords.html
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-
-
- Keywords
-
-
- Keywords
- keywordBoolean
- Boolean literal values.
-
- keywordImport
- Keywords related to the module system.
-
- - export
- - from
- - import
- - module
-
- keywordControl
- Keywords used in control flow and declarations.
-
- - as
- - assert
- - circuit
- - const
- - constructor
- - contract
- - default
- - disclose
- - else
- - enum
- - fold
- - for
- - if
- - include
- - ledger
- - map
- - new
- - of
- - pad
- - pragma
- - prefix
- - pure
- - return
- - sealed
- - slice
- - struct
- - type
- - witness
-
- keywordDataTypes
- Built-in data type keywords.
-
- - Boolean
- - Bytes
- - Field
- - Opaque
- - Uint
- - Vector
-
- keywordReservedForFutureUse
- Reserved keywords that may be used in future versions of the language. Using these as identifiers is not allowed.
-
- - await
- - break
- - case
- - catch
- - class
- - continue
- - debugger
- - delete
- - do
- - extends
- - finally
- - function
- - implements
- - in
- - instanceof
- - interface
- - let
- - null
- - package
- - private
- - protected
- - public
- - static
- - super
- - switch
- - this
- - throw
- - try
- - typeof
- - var
- - void
- - while
- - with
- - yield
-
-
-
diff --git a/static/language/compact.html b/static/language/compact.html
index 8b038236..c243b726 100644
--- a/static/language/compact.html
+++ b/static/language/compact.html
@@ -6,7 +6,7 @@
Compact Grammar
Compact language version 0.21.0.
-
Notational note: In the grammar productions below, ellipses are used to specify repetition. The notation X ... X, where X is a grammar symbol, represents zero or more occurrences of X. The notation X s ... s X, where X is a grammar symbol and s is a separator such as a comma or or semicolon, represents zero or more occurrences of X separated by s. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one X. When such a sequence is followed by sopt, an optional trailing separator is allowed, but only if there is at least one X. For example, id … id represents zero or more ids, and expr , …¹ , expr ,opt represents one or more comma-separated exprs possibly followed by an extra comma.
+
Notational note: In the grammar productions below, ellipses are used to specify repetition. The notation X ... X, where X is a grammar symbol, represents zero or more occurrences of X. The notation X , ... , X, where X is a grammar symbol and , is a separator, represents zero or more occurrences of X separated by ,. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one X. When such a sequence is followed by ,opt, an optional trailing separator is allowed, but only if there is at least one X. For example, id … id represents zero or more ids, and expr , …¹ , expr ,opt represents one or more comma-separated exprs possibly followed by an extra comma. There are two separators: comma and semicolon.
end of file
@@ -19,33 +19,33 @@ Compact Grammar
a version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2.3, representing major, minor, and bugfix versions
-
-
+
+
-
-
-
+
+| include-form | → | include file ; |
+
-
-
+
+
| import-element | → | id |
| | → | id as id |
| import-prefix | → | prefix id |
-
-| xdecl | → | export { id , … , id ,opt } ;opt |
-| ldecl | → | exportopt sealedopt ledger id : type ; |
-
-
-
-
-
-
-| enumdef | → | exportopt enum enum-name { id , …¹ , id ,opt } ;opt |
-
+
+| export-form | → | export { id , … , id ,opt } ;opt |
+| ledger-declaration | → | exportopt sealedopt ledger id : type ; |
+
+
+
+
+| enum-declaration | → | exportopt enum enum-name { id , …¹ , id ,opt } ;opt |
+
+
+
@@ -55,9 +55,8 @@ Compact Grammar
-
-
-| pattern-tuple-elt | → | (empty) |
| | → | pattern |
+
+
@@ -70,9 +69,9 @@ Compact Grammar
-| expr9 | → | fun ( expr , … , expr ,opt ) |
| | → | map ( fun , expr , …¹ , expr ,opt ) |
| | → | fold ( fun , expr , expr , …¹ , expr ,opt ) |
| | → | slice < tsize > ( expr , expr ) |
| | → | [ tuple-arg , … , tuple-arg ,opt ] |
| | → | Bytes [ bytes-arg , … , bytes-arg ,opt ] |
| | → | tref { struct-arg , … , struct-arg ,opt } |
| | → | assert ( expr , str ) |
| | → | disclose ( expr ) |
| | → | term |
+| expr9 | → | fun ( expr , … , expr ,opt ) |
| | → | map ( fun , expr , …¹ , expr ,opt ) |
| | → | fold ( fun , expr , expr , …¹ , expr ,opt ) |
| | → | slice < tsize > ( expr , expr ) |
| | → | [ tuple-arg , … , tuple-arg ,opt ] |
| | → | Bytes [ tuple-arg , … , tuple-arg ,opt ] |
| | → | tref { struct-arg , … , struct-arg ,opt } |
| | → | assert ( expr , str ) |
| | → | disclose ( expr ) |
| | → | term |
-
+| tuple-arg | → | expr |
| | → | ... expr |
| bytes-arg | → | tuple-arg |
From 4857655e51f39b79bda2830890642d983ed7580a Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Mon, 9 Mar 2026 18:40:33 +0100
Subject: [PATCH 02/41] first cut at markdown version of compact-grammar.mdx
along with corresponding changes to custom.css
---
docs/compact/reference/compact-grammar.mdx | 484 ++++++++++++++++++++-
src/css/custom.css | 9 +-
static/language/compact.html | 81 ----
3 files changed, 483 insertions(+), 91 deletions(-)
delete mode 100644 static/language/compact.html
diff --git a/docs/compact/reference/compact-grammar.mdx b/docs/compact/reference/compact-grammar.mdx
index f8f35f2b..35530c4b 100644
--- a/docs/compact/reference/compact-grammar.mdx
+++ b/docs/compact/reference/compact-grammar.mdx
@@ -1,12 +1,478 @@
----
-SPDX-License-Identifier: Apache-2.0
-copyright: This file is part of midnight-docs. Copyright (C) 2025 Midnight Foundation. Licensed under the Apache License, Version 2.0 (the "License"); You may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-title: Formal grammar
-sidebar_position: 15
----
-# Formal grammar
-import Iframe from "@site/src/components/IFrame/Iframe";
-
+
+
+# Compact Grammar
+
+Compact language version 0.21.0.
+
+Notational note: In the grammar productions below, ellipses are used to specify repetition. The notation X ... X, where X is a grammar symbol, represents zero or more occurrences of X. The notation X , ... , X, where X is a grammar symbol and , is a separator, represents zero or more occurrences of X separated by ,. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one X. When such a sequence is followed by ,opt, an optional trailing separator is allowed, but only if there is at least one X. For example, id … id represents zero or more ids, and expr , …¹ , expr ,opt represents one or more comma-separated exprs possibly followed by an extra comma. There are two separators: comma and semicolon.
+### end-of-file (*eof*)
+
+end of file
+### identifier (*id*, *module-name*, *function-name*, *struct-name*, *enum-name*, *contract-name*, *tvar-name*, *type-name*)
+
+identifiers have the same syntax as Typescript identifiers
+### field-literal (*nat*)
+
+a field literal is 0 or a natural number formed from a sequence of digits starting with 1-9, e.g. 723, whose value does not exceed the maximum field value
+### string-literal (*str*, *file*)
+
+a string literal has the same syntax as a Typescript string
+### version-literal (*version*)
+
+a version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2.3, representing major, minor, and bugfix versions
+### Compact (**program**)
+
+| | | |
+|-----------------|--------|---------------------------------------------------|
+| *program* | → | *pelt* … *pelt* *eof* |
+
+### Program-element (**pelt**)
+
+| | | |
+|--------------|--------|--------------------------------------|
+| *pelt* | → | *pragma-form* |
+| | → | *module-definition* |
+| | → | *import-form* |
+| | → | *export-form* |
+| | → | *include-form* |
+| | → | *struct-declaration* |
+| | → | *enum-declaration* |
+| | → | *contract-declaration* |
+| | → | *type-alias-declaration* |
+| | → | *ledger-declaration* |
+| | → | *witness-declaration* |
+| | → | *constructor-definition* |
+| | → | *circuit-definition* |
+
+### Pragma (**pragma-form**)
+
+| | | |
+|---------------------|--------|-----------------------------------------------------------------------------------------------------------|
+| *pragma-form* | → | pragma *id* *version-expr* ; |
+
+### Version-expression (**version-expr**)
+
+| | | |
+|----------------------|--------|--------------------------------------------------------------------------------------------------|
+| *version-expr* | → | *version-expr* \|\| *version-expr0* |
+| | → | *version-expr0* |
+
+### Version-expression0 (**version-expr0**)
+
+| | | |
+|----------------------------------|--------|--------------------------------------------------------------------------------------------------------|
+| *version-expr0* | → | *version-expr0* && *version-term* |
+| | → | *version-term* |
+
+### Version-Term (**version-term**)
+
+| | | |
+|----------------------|--------|--------------------------------------------------------------------------------------|
+| *version-term* | → | *version-atom* |
+| | → | ! *version-atom* |
+| | → | < *version-atom* |
+| | → | <= *version-atom* |
+| | → | >= *version-atom* |
+| | → | > *version-atom* |
+| | → | ( *version-expr* ) |
+
+### Version-atom (**version-atom**)
+
+| | | |
+|----------------------|--------|-----------------------|
+| *version-atom* | → | *nat* |
+| | → | *version* |
+
+### Include (**include-form**)
+
+| | | |
+|----------------------|--------|------------------------------------------------------------------------------------|
+| *include-form* | → | include *file* ; |
+
+### Module-definition (**module-definition**)
+
+| | | |
+|---------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *module-definition* | → | exportopt module *module-name* *gparams*opt \{ *pelt* … *pelt* } |
+
+### Generic-parameter-list (**gparams**)
+
+| | | |
+|-----------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *gparams* | → | < *generic-param* , … , *generic-param* ,opt > |
+
+### Generic-parameter (**generic-param**)
+
+| | | |
+|-----------------------|--------|------------------------------------------------------|
+| *generic-param* | → | # *tvar-name* |
+| | → | *tvar-name* |
+
+### Import-declaration (**import-form**)
+
+| | | |
+|---------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *import-form* | → | import *import-selection*opt *import-name* *gargs*opt *import-prefix*opt ; |
+
+### Import-selection (**import-selection**)
+
+| | | |
+|--------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *import-selection* | → | \{ *import-element* , … , *import-element* ,opt } from |
+
+### Import-element (**import-element**)
+
+| | | |
+|------------------------|--------|----------------------------------------------------------------|
+| *import-element* | → | *id* |
+| | → | *id* as *id* |
+
+### Import-name (**import-name**)
+
+| | | |
+|---------------------|--------|--------------------|
+| *import-name* | → | *id* |
+| | → | *file* |
+
+### Import-prefix (**import-prefix**)
+
+| | | |
+|-----------------------|--------|----------------------------------------------------|
+| *import-prefix* | → | prefix *id* |
+
+### Generic-argument-list (**gargs**)
+
+| | | |
+|---------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *gargs* | → | < *garg* , … , *garg* ,opt > |
+
+### Generic-argument (**garg**)
+
+| | | |
+|--------------|--------|--------------------|
+| *garg* | → | *nat* |
+| | → | *type* |
+
+### Export-declaration (**export-form**)
+
+| | | |
+|---------------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *export-form* | → | export \{ *id* , … , *id* ,opt } ;opt |
+
+### Ledger-declaration (**ledger-declaration**)
+
+| | | |
+|----------------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *ledger-declaration* | → | exportopt sealedopt ledger *id* : *type* ; |
+
+### Witness-declaration (**witness-declaration**)
+
+| | | |
+|-----------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *witness-declaration* | → | exportopt witness *id* *gparams*opt *simple-parameter-list* : *type* ; |
+
+### Constructor (**constructor-definition**)
+
+| | | |
+|--------------------------------|--------|------------------------------------------------------------------------------------------------|
+| *constructor-definition* | → | constructor *pattern-parameter-list* *block* |
+
+### Circuit-definition (**circuit-definition**)
+
+| | | |
+|----------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *circuit-definition* | → | exportopt pureopt circuit *function-name* *gparams*opt *pattern-parameter-list* : *type* *block* |
+
+### Structure-declaration (**struct-declaration**)
+
+| | | |
+|----------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *struct-declaration* | → | exportopt struct *struct-name* *gparams*opt \{ *typed-identifier* ; … ; *typed-identifier* ;opt } ;opt |
+| | → | exportopt struct *struct-name* *gparams*opt \{ *typed-identifier* , … , *typed-identifier* ,opt } ;opt |
+
+### Enum-declaration (**enum-declaration**)
+
+| | | |
+|--------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *enum-declaration* | → | exportopt enum *enum-name* \{ *id* , …¹ , *id* ,opt } ;opt |
+
+### External-contract-declaration (**contract-declaration**)
+
+| | | |
+|------------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *contract-declaration* | → | exportopt contract *contract-name* \{ *circuit-declaration* ; … ; *circuit-declaration* ;opt } ;opt |
+| | → | exportopt contract *contract-name* \{ *circuit-declaration* , … , *circuit-declaration* ,opt } ;opt |
+
+### External-contract-circuit (**circuit-declaration**)
+
+| | | |
+|-----------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *circuit-declaration* | → | pureopt circuit *id* *simple-parameter-list* : *type* |
+
+### Type-declaration (**type-alias-declaration**)
+
+| | | |
+|--------------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *type-alias-declaration* | → | exportopt newopt type *type-name* *gparams*opt = *type* ; |
+
+### Typed-identifier (**typed-identifier**)
+
+| | | |
+|--------------------------|--------|-----------------------------------------------------------------|
+| *typed-identifier* | → | *id* : *type* |
+
+### Simple-parameter-list (**simple-parameter-list**)
+
+| | | |
+|-------------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *simple-parameter-list* | → | ( *typed-identifier* , … , *typed-identifier* ,opt ) |
+
+### Typed-pattern (**typed-pattern**)
+
+| | | |
+|-----------------------|--------|----------------------------------------------------------------------|
+| *typed-pattern* | → | *pattern* : *type* |
+
+### Pattern-parameter-list (**pattern-parameter-list**)
+
+| | | |
+|--------------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *pattern-parameter-list* | → | ( *typed-pattern* , … , *typed-pattern* ,opt ) |
+
+### Type (**type**)
+
+| | | |
+|--------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *type* | → | *tref* |
+| | → | Boolean |
+| | → | Field |
+| | → | Uint < *tsize* > |
+| | → | Uint < *tsize* .. *tsize* > |
+| | → | Bytes < *tsize* > |
+| | → | Opaque < *str* > |
+| | → | Vector < *tsize* , *type* > |
+| | → | [ *type* , … , *type* ,opt ] |
+
+### Type-reference (**tref**)
+
+| | | |
+|--------------|--------|---------------------------------------------------|
+| *tref* | → | *id* *gargs*opt |
+
+### Type-size (**tsize**)
+
+| | | |
+|---------------|--------|-------------------|
+| *tsize* | → | *nat* |
+| | → | *id* |
+
+### Block (**block**)
+
+| | | |
+|---------------|--------|---------------------------------------------------------------------------------------------|
+| *block* | → | \{ *stmt* … *stmt* } |
+
+### Statement (**stmt**)
+
+| | | |
+|--------------|--------|----------------------------------------------------------------------------------------------------------------------------------|
+| *stmt* | → | if ( *expr-seq* ) *stmt* |
+| | → | *stmt0* |
+
+### Statement0 (**stmt0**)
+
+| | | |
+|--------------------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *stmt0* | → | *expr-seq* ; |
+| | → | const *cbinding* , …¹ , *cbinding* ; |
+| | → | if ( *expr-seq* ) *stmt0* else *stmt* |
+| | → | for ( const *id* of *nat* .. *nat* ) *stmt* |
+| | → | for ( const *id* of *expr-seq* ) *stmt* |
+| | → | return *expr-seq* ; |
+| | → | return ; |
+| | → | *block* |
+
+### Pattern (**pattern**)
+
+| | | |
+|-----------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *pattern* | → | *id* |
+| | → | [ *pattern*opt , … , *pattern*opt ,opt ] |
+| | → | \{ *pattern-struct-elt* , … , *pattern-struct-elt* ,opt } |
+
+### Pattern-struct-element (**pattern-struct-elt**)
+
+| | | |
+|----------------------------|--------|--------------------------------------------------------------------|
+| *pattern-struct-elt* | → | *id* |
+| | → | *id* : *pattern* |
+
+### Expression-sequence (**expr-seq**)
+
+| | | |
+|------------------|--------|----------------------------------------------------------------------------------------------------------------------------|
+| *expr-seq* | → | *expr* |
+| | → | *expr* , …¹ , *expr* , *expr* |
+
+### Expression (**expr**)
+
+| | | |
+|--------------|--------|------------------------------------------------------------------------------------------------------------------------------|
+| *expr* | → | *expr0* ? *expr* : *expr* |
+| | → | *expr0* = *expr* |
+| | → | *expr0* += *expr* |
+| | → | *expr0* -= *expr* |
+| | → | *expr0* |
+
+### Expression0 (**expr0**)
+
+| | | |
+|--------------------------|--------|----------------------------------------------------------------------------------------------|
+| *expr0* | → | *expr0* \|\| *expr1* |
+| | → | *expr1* |
+
+### Expression1 (**expr1**)
+
+| | | |
+|--------------------------|--------|----------------------------------------------------------------------------------------------------|
+| *expr1* | → | *expr1* && *expr2* |
+| | → | *expr2* |
+
+### Expression2 (**expr2**)
+
+| | | |
+|--------------------------|--------|--------------------------------------------------------------------------------------------|
+| *expr2* | → | *expr2* == *expr3* |
+| | → | *expr2* != *expr3* |
+| | → | *expr3* |
+
+### Expression3 (**expr3**)
+
+| | | |
+|--------------------------|--------|-----------------------------------------------------------------------------------------------|
+| *expr3* | → | *expr4* < *expr4* |
+| | → | *expr4* <= *expr4* |
+| | → | *expr4* >= *expr4* |
+| | → | *expr4* > *expr4* |
+| | → | *expr4* |
+
+### Expression4 (**expr4**)
+
+| | | |
+|--------------------------|--------|--------------------------------------------------------------------------------|
+| *expr4* | → | *expr4* as *type* |
+| | → | *expr5* |
+
+### Expression5 (**expr5**)
+
+| | | |
+|--------------------------|--------|-------------------------------------------------------------------------------------------|
+| *expr5* | → | *expr5* + *expr6* |
+| | → | *expr5* - *expr6* |
+| | → | *expr6* |
+
+### Expression6 (**expr6**)
+
+| | | |
+|--------------------------|--------|-------------------------------------------------------------------------------------------|
+| *expr6* | → | *expr6* * *expr7* |
+| | → | *expr7* |
+
+### Expression7 (**expr7**)
+
+| | | |
+|--------------------------|--------|-------------------------------------------------------------|
+| *expr7* | → | ! *expr7* |
+| | → | *expr8* |
+
+### Expression8 (**expr8**)
+
+| | | |
+|--------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *expr8* | → | *expr8* [ *expr* ] |
+| | → | *expr8* . *id* |
+| | → | *expr8* . *id* ( *expr* , … , *expr* ,opt ) |
+| | → | *expr9* |
+
+### Expression9 (**expr9**)
+
+| | | |
+|--------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *expr9* | → | *fun* ( *expr* , … , *expr* ,opt ) |
+| | → | map ( *fun* , *expr* , …¹ , *expr* ,opt ) |
+| | → | fold ( *fun* , *expr* , *expr* , …¹ , *expr* ,opt ) |
+| | → | slice < *tsize* > ( *expr* , *expr* ) |
+| | → | [ *tuple-arg* , … , *tuple-arg* ,opt ] |
+| | → | Bytes [ *tuple-arg* , … , *tuple-arg* ,opt ] |
+| | → | *tref* \{ *struct-arg* , … , *struct-arg* ,opt } |
+| | → | assert ( *expr* , *str* ) |
+| | → | disclose ( *expr* ) |
+| | → | *term* |
+
+### Term (**term**)
+
+| | | |
+|--------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *term* | → | *id* |
+| | → | true |
+| | → | false |
+| | → | *nat* |
+| | → | *str* |
+| | → | pad ( *nat* , *str* ) |
+| | → | default < *type* > |
+| | → | ( *expr-seq* ) |
+
+### Tuple-argument (**tuple-arg**, **bytes-arg**)
+
+| | | |
+|-------------------|--------|---------------------------------------------------|
+| *tuple-arg* | → | *expr* |
+| | → | ... *expr* |
+| *bytes-arg* | → | *tuple-arg* |
+
+### Structure-argument (**struct-arg**)
+
+| | | |
+|--------------------|--------|-----------------------------------------------------------------|
+| *struct-arg* | → | *expr* |
+| | → | *id* : *expr* |
+| | → | ... *expr* |
+
+### Function (**fun**)
+
+| | | |
+|-------------|--------|-------------------------------------------------------------------------------------------------------------------------------|
+| *fun* | → | *id* *gargs*opt |
+| | → | *arrow-parameter-list* *return-type*opt => *block* |
+| | → | *arrow-parameter-list* *return-type*opt => *expr* |
+| | → | ( *fun* ) |
+
+### Return-type (**return-type**)
+
+| | | |
+|---------------------|--------|-------------------------------------------------|
+| *return-type* | → | : *type* |
+
+### Optionally-typed-pattern (**optionally-typed-pattern**)
+
+| | | |
+|----------------------------------|--------|-----------------------------|
+| *optionally-typed-pattern* | → | *pattern* |
+| | → | *typed-pattern* |
+
+### Const-Binding (**cbinding**)
+
+| | | |
+|------------------|--------|---------------------------------------------------------------------------------------|
+| *cbinding* | → | *optionally-typed-pattern* = *expr* |
+
+### Arrow-parameter-list (**arrow-parameter-list**)
+
+| | | |
+|------------------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *arrow-parameter-list* | → | ( *optionally-typed-pattern* , … , *optionally-typed-pattern* ,opt ) |
+
+
diff --git a/src/css/custom.css b/src/css/custom.css
index fbc9ee72..d47b7e44 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -606,7 +606,14 @@ pre {
border-collapse: separate;
border-spacing: 0;
--ifm-table-stripe-background: none;
- border: 1px solid; /* Add border to the table */
+}
+
+.lang-ref-table thead {
+ display: none
+}
+
+.lang-ref-table tbody tr {
+ border: none
}
.lang-ref-table td,
diff --git a/static/language/compact.html b/static/language/compact.html
deleted file mode 100644
index c243b726..00000000
--- a/static/language/compact.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-Compact
-
-Compact Grammar
-Compact language version 0.21.0.
-
Notational note: In the grammar productions below, ellipses are used to specify repetition. The notation X ... X, where X is a grammar symbol, represents zero or more occurrences of X. The notation X , ... , X, where X is a grammar symbol and , is a separator, represents zero or more occurrences of X separated by ,. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one X. When such a sequence is followed by ,opt, an optional trailing separator is allowed, but only if there is at least one X. For example, id … id represents zero or more ids, and expr , …¹ , expr ,opt represents one or more comma-separated exprs possibly followed by an extra comma. There are two separators: comma and semicolon.
-
-end of file
-
-identifiers have the same syntax as Typescript identifiers
-
-a field literal is 0 or a natural number formed from a sequence of digits starting with 1-9, e.g. 723, whose value does not exceed the maximum field value
-
-a string literal has the same syntax as a Typescript string
-
-a version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2.3, representing major, minor, and bugfix versions
-
-
-
-
-
-
-
-
-| include-form | → | include file ; |
-
-
-
-
-
-| import-element | → | id |
| | → | id as id |
-
-| import-prefix | → | prefix id |
-
-
-| export-form | → | export { id , … , id ,opt } ;opt |
-| ledger-declaration | → | exportopt sealedopt ledger id : type ; |
-
-
-
-
-| enum-declaration | → | exportopt enum enum-name { id , …¹ , id ,opt } ;opt |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-| expr9 | → | fun ( expr , … , expr ,opt ) |
| | → | map ( fun , expr , …¹ , expr ,opt ) |
| | → | fold ( fun , expr , expr , …¹ , expr ,opt ) |
| | → | slice < tsize > ( expr , expr ) |
| | → | [ tuple-arg , … , tuple-arg ,opt ] |
| | → | Bytes [ tuple-arg , … , tuple-arg ,opt ] |
| | → | tref { struct-arg , … , struct-arg ,opt } |
| | → | assert ( expr , str ) |
| | → | disclose ( expr ) |
| | → | term |
-
-| tuple-arg | → | expr |
| | → | ... expr |
| bytes-arg | → | tuple-arg |
-
-
-
-
-
-
-
\ No newline at end of file
From b2574ebdd47e246ab5569e9df3b11722f3846789 Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Mon, 9 Mar 2026 21:14:34 +0100
Subject: [PATCH 03/41] commiting the latest compact-grammar.mdx plus some
changes to custom.css to make the table rendering prettier.
---
docs/compact/reference/compact-grammar.mdx | 884 ++++++++++++---------
src/css/custom.css | 12 +-
2 files changed, 512 insertions(+), 384 deletions(-)
diff --git a/docs/compact/reference/compact-grammar.mdx b/docs/compact/reference/compact-grammar.mdx
index 35530c4b..5c537079 100644
--- a/docs/compact/reference/compact-grammar.mdx
+++ b/docs/compact/reference/compact-grammar.mdx
@@ -1,478 +1,598 @@
+# Compact grammar
+Compact language version 0.21.0.
+Notational note: In the grammar below, terminals are in `monospaced` font. Non-terminals are in *emphasized* font. Alternation is indicated by a vertical bar (`|`). Optional items are indicated by the superscript opt. Repetition is specified by ellipses. The notation *X* … *X*, where *X* is a grammar symbol, represents zero or more occurrences of *X*. The notation *X* `,` … `,` *X*, where *X* is a grammar symbol and `,` is a literal comma, represents zero or more occurrences of *X* separated by commas. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one *X*. When such a sequence is followed by *,*opt, an optional trailing comma is allowed, but only if there is at least one *X*. For example, *id* … *id* represents zero or more *id*s, and *expr* `,` …¹ `,` *expr* `,`opt represents one or more comma-separated *expr*s possibly followed by an extra comma. The rules involving commas apply equally to semicolons, i.e., apply when `,` is replaced by `;`.
+#### end-of-file (*eof*)
+End of file.
-# Compact Grammar
+#### identifier (*id*, *module-name*, *function-name*, *struct-name*, *enum-name*, *contract-name*, *tvar-name*, *type-name*)
-Compact language version 0.21.0.
+Identifiers have the same syntax as Typescript identifiers.
+
+#### field-literal (*nat*)
-Notational note: In the grammar productions below, ellipses are used to specify repetition. The notation X ... X, where X is a grammar symbol, represents zero or more occurrences of X. The notation X , ... , X, where X is a grammar symbol and , is a separator, represents zero or more occurrences of X separated by ,. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one X. When such a sequence is followed by ,opt, an optional trailing separator is allowed, but only if there is at least one X. For example, id … id represents zero or more ids, and expr , …¹ , expr ,opt represents one or more comma-separated exprs possibly followed by an extra comma. There are two separators: comma and semicolon.
-### end-of-file (*eof*)
+A field literal is 0 or a natural number formed from a sequence of digits starting with 1-9, e.g. 723, whose value does not exceed the maximum field value.
-end of file
-### identifier (*id*, *module-name*, *function-name*, *struct-name*, *enum-name*, *contract-name*, *tvar-name*, *type-name*)
+#### string-literal (*str*, *file*)
-identifiers have the same syntax as Typescript identifiers
-### field-literal (*nat*)
+A string literal has the same syntax as a Typescript string.
-a field literal is 0 or a natural number formed from a sequence of digits starting with 1-9, e.g. 723, whose value does not exceed the maximum field value
-### string-literal (*str*, *file*)
+#### version-literal (*version*)
-a string literal has the same syntax as a Typescript string
-### version-literal (*version*)
+A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2.3, representing major, minor, and bugfix versions.
+
+#### Compact (**program**)
-a version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2.3, representing major, minor, and bugfix versions
-### Compact (**program**)
-| | | |
-|-----------------|--------|---------------------------------------------------|
-| *program* | → | *pelt* … *pelt* *eof* |
+| | | |
+|-----------|---------|----------------------------|
+| *program* | ⟶ | *pelt* … *pelt* *eof* |
-### Program-element (**pelt**)
+
+#### Program-element (**pelt**)
+
-| | | |
-|--------------|--------|--------------------------------------|
-| *pelt* | → | *pragma-form* |
-| | → | *module-definition* |
-| | → | *import-form* |
-| | → | *export-form* |
-| | → | *include-form* |
-| | → | *struct-declaration* |
-| | → | *enum-declaration* |
-| | → | *contract-declaration* |
-| | → | *type-alias-declaration* |
-| | → | *ledger-declaration* |
-| | → | *witness-declaration* |
-| | → | *constructor-definition* |
-| | → | *circuit-definition* |
+| | | |
+|--------|---------|--------------------------|
+| *pelt* | ⟶ | *pragma-form* |
+| | \| | *module-definition* |
+| | \| | *import-form* |
+| | \| | *export-form* |
+| | \| | *include-form* |
+| | \| | *struct-declaration* |
+| | \| | *enum-declaration* |
+| | \| | *contract-declaration* |
+| | \| | *type-alias-declaration* |
+| | \| | *ledger-declaration* |
+| | \| | *witness-declaration* |
+| | \| | *constructor-definition* |
+| | \| | *circuit-definition* |
-### Pragma (**pragma-form**)
+
+#### Pragma (**pragma-form**)
+
-| | | |
-|---------------------|--------|-----------------------------------------------------------------------------------------------------------|
-| *pragma-form* | → | pragma *id* *version-expr* ; |
+| | | |
+|---------------|---------|----------------------------------|
+| *pragma-form* | ⟶ | `pragma` *id* *version-expr* `;` |
-### Version-expression (**version-expr**)
+
+#### Version-expression (**version-expr**)
+
-| | | |
-|----------------------|--------|--------------------------------------------------------------------------------------------------|
-| *version-expr* | → | *version-expr* \|\| *version-expr0* |
-| | → | *version-expr0* |
+| | | |
+|----------------|---------|--------------------------------------------------|
+| *version-expr* | ⟶ | *version-expr* `\|\|` *version-expr0* |
+| | \| | *version-expr0* |
-### Version-expression0 (**version-expr0**)
+
+#### Version-expression0 (**version-expr0**)
+
-| | | |
-|----------------------------------|--------|--------------------------------------------------------------------------------------------------------|
-| *version-expr0* | → | *version-expr0* && *version-term* |
-| | → | *version-term* |
+| | | |
+|----------------------------|---------|------------------------------------------------|
+| *version-expr0* | ⟶ | *version-expr0* `&&` *version-term* |
+| | \| | *version-term* |
-### Version-Term (**version-term**)
+
+#### Version-Term (**version-term**)
+
-| | | |
-|----------------------|--------|--------------------------------------------------------------------------------------|
-| *version-term* | → | *version-atom* |
-| | → | ! *version-atom* |
-| | → | < *version-atom* |
-| | → | <= *version-atom* |
-| | → | >= *version-atom* |
-| | → | > *version-atom* |
-| | → | ( *version-expr* ) |
+| | | |
+|----------------|---------|------------------------|
+| *version-term* | ⟶ | *version-atom* |
+| | \| | `!` *version-atom* |
+| | \| | `<` *version-atom* |
+| | \| | `<=` *version-atom* |
+| | \| | `>=` *version-atom* |
+| | \| | `>` *version-atom* |
+| | \| | `(` *version-expr* `)` |
-### Version-atom (**version-atom**)
+
+#### Version-atom (**version-atom**)
+
-| | | |
-|----------------------|--------|-----------------------|
-| *version-atom* | → | *nat* |
-| | → | *version* |
+| | | |
+|----------------|---------|-----------|
+| *version-atom* | ⟶ | *nat* |
+| | \| | *version* |
-### Include (**include-form**)
+
+#### Include (**include-form**)
+
-| | | |
-|----------------------|--------|------------------------------------------------------------------------------------|
-| *include-form* | → | include *file* ; |
+| | | |
+|----------------|---------|----------------------|
+| *include-form* | ⟶ | `include` *file* `;` |
-### Module-definition (**module-definition**)
+
+#### Module-definition (**module-definition**)
+
-| | | |
-|---------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *module-definition* | → | exportopt module *module-name* *gparams*opt \{ *pelt* … *pelt* } |
+| | | |
+|---------------------|---------|----------------------------------------------------------------------------------------------------|
+| *module-definition* | ⟶ | `export`opt `module` *module-name* *gparams*opt `{` *pelt* … *pelt* `}` |
-### Generic-parameter-list (**gparams**)
+
+#### Generic-parameter-list (**gparams**)
+
-| | | |
-|-----------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *gparams* | → | < *generic-param* , … , *generic-param* ,opt > |
+| | | |
+|-----------|---------|--------------------------------------------------------------------------|
+| *gparams* | ⟶ | `<` *generic-param* `,` … `,` *generic-param* `,`opt `>` |
-### Generic-parameter (**generic-param**)
+
+#### Generic-parameter (**generic-param**)
+
-| | | |
-|-----------------------|--------|------------------------------------------------------|
-| *generic-param* | → | # *tvar-name* |
-| | → | *tvar-name* |
+| | | |
+|-----------------|---------|-----------------|
+| *generic-param* | ⟶ | `#` *tvar-name* |
+| | \| | *tvar-name* |
-### Import-declaration (**import-form**)
+
+#### Import-declaration (**import-form**)
+
-| | | |
-|---------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *import-form* | → | import *import-selection*opt *import-name* *gargs*opt *import-prefix*opt ; |
+| | | |
+|---------------|---------|-----------------------------------------------------------------------------------------------------------------|
+| *import-form* | ⟶ | `import` *import-selection*opt *import-name* *gargs*opt *import-prefix*opt `;` |
-### Import-selection (**import-selection**)
+
+#### Import-selection (**import-selection**)
+
-| | | |
-|--------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *import-selection* | → | \{ *import-element* , … , *import-element* ,opt } from |
+| | | |
+|--------------------|---------|-----------------------------------------------------------------------------------|
+| *import-selection* | ⟶ | `{` *import-element* `,` … `,` *import-element* `,`opt `}` `from` |
-### Import-element (**import-element**)
+
+#### Import-element (**import-element**)
+
-| | | |
-|------------------------|--------|----------------------------------------------------------------|
-| *import-element* | → | *id* |
-| | → | *id* as *id* |
+| | | |
+|------------------|---------|----------------|
+| *import-element* | ⟶ | *id* |
+| | \| | *id* `as` *id* |
-### Import-name (**import-name**)
+
+#### Import-name (**import-name**)
+
-| | | |
-|---------------------|--------|--------------------|
-| *import-name* | → | *id* |
-| | → | *file* |
+| | | |
+|---------------|---------|--------|
+| *import-name* | ⟶ | *id* |
+| | \| | *file* |
-### Import-prefix (**import-prefix**)
+
+#### Import-prefix (**import-prefix**)
+
-| | | |
-|-----------------------|--------|----------------------------------------------------|
-| *import-prefix* | → | prefix *id* |
+| | | |
+|-----------------|---------|---------------|
+| *import-prefix* | ⟶ | `prefix` *id* |
-### Generic-argument-list (**gargs**)
+
+#### Generic-argument-list (**gargs**)
+
-| | | |
-|---------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *gargs* | → | < *garg* , … , *garg* ,opt > |
+| | | |
+|---------|---------|--------------------------------------------------------|
+| *gargs* | ⟶ | `<` *garg* `,` … `,` *garg* `,`opt `>` |
-### Generic-argument (**garg**)
+
+#### Generic-argument (**garg**)
+
-| | | |
-|--------------|--------|--------------------|
-| *garg* | → | *nat* |
-| | → | *type* |
+| | | |
+|--------|---------|--------|
+| *garg* | ⟶ | *nat* |
+| | \| | *type* |
-### Export-declaration (**export-form**)
+
+#### Export-declaration (**export-form**)
+
-| | | |
-|---------------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *export-form* | → | export \{ *id* , … , *id* ,opt } ;opt |
+| | | |
+|---------------|---------|-------------------------------------------------------------------------------|
+| *export-form* | ⟶ | `export` `{` *id* `,` … `,` *id* `,`opt `}` `;`opt |
-### Ledger-declaration (**ledger-declaration**)
+
+#### Ledger-declaration (**ledger-declaration**)
+
-| | | |
-|----------------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *ledger-declaration* | → | exportopt sealedopt ledger *id* : *type* ; |
+| | | |
+|----------------------|---------|----------------------------------------------------------------------------|
+| *ledger-declaration* | ⟶ | `export`opt `sealed`opt `ledger` *id* `:` *type* `;` |
-### Witness-declaration (**witness-declaration**)
+
+#### Witness-declaration (**witness-declaration**)
+
-| | | |
-|-----------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *witness-declaration* | → | exportopt witness *id* *gparams*opt *simple-parameter-list* : *type* ; |
+| | | |
+|-----------------------|---------|------------------------------------------------------------------------------------------------------|
+| *witness-declaration* | ⟶ | `export`opt `witness` *id* *gparams*opt *simple-parameter-list* `:` *type* `;` |
-### Constructor (**constructor-definition**)
+
+#### Constructor (**constructor-definition**)
+
-| | | |
-|--------------------------------|--------|------------------------------------------------------------------------------------------------|
-| *constructor-definition* | → | constructor *pattern-parameter-list* *block* |
+| | | |
+|--------------------------|---------|------------------------------------------------|
+| *constructor-definition* | ⟶ | `constructor` *pattern-parameter-list* *block* |
-### Circuit-definition (**circuit-definition**)
+
+#### Circuit-definition (**circuit-definition**)
+
-| | | |
-|----------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *circuit-definition* | → | exportopt pureopt circuit *function-name* *gparams*opt *pattern-parameter-list* : *type* *block* |
+| | | |
+|----------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------|
+| *circuit-definition* | ⟶ | `export`opt `pure`opt `circuit` *function-name* *gparams*opt *pattern-parameter-list* `:` *type* *block* |
-### Structure-declaration (**struct-declaration**)
+
+#### Structure-declaration (**struct-declaration**)
+
-| | | |
-|----------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *struct-declaration* | → | exportopt struct *struct-name* *gparams*opt \{ *typed-identifier* ; … ; *typed-identifier* ;opt } ;opt |
-| | → | exportopt struct *struct-name* *gparams*opt \{ *typed-identifier* , … , *typed-identifier* ,opt } ;opt |
+| | | |
+|----------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *struct-declaration* | ⟶ | `export`opt `struct` *struct-name* *gparams*opt `{` *typed-identifier* `;` … `;` *typed-identifier* `;`opt `}` `;`opt |
+| | \| | `export`opt `struct` *struct-name* *gparams*opt `{` *typed-identifier* `,` … `,` *typed-identifier* `,`opt `}` `;`opt |
-### Enum-declaration (**enum-declaration**)
+
+#### Enum-declaration (**enum-declaration**)
+
-| | | |
-|--------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *enum-declaration* | → | exportopt enum *enum-name* \{ *id* , …¹ , *id* ,opt } ;opt |
+| | | |
+|--------------------|---------|----------------------------------------------------------------------------------------------------------------------|
+| *enum-declaration* | ⟶ | `export`opt `enum` *enum-name* `{` *id* `,` …¹ `,` *id* `,`opt `}` `;`opt |
-### External-contract-declaration (**contract-declaration**)
+
+#### External-contract-declaration (**contract-declaration**)
+
-| | | |
-|------------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *contract-declaration* | → | exportopt contract *contract-name* \{ *circuit-declaration* ; … ; *circuit-declaration* ;opt } ;opt |
-| | → | exportopt contract *contract-name* \{ *circuit-declaration* , … , *circuit-declaration* ,opt } ;opt |
+| | | |
+|------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *contract-declaration* | ⟶ | `export`opt `contract` *contract-name* `{` *circuit-declaration* `;` … `;` *circuit-declaration* `;`opt `}` `;`opt |
+| | \| | `export`opt `contract` *contract-name* `{` *circuit-declaration* `,` … `,` *circuit-declaration* `,`opt `}` `;`opt |
-### External-contract-circuit (**circuit-declaration**)
+
+#### External-contract-circuit (**circuit-declaration**)
+
-| | | |
-|-----------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *circuit-declaration* | → | pureopt circuit *id* *simple-parameter-list* : *type* |
+| | | |
+|-----------------------|---------|------------------------------------------------------------------------|
+| *circuit-declaration* | ⟶ | `pure`opt `circuit` *id* *simple-parameter-list* `:` *type* |
-### Type-declaration (**type-alias-declaration**)
+
+#### Type-declaration (**type-alias-declaration**)
+
-| | | |
-|--------------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *type-alias-declaration* | → | exportopt newopt type *type-name* *gparams*opt = *type* ; |
+| | | |
+|--------------------------|---------|------------------------------------------------------------------------------------------------------|
+| *type-alias-declaration* | ⟶ | `export`opt `new`opt `type` *type-name* *gparams*opt `=` *type* `;` |
-### Typed-identifier (**typed-identifier**)
+
+#### Typed-identifier (**typed-identifier**)
+
-| | | |
-|--------------------------|--------|-----------------------------------------------------------------|
-| *typed-identifier* | → | *id* : *type* |
+| | | |
+|--------------------|---------|-----------------|
+| *typed-identifier* | ⟶ | *id* `:` *type* |
-### Simple-parameter-list (**simple-parameter-list**)
+
+#### Simple-parameter-list (**simple-parameter-list**)
+
-| | | |
-|-------------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *simple-parameter-list* | → | ( *typed-identifier* , … , *typed-identifier* ,opt ) |
+| | | |
+|-------------------------|---------|--------------------------------------------------------------------------------|
+| *simple-parameter-list* | ⟶ | `(` *typed-identifier* `,` … `,` *typed-identifier* `,`opt `)` |
-### Typed-pattern (**typed-pattern**)
+
+#### Typed-pattern (**typed-pattern**)
+
-| | | |
-|-----------------------|--------|----------------------------------------------------------------------|
-| *typed-pattern* | → | *pattern* : *type* |
+| | | |
+|-----------------|---------|----------------------|
+| *typed-pattern* | ⟶ | *pattern* `:` *type* |
-### Pattern-parameter-list (**pattern-parameter-list**)
+
+#### Pattern-parameter-list (**pattern-parameter-list**)
+
-| | | |
-|--------------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *pattern-parameter-list* | → | ( *typed-pattern* , … , *typed-pattern* ,opt ) |
+| | | |
+|--------------------------|---------|--------------------------------------------------------------------------|
+| *pattern-parameter-list* | ⟶ | `(` *typed-pattern* `,` … `,` *typed-pattern* `,`opt `)` |
-### Type (**type**)
+
+#### Type (**type**)
+
-| | | |
-|--------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *type* | → | *tref* |
-| | → | Boolean |
-| | → | Field |
-| | → | Uint < *tsize* > |
-| | → | Uint < *tsize* .. *tsize* > |
-| | → | Bytes < *tsize* > |
-| | → | Opaque < *str* > |
-| | → | Vector < *tsize* , *type* > |
-| | → | [ *type* , … , *type* ,opt ] |
+| | | |
+|--------|---------|--------------------------------------------------------|
+| *type* | ⟶ | *tref* |
+| | \| | `Boolean` |
+| | \| | `Field` |
+| | \| | `Uint` `<` *tsize* `>` |
+| | \| | `Uint` `<` *tsize* `..` *tsize* `>` |
+| | \| | `Bytes` `<` *tsize* `>` |
+| | \| | `Opaque` `<` *str* `>` |
+| | \| | `Vector` `<` *tsize* `,` *type* `>` |
+| | \| | `[` *type* `,` … `,` *type* `,`opt `]` |
-### Type-reference (**tref**)
+
+#### Type-reference (**tref**)
+
-| | | |
-|--------------|--------|---------------------------------------------------|
-| *tref* | → | *id* *gargs*opt |
+| | | |
+|--------|---------|----------------------------|
+| *tref* | ⟶ | *id* *gargs*opt |
-### Type-size (**tsize**)
+
+#### Type-size (**tsize**)
+
-| | | |
-|---------------|--------|-------------------|
-| *tsize* | → | *nat* |
-| | → | *id* |
+| | | |
+|---------|---------|-------|
+| *tsize* | ⟶ | *nat* |
+| | \| | *id* |
-### Block (**block**)
+
+#### Block (**block**)
+
-| | | |
-|---------------|--------|---------------------------------------------------------------------------------------------|
-| *block* | → | \{ *stmt* … *stmt* } |
+| | | |
+|---------|---------|------------------------------|
+| *block* | ⟶ | `{` *stmt* … *stmt* `}` |
-### Statement (**stmt**)
+
+#### Statement (**stmt**)
+
-| | | |
-|--------------|--------|----------------------------------------------------------------------------------------------------------------------------------|
-| *stmt* | → | if ( *expr-seq* ) *stmt* |
-| | → | *stmt0* |
+| | | |
+|--------|---------|--------------------------------|
+| *stmt* | ⟶ | `if` `(` *expr-seq* `)` *stmt* |
+| | \| | *stmt0* |
-### Statement0 (**stmt0**)
+
+#### Statement0 (**stmt0**)
+
-| | | |
-|--------------------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *stmt0* | → | *expr-seq* ; |
-| | → | const *cbinding* , …¹ , *cbinding* ; |
-| | → | if ( *expr-seq* ) *stmt0* else *stmt* |
-| | → | for ( const *id* of *nat* .. *nat* ) *stmt* |
-| | → | for ( const *id* of *expr-seq* ) *stmt* |
-| | → | return *expr-seq* ; |
-| | → | return ; |
-| | → | *block* |
+| | | |
+|--------------------|---------|----------------------------------------------------------|
+| *stmt0* | ⟶ | *expr-seq* `;` |
+| | \| | `const` *cbinding* `,` …¹ `,` *cbinding* `;` |
+| | \| | `if` `(` *expr-seq* `)` *stmt0* `else` *stmt* |
+| | \| | `for` `(` `const` *id* `of` *nat* `..` *nat* `)` *stmt* |
+| | \| | `for` `(` `const` *id* `of` *expr-seq* `)` *stmt* |
+| | \| | `return` *expr-seq* `;` |
+| | \| | `return` `;` |
+| | \| | *block* |
-### Pattern (**pattern**)
+
+#### Pattern (**pattern**)
+
-| | | |
-|-----------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *pattern* | → | *id* |
-| | → | [ *pattern*opt , … , *pattern*opt ,opt ] |
-| | → | \{ *pattern-struct-elt* , … , *pattern-struct-elt* ,opt } |
+| | | |
+|-----------|---------|------------------------------------------------------------------------------------------|
+| *pattern* | ⟶ | *id* |
+| | \| | `[` *pattern*opt `,` … `,` *pattern*opt `,`opt `]` |
+| | \| | `{` *pattern-struct-elt* `,` … `,` *pattern-struct-elt* `,`opt `}` |
-### Pattern-struct-element (**pattern-struct-elt**)
+
+#### Pattern-struct-element (**pattern-struct-elt**)
+
+
+| | | |
+|----------------------|---------|--------------------|
+| *pattern-struct-elt* | ⟶ | *id* |
+| | \| | *id* `:` *pattern* |
+
+
+#### Expression-sequence (**expr-seq**)
+
+
+| | | |
+|------------|---------|------------------------------------------------|
+| *expr-seq* | ⟶ | *expr* |
+| | \| | *expr* `,` …¹ `,` *expr* `,` *expr* |
+
+
+#### Expression (**expr**)
+
+
+| | | |
+|--------|---------|------------------------------------------|
+| *expr* | ⟶ | *expr0* `?` *expr* `:` *expr* |
+| | \| | *expr0* `=` *expr* |
+| | \| | *expr0* `+=` *expr* |
+| | \| | *expr0* `-=` *expr* |
+| | \| | *expr0* |
+
+
+#### Expression0 (**expr0**)
+
+
+| | | |
+|--------------------|---------|----------------------------------------------|
+| *expr0* | ⟶ | *expr0* `\|\|` *expr1* |
+| | \| | *expr1* |
+
+
+#### Expression1 (**expr1**)
+
+
+| | | |
+|--------------------|---------|--------------------------------------------|
+| *expr1* | ⟶ | *expr1* `&&` *expr2* |
+| | \| | *expr2* |
+
+
+#### Expression2 (**expr2**)
+
+
+| | | |
+|--------------------|---------|--------------------------------------------|
+| *expr2* | ⟶ | *expr2* `==` *expr3* |
+| | \| | *expr2* `!=` *expr3* |
+| | \| | *expr3* |
+
+
+#### Expression3 (**expr3**)
+
+
+| | | |
+|--------------------|---------|--------------------------------------------|
+| *expr3* | ⟶ | *expr4* `<` *expr4* |
+| | \| | *expr4* `<=` *expr4* |
+| | \| | *expr4* `>=` *expr4* |
+| | \| | *expr4* `>` *expr4* |
+| | \| | *expr4* |
+
+
+#### Expression4 (**expr4**)
+
-| | | |
-|----------------------------|--------|--------------------------------------------------------------------|
-| *pattern-struct-elt* | → | *id* |
-| | → | *id* : *pattern* |
+| | | |
+|--------------------|---------|--------------------------------|
+| *expr4* | ⟶ | *expr4* `as` *type* |
+| | \| | *expr5* |
-### Expression-sequence (**expr-seq**)
+
+#### Expression5 (**expr5**)
+
+
+| | | |
+|--------------------|---------|-------------------------------------------|
+| *expr5* | ⟶ | *expr5* `+` *expr6* |
+| | \| | *expr5* `-` *expr6* |
+| | \| | *expr6* |
+
+
+#### Expression6 (**expr6**)
+
+
+| | | |
+|--------------------|---------|-------------------------------------------|
+| *expr6* | ⟶ | *expr6* `*` *expr7* |
+| | \| | *expr7* |
+
+
+#### Expression7 (**expr7**)
+
-| | | |
-|------------------|--------|----------------------------------------------------------------------------------------------------------------------------|
-| *expr-seq* | → | *expr* |
-| | → | *expr* , …¹ , *expr* , *expr* |
+| | | |
+|--------------------|---------|------------------------|
+| *expr7* | ⟶ | `!` *expr7* |
+| | \| | *expr8* |
-### Expression (**expr**)
-
-| | | |
-|--------------|--------|------------------------------------------------------------------------------------------------------------------------------|
-| *expr* | → | *expr0* ? *expr* : *expr* |
-| | → | *expr0* = *expr* |
-| | → | *expr0* += *expr* |
-| | → | *expr0* -= *expr* |
-| | → | *expr0* |
-
-### Expression0 (**expr0**)
-
-| | | |
-|--------------------------|--------|----------------------------------------------------------------------------------------------|
-| *expr0* | → | *expr0* \|\| *expr1* |
-| | → | *expr1* |
-
-### Expression1 (**expr1**)
-
-| | | |
-|--------------------------|--------|----------------------------------------------------------------------------------------------------|
-| *expr1* | → | *expr1* && *expr2* |
-| | → | *expr2* |
-
-### Expression2 (**expr2**)
-
-| | | |
-|--------------------------|--------|--------------------------------------------------------------------------------------------|
-| *expr2* | → | *expr2* == *expr3* |
-| | → | *expr2* != *expr3* |
-| | → | *expr3* |
-
-### Expression3 (**expr3**)
-
-| | | |
-|--------------------------|--------|-----------------------------------------------------------------------------------------------|
-| *expr3* | → | *expr4* < *expr4* |
-| | → | *expr4* <= *expr4* |
-| | → | *expr4* >= *expr4* |
-| | → | *expr4* > *expr4* |
-| | → | *expr4* |
-
-### Expression4 (**expr4**)
-
-| | | |
-|--------------------------|--------|--------------------------------------------------------------------------------|
-| *expr4* | → | *expr4* as *type* |
-| | → | *expr5* |
-
-### Expression5 (**expr5**)
-
-| | | |
-|--------------------------|--------|-------------------------------------------------------------------------------------------|
-| *expr5* | → | *expr5* + *expr6* |
-| | → | *expr5* - *expr6* |
-| | → | *expr6* |
-
-### Expression6 (**expr6**)
-
-| | | |
-|--------------------------|--------|-------------------------------------------------------------------------------------------|
-| *expr6* | → | *expr6* * *expr7* |
-| | → | *expr7* |
-
-### Expression7 (**expr7**)
-
-| | | |
-|--------------------------|--------|-------------------------------------------------------------|
-| *expr7* | → | ! *expr7* |
-| | → | *expr8* |
-
-### Expression8 (**expr8**)
-
-| | | |
-|--------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *expr8* | → | *expr8* [ *expr* ] |
-| | → | *expr8* . *id* |
-| | → | *expr8* . *id* ( *expr* , … , *expr* ,opt ) |
-| | → | *expr9* |
-
-### Expression9 (**expr9**)
-
-| | | |
-|--------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *expr9* | → | *fun* ( *expr* , … , *expr* ,opt ) |
-| | → | map ( *fun* , *expr* , …¹ , *expr* ,opt ) |
-| | → | fold ( *fun* , *expr* , *expr* , …¹ , *expr* ,opt ) |
-| | → | slice < *tsize* > ( *expr* , *expr* ) |
-| | → | [ *tuple-arg* , … , *tuple-arg* ,opt ] |
-| | → | Bytes [ *tuple-arg* , … , *tuple-arg* ,opt ] |
-| | → | *tref* \{ *struct-arg* , … , *struct-arg* ,opt } |
-| | → | assert ( *expr* , *str* ) |
-| | → | disclose ( *expr* ) |
-| | → | *term* |
-
-### Term (**term**)
-
-| | | |
-|--------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *term* | → | *id* |
-| | → | true |
-| | → | false |
-| | → | *nat* |
-| | → | *str* |
-| | → | pad ( *nat* , *str* ) |
-| | → | default < *type* > |
-| | → | ( *expr-seq* ) |
-
-### Tuple-argument (**tuple-arg**, **bytes-arg**)
-
-| | | |
-|-------------------|--------|---------------------------------------------------|
-| *tuple-arg* | → | *expr* |
-| | → | ... *expr* |
-| *bytes-arg* | → | *tuple-arg* |
-
-### Structure-argument (**struct-arg**)
-
-| | | |
-|--------------------|--------|-----------------------------------------------------------------|
-| *struct-arg* | → | *expr* |
-| | → | *id* : *expr* |
-| | → | ... *expr* |
-
-### Function (**fun**)
-
-| | | |
-|-------------|--------|-------------------------------------------------------------------------------------------------------------------------------|
-| *fun* | → | *id* *gargs*opt |
-| | → | *arrow-parameter-list* *return-type*opt => *block* |
-| | → | *arrow-parameter-list* *return-type*opt => *expr* |
-| | → | ( *fun* ) |
-
-### Return-type (**return-type**)
-
-| | | |
-|---------------------|--------|-------------------------------------------------|
-| *return-type* | → | : *type* |
-
-### Optionally-typed-pattern (**optionally-typed-pattern**)
-
-| | | |
-|----------------------------------|--------|-----------------------------|
-| *optionally-typed-pattern* | → | *pattern* |
-| | → | *typed-pattern* |
-
-### Const-Binding (**cbinding**)
-
-| | | |
-|------------------|--------|---------------------------------------------------------------------------------------|
-| *cbinding* | → | *optionally-typed-pattern* = *expr* |
-
-### Arrow-parameter-list (**arrow-parameter-list**)
-
-| | | |
-|------------------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *arrow-parameter-list* | → |
( *optionally-typed-pattern*
, …
, *optionally-typed-pattern*
,opt ) |
+
+#### Expression
8 (**expr
8**)
+
+
+| | | |
+|--------------------|---------|------------------------------------------------------------------------------------|
+| *expr8* | ⟶ | *expr8* `[` *expr* `]` |
+| | \| | *expr8* `.` *id* |
+| | \| | *expr8* `.` *id* `(` *expr* `,` … `,` *expr* `,`opt `)` |
+| | \| | *expr9* |
+
+
+#### Expression
9 (**expr
9**)
+
+
+| | | |
+|--------------------|---------|------------------------------------------------------------------------------------------|
+| *expr9* | ⟶ | *fun* `(` *expr* `,` … `,` *expr* `,`opt `)` |
+| | \| | `map` `(` *fun* `,` *expr* `,` …¹ `,` *expr* `,`opt `)` |
+| | \| | `fold` `(` *fun* `,` *expr* `,` *expr* `,` …¹ `,` *expr* `,`opt `)` |
+| | \| | `slice` `<` *tsize* `>` `(` *expr* `,` *expr* `)` |
+| | \| | `[` *tuple-arg* `,` … `,` *tuple-arg* `,`opt `]` |
+| | \| | `Bytes` `[` *tuple-arg* `,` … `,` *tuple-arg* `,`opt `]` |
+| | \| | *tref* `{` *struct-arg* `,` … `,` *struct-arg* `,`opt `}` |
+| | \| | `assert` `(` *expr* `,` *str* `)` |
+| | \| | `disclose` `(` *expr* `)` |
+| | \| | *term* |
+
+
+#### Term (**term**)
+
+
+| | | |
+|--------|---------|-------------------------------|
+| *term* | ⟶ | *id* |
+| | \| | `true` |
+| | \| | `false` |
+| | \| | *nat* |
+| | \| | *str* |
+| | \| | `pad` `(` *nat* `,` *str* `)` |
+| | \| | `default` `<` *type* `>` |
+| | \| | `(` *expr-seq* `)` |
+
+
+#### Tuple-argument (**tuple-arg**, **bytes-arg**)
+
+
+| | | |
+|-------------|---------|--------------|
+| *tuple-arg* | ⟶ | *expr* |
+| | \| | `...` *expr* |
+| *bytes-arg* | ⟶ | *tuple-arg* |
+
+
+#### Structure-argument (**struct-arg**)
+
+
+| | | |
+|--------------|---------|-----------------|
+| *struct-arg* | ⟶ | *expr* |
+| | \| | *id* `:` *expr* |
+| | \| | `...` *expr* |
+
+
+#### Function (**fun**)
+
+
+| | | |
+|-------|---------|-----------------------------------------------------------------|
+| *fun* | ⟶ | *id* *gargs*opt |
+| | \| | *arrow-parameter-list* *return-type*opt `=>` *block* |
+| | \| | *arrow-parameter-list* *return-type*opt `=>` *expr* |
+| | \| | `(` *fun* `)` |
+
+
+#### Return-type (**return-type**)
+
+
+| | | |
+|---------------|---------|------------|
+| *return-type* | ⟶ | `:` *type* |
+
+
+#### Optionally-typed-pattern (**optionally-typed-pattern**)
+
+
+| | | |
+|----------------------------|---------|-----------------|
+| *optionally-typed-pattern* | ⟶ | *pattern* |
+| | \| | *typed-pattern* |
+
+
+#### Const-Binding (**cbinding**)
+
+
+| | | |
+|------------|---------|---------------------------------------|
+| *cbinding* | ⟶ | *optionally-typed-pattern* `=` *expr* |
+
+
+#### Arrow-parameter-list (**arrow-parameter-list**)
+
+
+| | | |
+|------------------------|---------|------------------------------------------------------------------------------------------------|
+| *arrow-parameter-list* | ⟶ | `(` *optionally-typed-pattern* `,` … `,` *optionally-typed-pattern* `,`opt `)` |
diff --git a/src/css/custom.css b/src/css/custom.css
index d47b7e44..c311eb12 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -89,6 +89,10 @@ h6 {
color: var(--ifm-heading-color);
}
+body h4 {
+ font-size: 1.1rem;
+}
+
/* ============================================
MINTLIFY-INSPIRED SIDEBAR STYLES
============================================ */
@@ -605,6 +609,7 @@ pre {
.lang-ref-table {
border-collapse: separate;
border-spacing: 0;
+ padding-left: 20px;
--ifm-table-stripe-background: none;
}
@@ -613,13 +618,16 @@ pre {
}
.lang-ref-table tbody tr {
- border: none
+ border: none;
}
.lang-ref-table td,
.lang-ref-table th {
border: none;
- padding: 1px;
+ padding-top: 1px;
+ padding-bottom: 1px;
+ padding-left: 5px;
+ padding-right: 5px;
text-align: left;
}
From 05ffc7cc359673c8e95a66193c04001cde7a14bc Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Tue, 10 Mar 2026 06:33:24 +0100
Subject: [PATCH 04/41] limit lang-ref-table to
elements
---
src/css/custom.css | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/css/custom.css b/src/css/custom.css
index c311eb12..7699a371 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -606,7 +606,7 @@ pre {
}
/* The following table is specific to the Compact reference document */
-.lang-ref-table {
+.lang-ref-table table {
border-collapse: separate;
border-spacing: 0;
padding-left: 20px;
@@ -632,7 +632,7 @@ pre {
}
.lang-ref-table td:nth-child(2) {
- text-align: right; /* Right-align the middle column */
+ text-align: center; /* Right-align the middle column */
}
/* Animate navbar active tab */
From 31a4e4a65d3a5d48319227b4a2224eb042630a6b Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Tue, 10 Mar 2026 06:57:20 +0100
Subject: [PATCH 05/41] latest compact-grammar.mdx complete with link marks and
references
---
docs/compact/reference/compact-grammar.mdx | 674 ++++++++++-----------
1 file changed, 337 insertions(+), 337 deletions(-)
diff --git a/docs/compact/reference/compact-grammar.mdx b/docs/compact/reference/compact-grammar.mdx
index 5c537079..1a49dcc8 100644
--- a/docs/compact/reference/compact-grammar.mdx
+++ b/docs/compact/reference/compact-grammar.mdx
@@ -4,595 +4,595 @@ Compact language version 0.21.0.
Notational note: In the grammar below, terminals are in `monospaced` font. Non-terminals are in *emphasized* font. Alternation is indicated by a vertical bar (`|`). Optional items are indicated by the superscript opt. Repetition is specified by ellipses. The notation *X* … *X*, where *X* is a grammar symbol, represents zero or more occurrences of *X*. The notation *X* `,` … `,` *X*, where *X* is a grammar symbol and `,` is a literal comma, represents zero or more occurrences of *X* separated by commas. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one *X*. When such a sequence is followed by *,*opt, an optional trailing comma is allowed, but only if there is at least one *X*. For example, *id* … *id* represents zero or more *id*s, and *expr* `,` …¹ `,` *expr* `,`opt represents one or more comma-separated *expr*s possibly followed by an extra comma. The rules involving commas apply equally to semicolons, i.e., apply when `,` is replaced by `;`.
-#### end-of-file (*eof*)
+#### end-of-file (*eof*)
End of file.
-#### identifier (*id*, *module-name*, *function-name*, *struct-name*, *enum-name*, *contract-name*, *tvar-name*, *type-name*)
+#### identifier (*id*, *module-name*, *function-name*, *struct-name*, *enum-name*, *contract-name*, *tvar-name*, *type-name*)
Identifiers have the same syntax as Typescript identifiers.
-#### field-literal (*nat*)
+#### field-literal (*nat*)
A field literal is 0 or a natural number formed from a sequence of digits starting with 1-9, e.g. 723, whose value does not exceed the maximum field value.
-#### string-literal (*str*, *file*)
+#### string-literal (*str*, *file*)
A string literal has the same syntax as a Typescript string.
-#### version-literal (*version*)
+#### version-literal (*version*)
A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2.3, representing major, minor, and bugfix versions.
-#### Compact (**program**)
+#### Compact (**program**)
-| | | |
-|-----------|---------|----------------------------|
-| *program* | ⟶ | *pelt* … *pelt* *eof* |
+| | | |
+|-----------|---------|------------------------------------------------------------------------------------|
+| *program* | ⟶ | [*pelt*](#Program-element) … [*pelt*](#Program-element) [*eof*](#end-of-file) |
-#### Program-element (**pelt**)
+#### Program-element (**pelt**)
-| | | |
-|--------|---------|--------------------------|
-| *pelt* | ⟶ | *pragma-form* |
-| | \| | *module-definition* |
-| | \| | *import-form* |
-| | \| | *export-form* |
-| | \| | *include-form* |
-| | \| | *struct-declaration* |
-| | \| | *enum-declaration* |
-| | \| | *contract-declaration* |
-| | \| | *type-alias-declaration* |
-| | \| | *ledger-declaration* |
-| | \| | *witness-declaration* |
-| | \| | *constructor-definition* |
-| | \| | *circuit-definition* |
+| | | |
+|--------|---------|----------------------------------------------------------|
+| *pelt* | ⟶ | [*pragma-form*](#Pragma) |
+| | \| | [*module-definition*](#Module-definition) |
+| | \| | [*import-form*](#Import-declaration) |
+| | \| | [*export-form*](#Export-declaration) |
+| | \| | [*include-form*](#Include) |
+| | \| | [*struct-declaration*](#Structure-declaration) |
+| | \| | [*enum-declaration*](#Enum-declaration) |
+| | \| | [*contract-declaration*](#External-contract-declaration) |
+| | \| | [*type-alias-declaration*](#Type-declaration) |
+| | \| | [*ledger-declaration*](#Ledger-declaration) |
+| | \| | [*witness-declaration*](#Witness-declaration) |
+| | \| | [*constructor-definition*](#Constructor) |
+| | \| | [*circuit-definition*](#Circuit-definition) |
-#### Pragma (**pragma-form**)
+#### Pragma (**pragma-form**)
-| | | |
-|---------------|---------|----------------------------------|
-| *pragma-form* | ⟶ | `pragma` *id* *version-expr* `;` |
+| | | |
+|---------------|---------|------------------------------------------------------------------------|
+| *pragma-form* | ⟶ | `pragma` [*id*](#identifier) [*version-expr*](#Version-expression) `;` |
-#### Version-expression (**version-expr**)
+#### Version-expression (**version-expr**)
-| | | |
-|----------------|---------|--------------------------------------------------|
-| *version-expr* | ⟶ | *version-expr* `\|\|` *version-expr0* |
-| | \| | *version-expr0* |
+| | | |
+|----------------|---------|-------------------------------------------------------------------------------------------------|
+| *version-expr* | ⟶ | [*version-expr*](#Version-expression) `\|\|` [*version-expr0*](#Version-expression0) |
+| | \| | [*version-expr0*](#Version-expression0) |
-#### Version-expression0 (**version-expr0**)
+#### Version-expression0 (**version-expr0**)
-| | | |
-|----------------------------|---------|------------------------------------------------|
-| *version-expr0* | ⟶ | *version-expr0* `&&` *version-term* |
-| | \| | *version-term* |
+| | | |
+|----------------------------|---------|-----------------------------------------------------------------------------------------|
+| *version-expr0* | ⟶ | [*version-expr0*](#Version-expression0) `&&` [*version-term*](#Version-Term) |
+| | \| | [*version-term*](#Version-Term) |
-#### Version-Term (**version-term**)
+#### Version-Term (**version-term**)
-| | | |
-|----------------|---------|------------------------|
-| *version-term* | ⟶ | *version-atom* |
-| | \| | `!` *version-atom* |
-| | \| | `<` *version-atom* |
-| | \| | `<=` *version-atom* |
-| | \| | `>=` *version-atom* |
-| | \| | `>` *version-atom* |
-| | \| | `(` *version-expr* `)` |
+| | | |
+|----------------|---------|-----------------------------------------------|
+| *version-term* | ⟶ | [*version-atom*](#Version-atom) |
+| | \| | `!` [*version-atom*](#Version-atom) |
+| | \| | `<` [*version-atom*](#Version-atom) |
+| | \| | `<=` [*version-atom*](#Version-atom) |
+| | \| | `>=` [*version-atom*](#Version-atom) |
+| | \| | `>` [*version-atom*](#Version-atom) |
+| | \| | `(` [*version-expr*](#Version-expression) `)` |
-#### Version-atom (**version-atom**)
+#### Version-atom (**version-atom**)
-| | | |
-|----------------|---------|-----------|
-| *version-atom* | ⟶ | *nat* |
-| | \| | *version* |
+| | | |
+|----------------|---------|-------------------------------|
+| *version-atom* | ⟶ | [*nat*](#field-literal) |
+| | \| | [*version*](#version-literal) |
-#### Include (**include-form**)
+#### Include (**include-form**)
-| | | |
-|----------------|---------|----------------------|
-| *include-form* | ⟶ | `include` *file* `;` |
+| | | |
+|----------------|---------|-----------------------------------------|
+| *include-form* | ⟶ | `include` [*file*](#string-literal) `;` |
-#### Module-definition (**module-definition**)
+#### Module-definition (**module-definition**)
-| | | |
-|---------------------|---------|----------------------------------------------------------------------------------------------------|
-| *module-definition* | ⟶ | `export`opt `module` *module-name* *gparams*opt `{` *pelt* … *pelt* `}` |
+| | | |
+|---------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*pelt*](#Program-element) … [*pelt*](#Program-element) `}` |
-#### Generic-parameter-list (**gparams**)
+#### Generic-parameter-list (**gparams**)
-| | | |
-|-----------|---------|--------------------------------------------------------------------------|
-| *gparams* | ⟶ | `<` *generic-param* `,` … `,` *generic-param* `,`opt `>` |
+| | | |
+|-----------|---------|----------------------------------------------------------------------------------------------------------------------|
+| *gparams* | ⟶ | `<` [*generic-param*](#Generic-parameter) `,` … `,` [*generic-param*](#Generic-parameter) `,`opt `>` |
-#### Generic-parameter (**generic-param**)
+#### Generic-parameter (**generic-param**)
-| | | |
-|-----------------|---------|-----------------|
-| *generic-param* | ⟶ | `#` *tvar-name* |
-| | \| | *tvar-name* |
+| | | |
+|-----------------|---------|--------------------------------|
+| *generic-param* | ⟶ | `#` [*tvar-name*](#identifier) |
+| | \| | [*tvar-name*](#identifier) |
-#### Import-declaration (**import-form**)
+#### Import-declaration (**import-form**)
-| | | |
-|---------------|---------|-----------------------------------------------------------------------------------------------------------------|
-| *import-form* | ⟶ | `import` *import-selection*opt *import-name* *gargs*opt *import-prefix*opt `;` |
+| | | |
+|---------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *import-form* | ⟶ | `import` [*import-selection*](#Import-selection)opt [*import-name*](#Import-name) [*gargs*](#Generic-argument-list)opt [*import-prefix*](#Import-prefix)opt `;` |
-#### Import-selection (**import-selection**)
+#### Import-selection (**import-selection**)
-| | | |
-|--------------------|---------|-----------------------------------------------------------------------------------|
-| *import-selection* | ⟶ | `{` *import-element* `,` … `,` *import-element* `,`opt `}` `from` |
+| | | |
+|--------------------|---------|-------------------------------------------------------------------------------------------------------------------------|
+| *import-selection* | ⟶ | `{` [*import-element*](#Import-element) `,` … `,` [*import-element*](#Import-element) `,`opt `}` `from` |
-#### Import-element (**import-element**)
+#### Import-element (**import-element**)
-| | | |
-|------------------|---------|----------------|
-| *import-element* | ⟶ | *id* |
-| | \| | *id* `as` *id* |
+| | | |
+|------------------|---------|----------------------------------------------|
+| *import-element* | ⟶ | [*id*](#identifier) |
+| | \| | [*id*](#identifier) `as` [*id*](#identifier) |
-#### Import-name (**import-name**)
+#### Import-name (**import-name**)
-| | | |
-|---------------|---------|--------|
-| *import-name* | ⟶ | *id* |
-| | \| | *file* |
+| | | |
+|---------------|---------|---------------------------|
+| *import-name* | ⟶ | [*id*](#identifier) |
+| | \| | [*file*](#string-literal) |
-#### Import-prefix (**import-prefix**)
+#### Import-prefix (**import-prefix**)
-| | | |
-|-----------------|---------|---------------|
-| *import-prefix* | ⟶ | `prefix` *id* |
+| | | |
+|-----------------|---------|------------------------------|
+| *import-prefix* | ⟶ | `prefix` [*id*](#identifier) |
-#### Generic-argument-list (**gargs**)
+#### Generic-argument-list (**gargs**)
-| | | |
-|---------|---------|--------------------------------------------------------|
-| *gargs* | ⟶ | `<` *garg* `,` … `,` *garg* `,`opt `>` |
+| | | |
+|---------|---------|--------------------------------------------------------------------------------------------------|
+| *gargs* | ⟶ | `<` [*garg*](#Generic-argument) `,` … `,` [*garg*](#Generic-argument) `,`opt `>` |
-#### Generic-argument (**garg**)
+#### Generic-argument (**garg**)
-| | | |
-|--------|---------|--------|
-| *garg* | ⟶ | *nat* |
-| | \| | *type* |
+| | | |
+|--------|---------|-------------------------|
+| *garg* | ⟶ | [*nat*](#field-literal) |
+| | \| | [*type*](#Type) |
-#### Export-declaration (**export-form**)
+#### Export-declaration (**export-form**)
-| | | |
-|---------------|---------|-------------------------------------------------------------------------------|
-| *export-form* | ⟶ | `export` `{` *id* `,` … `,` *id* `,`opt `}` `;`opt |
+| | | |
+|---------------|---------|-------------------------------------------------------------------------------------------------------------|
+| *export-form* | ⟶ | `export` `{` [*id*](#identifier) `,` … `,` [*id*](#identifier) `,`opt `}` `;`opt |
-#### Ledger-declaration (**ledger-declaration**)
+#### Ledger-declaration (**ledger-declaration**)
-| | | |
-|----------------------|---------|----------------------------------------------------------------------------|
-| *ledger-declaration* | ⟶ | `export`opt `sealed`opt `ledger` *id* `:` *type* `;` |
+| | | |
+|----------------------|---------|----------------------------------------------------------------------------------------------------|
+| *ledger-declaration* | ⟶ | `export`opt `sealed`opt `ledger` [*id*](#identifier) `:` [*type*](#Type) `;` |
-#### Witness-declaration (**witness-declaration**)
+#### Witness-declaration (**witness-declaration**)
-| | | |
-|-----------------------|---------|------------------------------------------------------------------------------------------------------|
-| *witness-declaration* | ⟶ | `export`opt `witness` *id* *gparams*opt *simple-parameter-list* `:` *type* `;` |
+| | | |
+|-----------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *witness-declaration* | ⟶ | `export`opt `witness` [*id*](#identifier) [*gparams*](#Generic-parameter-list)opt [*simple-parameter-list*](#Simple-parameter-list) `:` [*type*](#Type) `;` |
-#### Constructor (**constructor-definition**)
+#### Constructor (**constructor-definition**)
-| | | |
-|--------------------------|---------|------------------------------------------------|
-| *constructor-definition* | ⟶ | `constructor` *pattern-parameter-list* *block* |
+| | | |
+|--------------------------|---------|-------------------------------------------------------------------------------------|
+| *constructor-definition* | ⟶ | `constructor` [*pattern-parameter-list*](#Pattern-parameter-list) [*block*](#Block) |
-#### Circuit-definition (**circuit-definition**)
+#### Circuit-definition (**circuit-definition**)
-| | | |
-|----------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------|
-| *circuit-definition* | ⟶ | `export`opt `pure`opt `circuit` *function-name* *gparams*opt *pattern-parameter-list* `:` *type* *block* |
+| | | |
+|----------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *circuit-definition* | ⟶ | `export`opt `pure`opt `circuit` [*function-name*](#identifier) [*gparams*](#Generic-parameter-list)opt [*pattern-parameter-list*](#Pattern-parameter-list) `:` [*type*](#Type) [*block*](#Block) |
-#### Structure-declaration (**struct-declaration**)
+#### Structure-declaration (**struct-declaration**)
-| | | |
-|----------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *struct-declaration* | ⟶ | `export`opt `struct` *struct-name* *gparams*opt `{` *typed-identifier* `;` … `;` *typed-identifier* `;`opt `}` `;`opt |
-| | \| | `export`opt `struct` *struct-name* *gparams*opt `{` *typed-identifier* `,` … `,` *typed-identifier* `,`opt `}` `;`opt |
+| | | |
+|----------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *struct-declaration* | ⟶ | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-identifier*](#Typed-identifier) `;` … `;` [*typed-identifier*](#Typed-identifier) `;`opt `}` `;`opt |
+| | \| | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-identifier*](#Typed-identifier) `,` … `,` [*typed-identifier*](#Typed-identifier) `,`opt `}` `;`opt |
-#### Enum-declaration (**enum-declaration**)
+#### Enum-declaration (**enum-declaration**)
-| | | |
-|--------------------|---------|----------------------------------------------------------------------------------------------------------------------|
-| *enum-declaration* | ⟶ | `export`opt `enum` *enum-name* `{` *id* `,` …¹ `,` *id* `,`opt `}` `;`opt |
+| | | |
+|--------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *enum-declaration* | ⟶ | `export`opt `enum` [*enum-name*](#identifier) `{` [*id*](#identifier) `,` …¹ `,` [*id*](#identifier) `,`opt `}` `;`opt |
-#### External-contract-declaration (**contract-declaration**)
+#### External-contract-declaration (**contract-declaration**)
-| | | |
-|------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *contract-declaration* | ⟶ | `export`opt `contract` *contract-name* `{` *circuit-declaration* `;` … `;` *circuit-declaration* `;`opt `}` `;`opt |
-| | \| | `export`opt `contract` *contract-name* `{` *circuit-declaration* `,` … `,` *circuit-declaration* `,`opt `}` `;`opt |
+| | | |
+|------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *contract-declaration* | ⟶ | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#External-contract-circuit) `;` … `;` [*circuit-declaration*](#External-contract-circuit) `;`opt `}` `;`opt |
+| | \| | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#External-contract-circuit) `,` … `,` [*circuit-declaration*](#External-contract-circuit) `,`opt `}` `;`opt |
-#### External-contract-circuit (**circuit-declaration**)
+#### External-contract-circuit (**circuit-declaration**)
-| | | |
-|-----------------------|---------|------------------------------------------------------------------------|
-| *circuit-declaration* | ⟶ | `pure`opt `circuit` *id* *simple-parameter-list* `:` *type* |
+| | | |
+|-----------------------|---------|--------------------------------------------------------------------------------------------------------------------------|
+| *circuit-declaration* | ⟶ | `pure`opt `circuit` [*id*](#identifier) [*simple-parameter-list*](#Simple-parameter-list) `:` [*type*](#Type) |
-#### Type-declaration (**type-alias-declaration**)
+#### Type-declaration (**type-alias-declaration**)
-| | | |
-|--------------------------|---------|------------------------------------------------------------------------------------------------------|
-| *type-alias-declaration* | ⟶ | `export`opt `new`opt `type` *type-name* *gparams*opt `=` *type* `;` |
+| | | |
+|--------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *type-alias-declaration* | ⟶ | `export`opt `new`opt `type` [*type-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `=` [*type*](#Type) `;` |
-#### Typed-identifier (**typed-identifier**)
+#### Typed-identifier (**typed-identifier**)
-| | | |
-|--------------------|---------|-----------------|
-| *typed-identifier* | ⟶ | *id* `:` *type* |
+| | | |
+|--------------------|---------|-----------------------------------------|
+| *typed-identifier* | ⟶ | [*id*](#identifier) `:` [*type*](#Type) |
-#### Simple-parameter-list (**simple-parameter-list**)
+#### Simple-parameter-list (**simple-parameter-list**)
-| | | |
-|-------------------------|---------|--------------------------------------------------------------------------------|
-| *simple-parameter-list* | ⟶ | `(` *typed-identifier* `,` … `,` *typed-identifier* `,`opt `)` |
+| | | |
+|-------------------------|---------|--------------------------------------------------------------------------------------------------------------------------|
+| *simple-parameter-list* | ⟶ | `(` [*typed-identifier*](#Typed-identifier) `,` … `,` [*typed-identifier*](#Typed-identifier) `,`opt `)` |
-#### Typed-pattern (**typed-pattern**)
+#### Typed-pattern (**typed-pattern**)
-| | | |
-|-----------------|---------|----------------------|
-| *typed-pattern* | ⟶ | *pattern* `:` *type* |
+| | | |
+|-----------------|---------|-------------------------------------------|
+| *typed-pattern* | ⟶ | [*pattern*](#Pattern) `:` [*type*](#Type) |
-#### Pattern-parameter-list (**pattern-parameter-list**)
+#### Pattern-parameter-list (**pattern-parameter-list**)
-| | | |
-|--------------------------|---------|--------------------------------------------------------------------------|
-| *pattern-parameter-list* | ⟶ | `(` *typed-pattern* `,` … `,` *typed-pattern* `,`opt `)` |
+| | | |
+|--------------------------|---------|--------------------------------------------------------------------------------------------------------------|
+| *pattern-parameter-list* | ⟶ | `(` [*typed-pattern*](#Typed-pattern) `,` … `,` [*typed-pattern*](#Typed-pattern) `,`opt `)` |
-#### Type (**type**)
+#### Type (**type**)
-| | | |
-|--------|---------|--------------------------------------------------------|
-| *type* | ⟶ | *tref* |
-| | \| | `Boolean` |
-| | \| | `Field` |
-| | \| | `Uint` `<` *tsize* `>` |
-| | \| | `Uint` `<` *tsize* `..` *tsize* `>` |
-| | \| | `Bytes` `<` *tsize* `>` |
-| | \| | `Opaque` `<` *str* `>` |
-| | \| | `Vector` `<` *tsize* `,` *type* `>` |
-| | \| | `[` *type* `,` … `,` *type* `,`opt `]` |
+| | | |
+|--------|---------|--------------------------------------------------------------------------|
+| *type* | ⟶ | [*tref*](#Type-reference) |
+| | \| | `Boolean` |
+| | \| | `Field` |
+| | \| | `Uint` `<` [*tsize*](#Type-size) `>` |
+| | \| | `Uint` `<` [*tsize*](#Type-size) `..` [*tsize*](#Type-size) `>` |
+| | \| | `Bytes` `<` [*tsize*](#Type-size) `>` |
+| | \| | `Opaque` `<` [*str*](#string-literal) `>` |
+| | \| | `Vector` `<` [*tsize*](#Type-size) `,` [*type*](#Type) `>` |
+| | \| | `[` [*type*](#Type) `,` … `,` [*type*](#Type) `,`opt `]` |
-#### Type-reference (**tref**)
+#### Type-reference (**tref**)
-| | | |
-|--------|---------|----------------------------|
-| *tref* | ⟶ | *id* *gargs*opt |
+| | | |
+|--------|---------|---------------------------------------------------------------------|
+| *tref* | ⟶ | [*id*](#identifier) [*gargs*](#Generic-argument-list)opt |
-#### Type-size (**tsize**)
+#### Type-size (**tsize**)
-| | | |
-|---------|---------|-------|
-| *tsize* | ⟶ | *nat* |
-| | \| | *id* |
+| | | |
+|---------|---------|-------------------------|
+| *tsize* | ⟶ | [*nat*](#field-literal) |
+| | \| | [*id*](#identifier) |
-#### Block (**block**)
+#### Block (**block**)
-| | | |
-|---------|---------|------------------------------|
-| *block* | ⟶ | `{` *stmt* … *stmt* `}` |
+| | | |
+|---------|---------|----------------------------------------------------------|
+| *block* | ⟶ | `{` [*stmt*](#Statement) … [*stmt*](#Statement) `}` |
-#### Statement (**stmt**)
+#### Statement (**stmt**)
-| | | |
-|--------|---------|--------------------------------|
-| *stmt* | ⟶ | `if` `(` *expr-seq* `)` *stmt* |
-| | \| | *stmt0* |
+| | | |
+|--------|---------|----------------------------------------------------------------------|
+| *stmt* | ⟶ | `if` `(` [*expr-seq*](#Expression-sequence) `)` [*stmt*](#Statement) |
+| | \| | [*stmt0*](#Statement0) |
-#### Statement0 (**stmt0**)
+#### Statement0 (**stmt0**)
-| | | |
-|--------------------|---------|----------------------------------------------------------|
-| *stmt0* | ⟶ | *expr-seq* `;` |
-| | \| | `const` *cbinding* `,` …¹ `,` *cbinding* `;` |
-| | \| | `if` `(` *expr-seq* `)` *stmt0* `else` *stmt* |
-| | \| | `for` `(` `const` *id* `of` *nat* `..` *nat* `)` *stmt* |
-| | \| | `for` `(` `const` *id* `of` *expr-seq* `)` *stmt* |
-| | \| | `return` *expr-seq* `;` |
-| | \| | `return` `;` |
-| | \| | *block* |
+| | | |
+|--------------------|---------|--------------------------------------------------------------------------------------------------------------------------|
+| *stmt0* | ⟶ | [*expr-seq*](#Expression-sequence) `;` |
+| | \| | `const` [*cbinding*](#Const-Binding) `,` …¹ `,` [*cbinding*](#Const-Binding) `;` |
+| | \| | `if` `(` [*expr-seq*](#Expression-sequence) `)` [*stmt0*](#Statement0) `else` [*stmt*](#Statement) |
+| | \| | `for` `(` `const` [*id*](#identifier) `of` [*nat*](#field-literal) `..` [*nat*](#field-literal) `)` [*stmt*](#Statement) |
+| | \| | `for` `(` `const` [*id*](#identifier) `of` [*expr-seq*](#Expression-sequence) `)` [*stmt*](#Statement) |
+| | \| | `return` [*expr-seq*](#Expression-sequence) `;` |
+| | \| | `return` `;` |
+| | \| | [*block*](#Block) |
-#### Pattern (**pattern**)
+#### Pattern (**pattern**)
-| | | |
-|-----------|---------|------------------------------------------------------------------------------------------|
-| *pattern* | ⟶ | *id* |
-| | \| | `[` *pattern*opt `,` … `,` *pattern*opt `,`opt `]` |
-| | \| | `{` *pattern-struct-elt* `,` … `,` *pattern-struct-elt* `,`opt `}` |
+| | | |
+|-----------|---------|------------------------------------------------------------------------------------------------------------------------------------------|
+| *pattern* | ⟶ | [*id*](#identifier) |
+| | \| | `[` [*pattern*](#Pattern)opt `,` … `,` [*pattern*](#Pattern)opt `,`opt `]` |
+| | \| | `{` [*pattern-struct-elt*](#Pattern-struct-element) `,` … `,` [*pattern-struct-elt*](#Pattern-struct-element) `,`opt `}` |
-#### Pattern-struct-element (**pattern-struct-elt**)
+#### Pattern-struct-element (**pattern-struct-elt**)
-| | | |
-|----------------------|---------|--------------------|
-| *pattern-struct-elt* | ⟶ | *id* |
-| | \| | *id* `:` *pattern* |
+| | | |
+|----------------------|---------|-----------------------------------------------|
+| *pattern-struct-elt* | ⟶ | [*id*](#identifier) |
+| | \| | [*id*](#identifier) `:` [*pattern*](#Pattern) |
-#### Expression-sequence (**expr-seq**)
+#### Expression-sequence (**expr-seq**)
-| | | |
-|------------|---------|------------------------------------------------|
-| *expr-seq* | ⟶ | *expr* |
-| | \| | *expr* `,` …¹ `,` *expr* `,` *expr* |
+| | | |
+|------------|---------|---------------------------------------------------------------------------------------------|
+| *expr-seq* | ⟶ | [*expr*](#Expression) |
+| | \| | [*expr*](#Expression) `,` …¹ `,` [*expr*](#Expression) `,` [*expr*](#Expression) |
-#### Expression (**expr**)
+#### Expression (**expr**)
-| | | |
-|--------|---------|------------------------------------------|
-| *expr* | ⟶ | *expr0* `?` *expr* `:` *expr* |
-| | \| | *expr0* `=` *expr* |
-| | \| | *expr0* `+=` *expr* |
-| | \| | *expr0* `-=` *expr* |
-| | \| | *expr0* |
+| | | |
+|--------|---------|----------------------------------------------------------------------------------------|
+| *expr* | ⟶ | [*expr0*](#Expression0) `?` [*expr*](#Expression) `:` [*expr*](#Expression) |
+| | \| | [*expr0*](#Expression0) `=` [*expr*](#Expression) |
+| | \| | [*expr0*](#Expression0) `+=` [*expr*](#Expression) |
+| | \| | [*expr0*](#Expression0) `-=` [*expr*](#Expression) |
+| | \| | [*expr0*](#Expression0) |
-#### Expression0 (**expr0**)
+#### Expression0 (**expr0**)
-| | | |
-|--------------------|---------|----------------------------------------------|
-| *expr0* | ⟶ | *expr0* `\|\|` *expr1* |
-| | \| | *expr1* |
+| | | |
+|--------------------|---------|------------------------------------------------------------------------------|
+| *expr0* | ⟶ | [*expr0*](#Expression0) `\|\|` [*expr1*](#Expression1) |
+| | \| | [*expr1*](#Expression1) |
-#### Expression1 (**expr1**)
+#### Expression1 (**expr1**)
-| | | |
-|--------------------|---------|--------------------------------------------|
-| *expr1* | ⟶ | *expr1* `&&` *expr2* |
-| | \| | *expr2* |
+| | | |
+|--------------------|---------|----------------------------------------------------------------------------|
+| *expr1* | ⟶ | [*expr1*](#Expression1) `&&` [*expr2*](#Expression2) |
+| | \| | [*expr2*](#Expression2) |
-#### Expression2 (**expr2**)
+#### Expression2 (**expr2**)
-| | | |
-|--------------------|---------|--------------------------------------------|
-| *expr2* | ⟶ | *expr2* `==` *expr3* |
-| | \| | *expr2* `!=` *expr3* |
-| | \| | *expr3* |
+| | | |
+|--------------------|---------|----------------------------------------------------------------------------|
+| *expr2* | ⟶ | [*expr2*](#Expression2) `==` [*expr3*](#Expression3) |
+| | \| | [*expr2*](#Expression2) `!=` [*expr3*](#Expression3) |
+| | \| | [*expr3*](#Expression3) |
-#### Expression3 (**expr3**)
+#### Expression3 (**expr3**)
-| | | |
-|--------------------|---------|--------------------------------------------|
-| *expr3* | ⟶ | *expr4* `<` *expr4* |
-| | \| | *expr4* `<=` *expr4* |
-| | \| | *expr4* `>=` *expr4* |
-| | \| | *expr4* `>` *expr4* |
-| | \| | *expr4* |
+| | | |
+|--------------------|---------|----------------------------------------------------------------------------|
+| *expr3* | ⟶ | [*expr4*](#Expression4) `<` [*expr4*](#Expression4) |
+| | \| | [*expr4*](#Expression4) `<=` [*expr4*](#Expression4) |
+| | \| | [*expr4*](#Expression4) `>=` [*expr4*](#Expression4) |
+| | \| | [*expr4*](#Expression4) `>` [*expr4*](#Expression4) |
+| | \| | [*expr4*](#Expression4) |
-#### Expression4 (**expr4**)
+#### Expression4 (**expr4**)
-| | | |
-|--------------------|---------|--------------------------------|
-| *expr4* | ⟶ | *expr4* `as` *type* |
-| | \| | *expr5* |
+| | | |
+|--------------------|---------|---------------------------------------------------------|
+| *expr4* | ⟶ | [*expr4*](#Expression4) `as` [*type*](#Type) |
+| | \| | [*expr5*](#Expression5) |
-#### Expression5 (**expr5**)
+#### Expression5 (**expr5**)
-| | | |
-|--------------------|---------|-------------------------------------------|
-| *expr5* | ⟶ | *expr5* `+` *expr6* |
-| | \| | *expr5* `-` *expr6* |
-| | \| | *expr6* |
+| | | |
+|--------------------|---------|---------------------------------------------------------------------------|
+| *expr5* | ⟶ | [*expr5*](#Expression5) `+` [*expr6*](#Expression6) |
+| | \| | [*expr5*](#Expression5) `-` [*expr6*](#Expression6) |
+| | \| | [*expr6*](#Expression6) |
-#### Expression6 (**expr6**)
+#### Expression6 (**expr6**)
-| | | |
-|--------------------|---------|-------------------------------------------|
-| *expr6* | ⟶ | *expr6* `*` *expr7* |
-| | \| | *expr7* |
+| | | |
+|--------------------|---------|---------------------------------------------------------------------------|
+| *expr6* | ⟶ | [*expr6*](#Expression6) `*` [*expr7*](#Expression7) |
+| | \| | [*expr7*](#Expression7) |
-#### Expression7 (**expr7**)
+#### Expression7 (**expr7**)
-| | | |
-|--------------------|---------|------------------------|
-| *expr7* | ⟶ | `!` *expr7* |
-| | \| | *expr8* |
+| | | |
+|--------------------|---------|----------------------------------------|
+| *expr7* | ⟶ | `!` [*expr7*](#Expression7) |
+| | \| | [*expr8*](#Expression8) |
-#### Expression8 (**expr8**)
+#### Expression8 (**expr8**)
-| | | |
-|--------------------|---------|------------------------------------------------------------------------------------|
-| *expr8* | ⟶ | *expr8* `[` *expr* `]` |
-| | \| | *expr8* `.` *id* |
-| | \| | *expr8* `.` *id* `(` *expr* `,` … `,` *expr* `,`opt `)` |
-| | \| | *expr9* |
+| | | |
+|--------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------|
+| *expr8* | ⟶ | [*expr8*](#Expression8) `[` [*expr*](#Expression) `]` |
+| | \| | [*expr8*](#Expression8) `.` [*id*](#identifier) |
+| | \| | [*expr8*](#Expression8) `.` [*id*](#identifier) `(` [*expr*](#Expression) `,` … `,` [*expr*](#Expression) `,`opt `)` |
+| | \| | [*expr9*](#Expression9) |
-#### Expression9 (**expr9**)
+#### Expression9 (**expr9**)
-| | | |
-|--------------------|---------|------------------------------------------------------------------------------------------|
-| *expr9* | ⟶ | *fun* `(` *expr* `,` … `,` *expr* `,`opt `)` |
-| | \| | `map` `(` *fun* `,` *expr* `,` …¹ `,` *expr* `,`opt `)` |
-| | \| | `fold` `(` *fun* `,` *expr* `,` *expr* `,` …¹ `,` *expr* `,`opt `)` |
-| | \| | `slice` `<` *tsize* `>` `(` *expr* `,` *expr* `)` |
-| | \| | `[` *tuple-arg* `,` … `,` *tuple-arg* `,`opt `]` |
-| | \| | `Bytes` `[` *tuple-arg* `,` … `,` *tuple-arg* `,`opt `]` |
-| | \| | *tref* `{` *struct-arg* `,` … `,` *struct-arg* `,`opt `}` |
-| | \| | `assert` `(` *expr* `,` *str* `)` |
-| | \| | `disclose` `(` *expr* `)` |
-| | \| | *term* |
+| | | |
+|--------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| *expr9* | ⟶ | [*fun*](#Function) `(` [*expr*](#Expression) `,` … `,` [*expr*](#Expression) `,`opt `)` |
+| | \| | `map` `(` [*fun*](#Function) `,` [*expr*](#Expression) `,` …¹ `,` [*expr*](#Expression) `,`opt `)` |
+| | \| | `fold` `(` [*fun*](#Function) `,` [*expr*](#Expression) `,` [*expr*](#Expression) `,` …¹ `,` [*expr*](#Expression) `,`opt `)` |
+| | \| | `slice` `<` [*tsize*](#Type-size) `>` `(` [*expr*](#Expression) `,` [*expr*](#Expression) `)` |
+| | \| | `[` [*tuple-arg*](#Tuple-argument) `,` … `,` [*tuple-arg*](#Tuple-argument) `,`opt `]` |
+| | \| | `Bytes` `[` [*tuple-arg*](#Tuple-argument) `,` … `,` [*tuple-arg*](#Tuple-argument) `,`opt `]` |
+| | \| | [*tref*](#Type-reference) `{` [*struct-arg*](#Structure-argument) `,` … `,` [*struct-arg*](#Structure-argument) `,`opt `}` |
+| | \| | `assert` `(` [*expr*](#Expression) `,` [*str*](#string-literal) `)` |
+| | \| | `disclose` `(` [*expr*](#Expression) `)` |
+| | \| | [*term*](#Term) |
-#### Term (**term**)
+#### Term (**term**)
-| | | |
-|--------|---------|-------------------------------|
-| *term* | ⟶ | *id* |
-| | \| | `true` |
-| | \| | `false` |
-| | \| | *nat* |
-| | \| | *str* |
-| | \| | `pad` `(` *nat* `,` *str* `)` |
-| | \| | `default` `<` *type* `>` |
-| | \| | `(` *expr-seq* `)` |
+| | | |
+|--------|---------|--------------------------------------------------------------------|
+| *term* | ⟶ | [*id*](#identifier) |
+| | \| | `true` |
+| | \| | `false` |
+| | \| | [*nat*](#field-literal) |
+| | \| | [*str*](#string-literal) |
+| | \| | `pad` `(` [*nat*](#field-literal) `,` [*str*](#string-literal) `)` |
+| | \| | `default` `<` [*type*](#Type) `>` |
+| | \| | `(` [*expr-seq*](#Expression-sequence) `)` |
-#### Tuple-argument (**tuple-arg**, **bytes-arg**)
+#### Tuple-argument (**tuple-arg**, **bytes-arg**)
-| | | |
-|-------------|---------|--------------|
-| *tuple-arg* | ⟶ | *expr* |
-| | \| | `...` *expr* |
-| *bytes-arg* | ⟶ | *tuple-arg* |
+| | | |
+|-------------|---------|-----------------------------|
+| *tuple-arg* | ⟶ | [*expr*](#Expression) |
+| | \| | `...` [*expr*](#Expression) |
+| *bytes-arg* | ⟶ | *tuple-arg* |
-#### Structure-argument (**struct-arg**)
+#### Structure-argument (**struct-arg**)
-| | | |
-|--------------|---------|-----------------|
-| *struct-arg* | ⟶ | *expr* |
-| | \| | *id* `:` *expr* |
-| | \| | `...` *expr* |
+| | | |
+|--------------|---------|-----------------------------------------------|
+| *struct-arg* | ⟶ | [*expr*](#Expression) |
+| | \| | [*id*](#identifier) `:` [*expr*](#Expression) |
+| | \| | `...` [*expr*](#Expression) |
-#### Function (**fun**)
+#### Function (**fun**)
-| | | |
-|-------|---------|-----------------------------------------------------------------|
-| *fun* | ⟶ | *id* *gargs*opt |
-| | \| | *arrow-parameter-list* *return-type*opt `=>` *block* |
-| | \| | *arrow-parameter-list* *return-type*opt `=>` *expr* |
-| | \| | `(` *fun* `)` |
+| | | |
+|-------|---------|------------------------------------------------------------------------------------------------------------------------|
+| *fun* | ⟶ | [*id*](#identifier) [*gargs*](#Generic-argument-list)opt |
+| | \| | [*arrow-parameter-list*](#Arrow-parameter-list) [*return-type*](#Return-type)opt `=>` [*block*](#Block) |
+| | \| | [*arrow-parameter-list*](#Arrow-parameter-list) [*return-type*](#Return-type)opt `=>` [*expr*](#Expression) |
+| | \| | `(` [*fun*](#Function) `)` |
-#### Return-type (**return-type**)
+#### Return-type (**return-type**)
-| | | |
-|---------------|---------|------------|
-| *return-type* | ⟶ | `:` *type* |
+| | | |
+|---------------|---------|---------------------|
+| *return-type* | ⟶ | `:` [*type*](#Type) |
-#### Optionally-typed-pattern (**optionally-typed-pattern**)
+#### Optionally-typed-pattern (**optionally-typed-pattern**)
-| | | |
-|----------------------------|---------|-----------------|
-| *optionally-typed-pattern* | ⟶ | *pattern* |
-| | \| | *typed-pattern* |
+| | | |
+|----------------------------|---------|-----------------------------------|
+| *optionally-typed-pattern* | ⟶ | [*pattern*](#Pattern) |
+| | \| | [*typed-pattern*](#Typed-pattern) |
-#### Const-Binding (**cbinding**)
+#### Const-Binding (**cbinding**)
-| | | |
-|------------|---------|---------------------------------------|
-| *cbinding* | ⟶ | *optionally-typed-pattern* `=` *expr* |
+| | | |
+|------------|---------|-----------------------------------------------------------------------------------|
+| *cbinding* | ⟶ | [*optionally-typed-pattern*](#Optionally-typed-pattern) `=` [*expr*](#Expression) |
-#### Arrow-parameter-list (**arrow-parameter-list**)
+#### Arrow-parameter-list (**arrow-parameter-list**)
-| | | |
-|------------------------|---------|------------------------------------------------------------------------------------------------|
-| *arrow-parameter-list* | ⟶ | `(` *optionally-typed-pattern* `,` … `,` *optionally-typed-pattern* `,`opt `)` |
+| | | |
+|------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *arrow-parameter-list* | ⟶ | `(` [*optionally-typed-pattern*](#Optionally-typed-pattern) `,` … `,` [*optionally-typed-pattern*](#Optionally-typed-pattern) `,`opt `)` |
From 23de83dd887a14e7b42d30990cdbd5202d36bae2 Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Tue, 10 Mar 2026 07:04:22 +0100
Subject: [PATCH 06/41] backed out limiting lang-ref-table to table elements
for now because it doesn't work when included in , only when
introduced outside of
---
src/css/custom.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/css/custom.css b/src/css/custom.css
index 7699a371..07575102 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -606,7 +606,7 @@ pre {
}
/* The following table is specific to the Compact reference document */
-.lang-ref-table table {
+.lang-ref-table {
border-collapse: separate;
border-spacing: 0;
padding-left: 20px;
From ca4cba94d187e4afd2bde30c999f78adb71fd195 Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Tue, 10 Mar 2026 07:22:24 +0100
Subject: [PATCH 07/41] latest lang-ref.mdx
---
docs/compact/reference/lang-ref.mdx | 106 ++++++++++++----------------
1 file changed, 46 insertions(+), 60 deletions(-)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index 737f140c..d32b5f2e 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -88,26 +88,25 @@ separately.
The syntax of Compact programs is given by an EBNF grammar. We use the
following notational conventions in the grammar:
-- Terminals are in bold monospaced font
-- Non-terminals are in emphasized font
-- Alternation is indicated by a vertical bar (`|`)
-- Optional items are indicated by a superscript opt
-- Repetition is specified by ellipses. The
- notation X ... X, where X is a grammar symbol,
- represents zero or more occurrences of X. The notation X
- , ... , X, where X is a
- grammar symbol and , is a literal comma, represents zero or more
- occurrences of X separated by commas. In either case, when
- the ellipsis is marked with the superscript 1, the notation represents a
- sequence containing at least one X. When such a sequence is followed
- by ,opt, an optional trailing comma is allowed, but
- only if there is at least one X. For example, id …
- id represents zero or more ids, and expr
- , …¹ , expr
- ,opt represents one or more comma-separated
- exprs possibly followed by an extra comma.
+- Terminals are in `monospaced` font.
+- Non-terminals are in *emphasized* font.
+- Alternation is indicated by a vertical bar (`|`).
+- Optional items are indicated by the superscript opt.
+- Repetition is specified by ellipses.
+ The notation *X* … *X*, where *X* is a grammar symbol, represents zero
+ or more occurrences of *X*.
+ The notation *X* `,` … `,` *X*, where *X* is a grammar symbol and
+ `,` is a literal comma, represents zero or more occurrences of *X*
+ separated by commas.
+ In either case, when the ellipsis is marked with the superscript 1,
+ the notation represents a sequence containing at least one *X*.
+ When such a sequence is followed by *,*opt, an optional
+ trailing comma is allowed, but only if there is at least one *X*.
+ For example, *id* … *id* represents zero or more *id*s, and
+ *expr* `,` …¹ `,` *expr* `,`opt represents one
+ or more comma-separated *expr*s possibly followed by an extra comma.
The rules involving commas apply equally to semicolons, i.e., apply when
- , is replaced by ;.
+ `,` is replaced by `;`.
## Static and dynamic errors
@@ -422,7 +421,7 @@ They can also define structural and nominal aliases for existing types.
#### Structure types
-Structure types are defined via a `struct` declaration with the following form:
+Structure types are defined via `struct` declarations with the following form:
| struct-declaration | → | exportopt struct struct-name gparamsopt \{ typed-identifier ; … ; typed-identifier ;opt } ;opt |
| | | | exportopt struct struct-name gparamsopt \{ typed-identifier , … , typed-identifier ,opt } ;opt |
| typed-identifier | → | id : type |
@@ -524,23 +523,14 @@ export circuit doesntWork(s: Even): Odd {
}
```
-Values of structure types are created with **structure-creation** expressions.
-These consist of the structure type (specialized if generic),
-followed by a sequence of field values enclosed in curly braces (`{ }`).
-Element values can be given positionally, in the same order as they are declared
-in the `struct` declaration; or they can be named using the element names from
-the declaration.
-Named element values can appear in any order.
-Positional and named element values can be mixed in the same structure creation
-expression, but all the positional ones must come before any of the named ones.
-See [Structure creation](#structure-creation) for the details.
-
-Using the example declarations above, structure values could be created with
-`Thing {[0, 1, 2], true}` or `NumberAnd> { item: 255, num: 0 }`.
+Values of structure types are created with
+[**structure-creation** expressions](#structure-creation)
+and accessed via
+[**structure-member-access** expressions](#structure-member-access).
#### Enumeration types
-Enumeration types are defined via a `enum` declaration with the following form:
+Enumeration types are defined via `enum` declarations with the following form:
| enum-declaration | → | exportopt enum enum-name \{ id , …¹ , id ,opt } ;opt |
@@ -562,9 +552,9 @@ names (in the same order) and distinct otherwise.
#### Contract types
-As of this writing, declarations of contracts and the cross-contract calls they
-support are not yet fully implemented, but the keyword `contract` used to
-declare contracts is reserved for this use.
+Compact 1.0 does not fully implement declarations of contracts and the
+cross-contract calls they support, but the keyword `contract` used to declare
+contracts is reserved for this use.
#### Type aliases
@@ -576,22 +566,28 @@ Within the scope of a type-alias declaration of *type-name* for *type*, *type-na
is itself a type.
Type aliases are either structural or nominal, depending on whether the optional
`new` modifier is present:
+
- A type alias *type-name* for *type* declared without the optional `new` modifier
is a structural type alias, i.e., *type-name* is the same type and is fully
- interchangeable with `type`.
+ interchangeable with *type*.
- A type alias *type-name* for *type* declared with the optional `new` modifier is
a nominal type alias, i.e., *type-name* is a distinct type compatible with *type*
but neither a subtype of nor a supertype of *type* (or any other type).
Any nominal type alias *type-name* for some type *type* is compatible with
*type* in the following senses:
+
- values of type *type-name* have the same representation as values of type *type*
- values of type *type-name* can be used by primitive operations that require
a value of type *type*
- values of type *type-name* can be cast explicitly to *type*, and
- values of type *type* can be cast explicitly to type *type-name*.
-For example, within the scope of `type V3U16 = Vector<3,
-Uint<16>>`, a value of type `V3U16` can be referenced or sliced just like a vector
+
+For example, within the scope of
+```compact
+new type V3U16 = Vector<3, Uint<16>>
+```
+a value of type `V3U16` can be referenced or sliced just like a vector
of type `Vector<3, Uint<16>>`, but it cannot, for example, be passed to a function
that expects a value of type `Vector<3, Uint<16>>` without an explicit cast.
@@ -1633,8 +1629,6 @@ type.
For example, in the following code, the binding for `x` has type `Boolean`, and
the binding for `y` has type `[Uint<64>, Uint<64>]`:
-!!!!!!!! TBD test this
-
```compact
witness w(): [Boolean, [Uint<16>, Uint<32>]];
circuit foo(): [Uint<64>, Uint<64>] {
@@ -1646,8 +1640,6 @@ circuit foo(): [Uint<64>, Uint<64>] {
while in the following, `x` still has type `Boolean` but `y` has (the inferred)
type `[Uint<16>, Uint<64>]`.
-!!!!!!!! TBD test this
-
```compact
witness w(): [Boolean, [Uint<16>, Uint<32>]];
circuit foo(): [Uint<64>, Uint<64>] {
@@ -1664,9 +1656,10 @@ For example, the reference to `x` on the first line of the body in the
definition of `foo` below is a static error:
```compact
-circuit foo(x: Uint<16>): Field {
- return x;
+circuit foo(a: Uint<16>): Field {
+ const y = x + a;
const x = 7;
+ return y;
}
```
@@ -1830,7 +1823,7 @@ The syntax of Compact expressions is summarized by the following grammar snippet
| expr7 | → | ! expr7 |
| | | | expr8 |
| expr8 | → | expr8 [ expr ] |
| | | | expr8 . id |
| | | | expr8 . id ( expr , … , expr ,opt ) |
| | | | expr9 |
| expr9 | → | fun ( expr , … , expr ,opt ) |
| | | | map ( fun , expr , …¹ , expr ,opt ) |
| | | | fold ( fun , expr , expr , …¹ , expr ,opt ) |
| | | | slice \< tsize > ( expr , expr ) |
| | | | [ tuple-arg , … , tuple-arg ,opt ] |
| | | | Bytes [ bytes-arg , … , bytes-arg ,opt ] |
| | | | tref \{ struct-arg , … , struct-arg ,opt } |
| | | | assert ( expr , str ) |
| | | | disclose ( expr ) |
| | | | term |
-| tuple-arg | → | expr |
| | → | ... expr |
| bytes-arg | → | tuple-arg |
+| tuple-arg | → | expr |
| | | | ... expr |
| bytes-arg | → | tuple-arg |
| struct-arg | → | expr |
| | | | id : expr |
| | | | ... expr |
| term | → | id |
| | | | true |
| | | | false |
| | | | nat |
| | | | str |
| | | | pad ( nat , str ) |
| | | | default \< type > |
| | | | ( expr-seq ) |
@@ -1961,10 +1954,8 @@ generic module or circuit in which a reference to a generic natural-number param
occurs in an expression context.
For example, if `foo` is defined as follows:
-!!!!!!!! TBD test this
-
```compact
-circuit foo<#N>(): Unsigned<16> {
+circuit foo<#N>(): Uint<16> {
return N;
}
```
@@ -1972,10 +1963,8 @@ circuit foo<#N>(): Unsigned<16> {
the call `foo<17>()`, at least in effect, gives rise to a copy of `foo` in
which `N` has been replaced by `17`.
-!!!!!!!! TBD test this
-
```compact
-circuit foo(): Unsigned<16> {
+circuit foo(): Uint<16> {
return 17;
}
```
@@ -2239,8 +2228,6 @@ type with the value cast back to `T`, which can result in a run-time error if
`T` is a nominal alias for a type `Uint<0..n>` and the value is not less than `n`.
For example:
-!!!!!!!! TBD test this
-
```compact
new type Feet = Uint<32>;
circuit foo(x: Feet, y: Feet, scale: Uint<32>): Feet {
@@ -2374,10 +2361,8 @@ compile-time constant value of `index` and `k` is the constant value of `size`.
For example, if `getMiddle` is defined as follows:
-!!!!!!!! TBD test this
-
```compact
-export circuit foo(x: Bytes<5>): Bytes<3> {
+export circuit getMiddle(x: Bytes<5>): Bytes<3> {
return slice<3>(x, 1);
}
```
@@ -2734,8 +2719,9 @@ Any cast not covered by one of the rules is not allowed.
!!!!!!!! TBD verify all of these claims -- Parisa
-In meeting convo: Do we have all the cases for downcast? check the code in analysis pass to see if it does
-what the claims say. the downcast isn't correct, even the example isn't correct.
+!!!!!!!! TBD mention of cast of state-ledger types ?
+
+!!!!!!!! TBD ??? In meeting convo: Do we have all the cases for downcast? check the code in analysis pass to see if it does what the claims say. the downcast isn't correct, even the example isn't correct.
#### Upcasts
From 8c23acca90f12e1386a8bca68b99a6a8c7dd946b Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Tue, 10 Mar 2026 15:27:45 +0100
Subject: [PATCH 08/41] latest lang-ref.mdx and compact-grammar.mdx
---
docs/compact/reference/compact-grammar.mdx | 162 ++++++++++-----------
docs/compact/reference/lang-ref.mdx | 125 ++++++++--------
2 files changed, 143 insertions(+), 144 deletions(-)
diff --git a/docs/compact/reference/compact-grammar.mdx b/docs/compact/reference/compact-grammar.mdx
index 1a49dcc8..66960f59 100644
--- a/docs/compact/reference/compact-grammar.mdx
+++ b/docs/compact/reference/compact-grammar.mdx
@@ -2,7 +2,7 @@
Compact language version 0.21.0.
-Notational note: In the grammar below, terminals are in `monospaced` font. Non-terminals are in *emphasized* font. Alternation is indicated by a vertical bar (`|`). Optional items are indicated by the superscript opt. Repetition is specified by ellipses. The notation *X* … *X*, where *X* is a grammar symbol, represents zero or more occurrences of *X*. The notation *X* `,` … `,` *X*, where *X* is a grammar symbol and `,` is a literal comma, represents zero or more occurrences of *X* separated by commas. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one *X*. When such a sequence is followed by *,*opt, an optional trailing comma is allowed, but only if there is at least one *X*. For example, *id* … *id* represents zero or more *id*s, and *expr* `,` …¹ `,` *expr* `,`opt represents one or more comma-separated *expr*s possibly followed by an extra comma. The rules involving commas apply equally to semicolons, i.e., apply when `,` is replaced by `;`.
+Notational note: In the grammar below, terminals are in `monospaced` font. Non-terminals are in *emphasized* font. Alternation is indicated by a vertical bar (`|`). Optional items are indicated by the superscript opt. Repetition is specified by ellipses. The notation *X* ⋯ *X*, where *X* is a grammar symbol, represents zero or more occurrences of *X*. The notation *X* `,` ⋯ `,` *X*, where *X* is a grammar symbol and `,` is a literal comma, represents zero or more occurrences of *X* separated by commas. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one *X*. When such a sequence is followed by *,*opt, an optional trailing comma is allowed, but only if there is at least one *X*. For example, *id* ⋯ *id* represents zero or more *id*s, and *expr* `,` ⋯¹`,` *expr* `,`opt represents one or more comma-separated *expr*s possibly followed by an extra comma. The rules involving commas apply equally to semicolons, i.e., apply when `,` is replaced by `;`.
#### end-of-file (*eof*)
@@ -27,9 +27,9 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Compact (**program**)
-| | | |
-|-----------|---------|------------------------------------------------------------------------------------|
-| *program* | ⟶ | [*pelt*](#Program-element) … [*pelt*](#Program-element) [*eof*](#end-of-file) |
+| | | |
+|-----------|---------|-------------------------------------------------------------------------------|
+| *program* | ⟶ | [*pelt*](#Program-element) ⋯ [*pelt*](#Program-element) [*eof*](#end-of-file) |
#### Program-element (**pelt**)
@@ -112,17 +112,17 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Module-definition (**module-definition**)
-| | | |
-|---------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*pelt*](#Program-element) … [*pelt*](#Program-element) `}` |
+| | | |
+|---------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*pelt*](#Program-element) ⋯ [*pelt*](#Program-element) `}` |
#### Generic-parameter-list (**gparams**)
-| | | |
-|-----------|---------|----------------------------------------------------------------------------------------------------------------------|
-| *gparams* | ⟶ | `<` [*generic-param*](#Generic-parameter) `,` … `,` [*generic-param*](#Generic-parameter) `,`opt `>` |
+| | | |
+|-----------|---------|-----------------------------------------------------------------------------------------------------------------|
+| *gparams* | ⟶ | `<` [*generic-param*](#Generic-parameter) `,` ⋯ `,` [*generic-param*](#Generic-parameter) `,`opt `>` |
#### Generic-parameter (**generic-param**)
@@ -145,9 +145,9 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Import-selection (**import-selection**)
-| | | |
-|--------------------|---------|-------------------------------------------------------------------------------------------------------------------------|
-| *import-selection* | ⟶ | `{` [*import-element*](#Import-element) `,` … `,` [*import-element*](#Import-element) `,`opt `}` `from` |
+| | | |
+|--------------------|---------|--------------------------------------------------------------------------------------------------------------------|
+| *import-selection* | ⟶ | `{` [*import-element*](#Import-element) `,` ⋯ `,` [*import-element*](#Import-element) `,`opt `}` `from` |
#### Import-element (**import-element**)
@@ -179,9 +179,9 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Generic-argument-list (**gargs**)
-| | | |
-|---------|---------|--------------------------------------------------------------------------------------------------|
-| *gargs* | ⟶ | `<` [*garg*](#Generic-argument) `,` … `,` [*garg*](#Generic-argument) `,`opt `>` |
+| | | |
+|---------|---------|---------------------------------------------------------------------------------------------|
+| *gargs* | ⟶ | `<` [*garg*](#Generic-argument) `,` ⋯ `,` [*garg*](#Generic-argument) `,`opt `>` |
#### Generic-argument (**garg**)
@@ -196,9 +196,9 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Export-declaration (**export-form**)
-| | | |
-|---------------|---------|-------------------------------------------------------------------------------------------------------------|
-| *export-form* | ⟶ | `export` `{` [*id*](#identifier) `,` … `,` [*id*](#identifier) `,`opt `}` `;`opt |
+| | | |
+|---------------|---------|--------------------------------------------------------------------------------------------------------|
+| *export-form* | ⟶ | `export` `{` [*id*](#identifier) `,` ⋯ `,` [*id*](#identifier) `,`opt `}` `;`opt |
#### Ledger-declaration (**ledger-declaration**)
@@ -236,27 +236,27 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Structure-declaration (**struct-declaration**)
-| | | |
-|----------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *struct-declaration* | ⟶ | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-identifier*](#Typed-identifier) `;` … `;` [*typed-identifier*](#Typed-identifier) `;`opt `}` `;`opt |
-| | \| | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-identifier*](#Typed-identifier) `,` … `,` [*typed-identifier*](#Typed-identifier) `,`opt `}` `;`opt |
+| | | |
+|----------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *struct-declaration* | ⟶ | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-identifier*](#Typed-identifier) `;` ⋯ `;` [*typed-identifier*](#Typed-identifier) `;`opt `}` `;`opt |
+| | \| | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-identifier*](#Typed-identifier) `,` ⋯ `,` [*typed-identifier*](#Typed-identifier) `,`opt `}` `;`opt |
#### Enum-declaration (**enum-declaration**)
-| | | |
-|--------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *enum-declaration* | ⟶ | `export`opt `enum` [*enum-name*](#identifier) `{` [*id*](#identifier) `,` …¹ `,` [*id*](#identifier) `,`opt `}` `;`opt |
+| | | |
+|--------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *enum-declaration* | ⟶ | `export`opt `enum` [*enum-name*](#identifier) `{` [*id*](#identifier) `,` ⋯¹ `,` [*id*](#identifier) `,`opt `}` `;`opt |
#### External-contract-declaration (**contract-declaration**)
-| | | |
-|------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *contract-declaration* | ⟶ | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#External-contract-circuit) `;` … `;` [*circuit-declaration*](#External-contract-circuit) `;`opt `}` `;`opt |
-| | \| | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#External-contract-circuit) `,` … `,` [*circuit-declaration*](#External-contract-circuit) `,`opt `}` `;`opt |
+| | | |
+|------------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *contract-declaration* | ⟶ | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#External-contract-circuit) `;` ⋯ `;` [*circuit-declaration*](#External-contract-circuit) `;`opt `}` `;`opt |
+| | \| | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#External-contract-circuit) `,` ⋯ `,` [*circuit-declaration*](#External-contract-circuit) `,`opt `}` `;`opt |
#### External-contract-circuit (**circuit-declaration**)
@@ -286,9 +286,9 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Simple-parameter-list (**simple-parameter-list**)
-| | | |
-|-------------------------|---------|--------------------------------------------------------------------------------------------------------------------------|
-| *simple-parameter-list* | ⟶ | `(` [*typed-identifier*](#Typed-identifier) `,` … `,` [*typed-identifier*](#Typed-identifier) `,`opt `)` |
+| | | |
+|-------------------------|---------|---------------------------------------------------------------------------------------------------------------------|
+| *simple-parameter-list* | ⟶ | `(` [*typed-identifier*](#Typed-identifier) `,` ⋯ `,` [*typed-identifier*](#Typed-identifier) `,`opt `)` |
#### Typed-pattern (**typed-pattern**)
@@ -302,25 +302,25 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Pattern-parameter-list (**pattern-parameter-list**)
-| | | |
-|--------------------------|---------|--------------------------------------------------------------------------------------------------------------|
-| *pattern-parameter-list* | ⟶ | `(` [*typed-pattern*](#Typed-pattern) `,` … `,` [*typed-pattern*](#Typed-pattern) `,`opt `)` |
+| | | |
+|--------------------------|---------|---------------------------------------------------------------------------------------------------------|
+| *pattern-parameter-list* | ⟶ | `(` [*typed-pattern*](#Typed-pattern) `,` ⋯ `,` [*typed-pattern*](#Typed-pattern) `,`opt `)` |
#### Type (**type**)
-| | | |
-|--------|---------|--------------------------------------------------------------------------|
-| *type* | ⟶ | [*tref*](#Type-reference) |
-| | \| | `Boolean` |
-| | \| | `Field` |
-| | \| | `Uint` `<` [*tsize*](#Type-size) `>` |
-| | \| | `Uint` `<` [*tsize*](#Type-size) `..` [*tsize*](#Type-size) `>` |
-| | \| | `Bytes` `<` [*tsize*](#Type-size) `>` |
-| | \| | `Opaque` `<` [*str*](#string-literal) `>` |
-| | \| | `Vector` `<` [*tsize*](#Type-size) `,` [*type*](#Type) `>` |
-| | \| | `[` [*type*](#Type) `,` … `,` [*type*](#Type) `,`opt `]` |
+| | | |
+|--------|---------|---------------------------------------------------------------------|
+| *type* | ⟶ | [*tref*](#Type-reference) |
+| | \| | `Boolean` |
+| | \| | `Field` |
+| | \| | `Uint` `<` [*tsize*](#Type-size) `>` |
+| | \| | `Uint` `<` [*tsize*](#Type-size) `..` [*tsize*](#Type-size) `>` |
+| | \| | `Bytes` `<` [*tsize*](#Type-size) `>` |
+| | \| | `Opaque` `<` [*str*](#string-literal) `>` |
+| | \| | `Vector` `<` [*tsize*](#Type-size) `,` [*type*](#Type) `>` |
+| | \| | `[` [*type*](#Type) `,` ⋯ `,` [*type*](#Type) `,`opt `]` |
#### Type-reference (**tref**)
@@ -343,9 +343,9 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Block (**block**)
-| | | |
-|---------|---------|----------------------------------------------------------|
-| *block* | ⟶ | `{` [*stmt*](#Statement) … [*stmt*](#Statement) `}` |
+| | | |
+|---------|---------|-----------------------------------------------------|
+| *block* | ⟶ | `{` [*stmt*](#Statement) ⋯ [*stmt*](#Statement) `}` |
#### Statement (**stmt**)
@@ -363,7 +363,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | | |
|--------------------|---------|--------------------------------------------------------------------------------------------------------------------------|
| *stmt0* | ⟶ | [*expr-seq*](#Expression-sequence) `;` |
-| | \| | `const` [*cbinding*](#Const-Binding) `,` …¹ `,` [*cbinding*](#Const-Binding) `;` |
+| | \| | `const` [*cbinding*](#Const-Binding) `,` ⋯¹ `,` [*cbinding*](#Const-Binding) `;` |
| | \| | `if` `(` [*expr-seq*](#Expression-sequence) `)` [*stmt0*](#Statement0) `else` [*stmt*](#Statement) |
| | \| | `for` `(` `const` [*id*](#identifier) `of` [*nat*](#field-literal) `..` [*nat*](#field-literal) `)` [*stmt*](#Statement) |
| | \| | `for` `(` `const` [*id*](#identifier) `of` [*expr-seq*](#Expression-sequence) `)` [*stmt*](#Statement) |
@@ -375,11 +375,11 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Pattern (**pattern**)
-| | | |
-|-----------|---------|------------------------------------------------------------------------------------------------------------------------------------------|
-| *pattern* | ⟶ | [*id*](#identifier) |
-| | \| | `[` [*pattern*](#Pattern)opt `,` … `,` [*pattern*](#Pattern)opt `,`opt `]` |
-| | \| | `{` [*pattern-struct-elt*](#Pattern-struct-element) `,` … `,` [*pattern-struct-elt*](#Pattern-struct-element) `,`opt `}` |
+| | | |
+|-----------|---------|-------------------------------------------------------------------------------------------------------------------------------------|
+| *pattern* | ⟶ | [*id*](#identifier) |
+| | \| | `[` [*pattern*](#Pattern)opt `,` ⋯ `,` [*pattern*](#Pattern)opt `,`opt `]` |
+| | \| | `{` [*pattern-struct-elt*](#Pattern-struct-element) `,` ⋯ `,` [*pattern-struct-elt*](#Pattern-struct-element) `,`opt `}` |
#### Pattern-struct-element (**pattern-struct-elt**)
@@ -394,10 +394,10 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Expression-sequence (**expr-seq**)
-| | | |
-|------------|---------|---------------------------------------------------------------------------------------------|
-| *expr-seq* | ⟶ | [*expr*](#Expression) |
-| | \| | [*expr*](#Expression) `,` …¹ `,` [*expr*](#Expression) `,` [*expr*](#Expression) |
+| | | |
+|------------|---------|-----------------------------------------------------------------------------------|
+| *expr-seq* | ⟶ | [*expr*](#Expression) |
+| | \| | [*expr*](#Expression) `,` ⋯¹ `,` [*expr*](#Expression) `,` [*expr*](#Expression) |
#### Expression (**expr**)
@@ -492,29 +492,29 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Expression8 (**expr8**)
-| | | |
-|--------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------|
-| *expr8* | ⟶ | [*expr8*](#Expression8) `[` [*expr*](#Expression) `]` |
-| | \| | [*expr8*](#Expression8) `.` [*id*](#identifier) |
-| | \| | [*expr8*](#Expression8) `.` [*id*](#identifier) `(` [*expr*](#Expression) `,` … `,` [*expr*](#Expression) `,`opt `)` |
-| | \| | [*expr9*](#Expression9) |
+| | | |
+|--------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------|
+| *expr8* | ⟶ | [*expr8*](#Expression8) `[` [*expr*](#Expression) `]` |
+| | \| | [*expr8*](#Expression8) `.` [*id*](#identifier) |
+| | \| | [*expr8*](#Expression8) `.` [*id*](#identifier) `(` [*expr*](#Expression) `,` ⋯ `,` [*expr*](#Expression) `,`opt `)` |
+| | \| | [*expr9*](#Expression9) |
#### Expression9 (**expr9**)
-| | | |
-|--------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------|
-| *expr9* | ⟶ | [*fun*](#Function) `(` [*expr*](#Expression) `,` … `,` [*expr*](#Expression) `,`opt `)` |
-| | \| | `map` `(` [*fun*](#Function) `,` [*expr*](#Expression) `,` …¹ `,` [*expr*](#Expression) `,`opt `)` |
-| | \| | `fold` `(` [*fun*](#Function) `,` [*expr*](#Expression) `,` [*expr*](#Expression) `,` …¹ `,` [*expr*](#Expression) `,`opt `)` |
-| | \| | `slice` `<` [*tsize*](#Type-size) `>` `(` [*expr*](#Expression) `,` [*expr*](#Expression) `)` |
-| | \| | `[` [*tuple-arg*](#Tuple-argument) `,` … `,` [*tuple-arg*](#Tuple-argument) `,`opt `]` |
-| | \| | `Bytes` `[` [*tuple-arg*](#Tuple-argument) `,` … `,` [*tuple-arg*](#Tuple-argument) `,`opt `]` |
-| | \| | [*tref*](#Type-reference) `{` [*struct-arg*](#Structure-argument) `,` … `,` [*struct-arg*](#Structure-argument) `,`opt `}` |
-| | \| | `assert` `(` [*expr*](#Expression) `,` [*str*](#string-literal) `)` |
-| | \| | `disclose` `(` [*expr*](#Expression) `)` |
-| | \| | [*term*](#Term) |
+| | | |
+|--------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------|
+| *expr9* | ⟶ | [*fun*](#Function) `(` [*expr*](#Expression) `,` ⋯ `,` [*expr*](#Expression) `,`opt `)` |
+| | \| | `map` `(` [*fun*](#Function) `,` [*expr*](#Expression) `,` ⋯¹ `,` [*expr*](#Expression) `,`opt `)` |
+| | \| | `fold` `(` [*fun*](#Function) `,` [*expr*](#Expression) `,` [*expr*](#Expression) `,` ⋯¹ `,` [*expr*](#Expression) `,`opt `)` |
+| | \| | `slice` `<` [*tsize*](#Type-size) `>` `(` [*expr*](#Expression) `,` [*expr*](#Expression) `)` |
+| | \| | `[` [*tuple-arg*](#Tuple-argument) `,` ⋯ `,` [*tuple-arg*](#Tuple-argument) `,`opt `]` |
+| | \| | `Bytes` `[` [*tuple-arg*](#Tuple-argument) `,` ⋯ `,` [*tuple-arg*](#Tuple-argument) `,`opt `]` |
+| | \| | [*tref*](#Type-reference) `{` [*struct-arg*](#Structure-argument) `,` ⋯ `,` [*struct-arg*](#Structure-argument) `,`opt `}` |
+| | \| | `assert` `(` [*expr*](#Expression) `,` [*str*](#string-literal) `)` |
+| | \| | `disclose` `(` [*expr*](#Expression) `)` |
+| | \| | [*term*](#Term) |
#### Term (**term**)
@@ -591,8 +591,8 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Arrow-parameter-list (**arrow-parameter-list**)
-| | | |
-|------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *arrow-parameter-list* | ⟶ | `(` [*optionally-typed-pattern*](#Optionally-typed-pattern) `,` … `,` [*optionally-typed-pattern*](#Optionally-typed-pattern) `,`opt `)` |
+| | | |
+|------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
+| *arrow-parameter-list* | ⟶ | `(` [*optionally-typed-pattern*](#Optionally-typed-pattern) `,` ⋯ `,` [*optionally-typed-pattern*](#Optionally-typed-pattern) `,`opt `)` |
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index d32b5f2e..7f281641 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -93,17 +93,17 @@ following notational conventions in the grammar:
- Alternation is indicated by a vertical bar (`|`).
- Optional items are indicated by the superscript opt.
- Repetition is specified by ellipses.
- The notation *X* … *X*, where *X* is a grammar symbol, represents zero
+ The notation *X* ⋯ *X*, where *X* is a grammar symbol, represents zero
or more occurrences of *X*.
- The notation *X* `,` … `,` *X*, where *X* is a grammar symbol and
+ The notation *X* `,` ⋯ `,` *X*, where *X* is a grammar symbol and
`,` is a literal comma, represents zero or more occurrences of *X*
separated by commas.
In either case, when the ellipsis is marked with the superscript 1,
- the notation represents a sequence containing at least one *X*.
- When such a sequence is followed by *,*opt, an optional
+ i.e., ⋯¹, the notation represents a sequence containing at least one *X*.
+ When such a sequence is followed by `,`opt, an optional
trailing comma is allowed, but only if there is at least one *X*.
- For example, *id* … *id* represents zero or more *id*s, and
- *expr* `,` …¹ `,` *expr* `,`opt represents one
+ For example, *id* ⋯ *id* represents zero or more *id*s, and
+ *expr* `,` ⋯¹ `,` *expr* `,`opt represents one
or more comma-separated *expr*s possibly followed by an extra comma.
The rules involving commas apply equally to semicolons, i.e., apply when
`,` is replaced by `;`.
@@ -261,7 +261,7 @@ Each parameter is either a type name (e.g., `T`) or a hash-prefixed natural-numb
Generic natural-number parameters are prefixed by `#` to distingish them from
generic type parameters.
-| gparams | → | \< generic-param , … , generic-param ,opt > |
+| gparams | → | \< generic-param , ⋯ , generic-param ,opt > |
| generic-param | → | # tvar-name |
| | | | tvar-name |
Generic entities must be *specialized* at the point of use to produce non-generic
@@ -271,7 +271,7 @@ Generic arguments are also enclosed in angle brackets.
Each generic argument must be a type, a natural number literal, or the type or
numeric value of a generic parameter.
-| gargs | → | \< garg , … , garg ,opt > |
+| gargs | → | \< garg , ⋯ , garg ,opt > |
| garg | → | nat |
| | | | type |
The syntax of types allows for type references, including references to generic
@@ -344,7 +344,7 @@ As with any other generic entity, it must be specialized at the point of use.
The following are the primitive types of Compact:
-| type | → | tref |
| | | | Boolean |
| | | | Field |
| | | | Uint \< tsize > |
| | | | Uint \< tsize .. tsize > |
| | | | Bytes \< tsize > |
| | | | Opaque \< str > |
| | | | Vector \< tsize , type > |
| | | | [ type , … , type ,opt ] |
+| type | → | tref |
| | | | Boolean |
| | | | Field |
| | | | Uint \< tsize > |
| | | | Uint \< tsize .. tsize > |
| | | | Bytes \< tsize > |
| | | | Opaque \< str > |
| | | | Vector \< tsize , type > |
| | | | [ type , ⋯ , type ,opt ] |
| tref | → | id gargsopt |
| tsize | → | nat |
| | | | id |
@@ -382,8 +382,8 @@ The following are the primitive types of Compact:
The current maximum field value is given in
[Implementation-specific limits](#implementation-specific-limits).
-- `[T, ...]`, where `T, ...` are zero or more comma-separated types, is the type
- of *tuple* values with element types `T, ...`.
+- `[T, ⋯]`, where `T, ⋯` are zero or more comma-separated types, is the type
+ of *tuple* values with element types `T, ⋯`.
Tuples are heterogeneous: any element type can differ from any of the others.
The *length* of a tuple type is the number of element types.
Two tuple types with different lengths are different types.
@@ -393,7 +393,7 @@ The following are the primitive types of Compact:
- `Vector`, where `n` is a natural number literal or generic natural-number
parameter and `T` is a type, is a shorthand notation for the tuple type
- `[T, ...]` with `n` occurrences of the type `T`.
+ `[T, ⋯]` with `n` occurrences of the type `T`.
Note that a vector type and the corresponding tuple type are two different ways
of writing exactly the same type.
Unless otherwise specified, type rules for vector types are derived from the
@@ -423,7 +423,7 @@ They can also define structural and nominal aliases for existing types.
Structure types are defined via `struct` declarations with the following form:
-| struct-declaration | → | exportopt struct struct-name gparamsopt \{ typed-identifier ; … ; typed-identifier ;opt } ;opt |
| | | | exportopt struct struct-name gparamsopt \{ typed-identifier , … , typed-identifier ,opt } ;opt |
+| struct-declaration | → | exportopt struct struct-name gparamsopt \{ typed-identifier ; ⋯ ; typed-identifier ;opt } ;opt |
| | | | exportopt struct struct-name gparamsopt \{ typed-identifier , ⋯ , typed-identifier ,opt } ;opt |
| typed-identifier | → | id : type |
A structure declaration has a sequence of named fields which must be separated
@@ -532,7 +532,7 @@ and accessed via
Enumeration types are defined via `enum` declarations with the following form:
-| enum-declaration | → | exportopt enum enum-name \{ id , …¹ , id ,opt } ;opt |
+| enum-declaration | → | exportopt enum enum-name \{ id , ⋯¹ , id ,opt } ;opt |
An enumeration declaration has a non-empty sequence of named elements separated by commas.
A trailing comma is allowed but not required.
@@ -614,10 +614,10 @@ When a generic nominal type is specialized, the specialized type is a nominal ty
### Subtyping and least upper bounds
-Some Compact types are related to other types via subtyping.
+Some Compact types are *related* to other types via subtyping.
Informally, if a type `T` is a *subtype* of a type `S` (equivalently, `S` is a
*supertype* of type `T`), then every value of type `T` is also a value of type `S`,
-i.e., any value of type `T` can be used where a value of type `S` expected without
+i.e., any value of type `T` can be used where a value of type `S` is expected without
the need for an explicit cast.
For example, a circuit or witness can be called with argument expressions whose
types are subtypes of the corresponding parameter type annotations, and
@@ -627,34 +627,33 @@ expression whose type is a subtype of the type annotation.
Subtyping is defined by the following rules:
- Any type `T` is a subtype of itself (subtyping is reflexive)
-- `Uint<0..n>` is a subtype of `Uint<0..m>` if `n` is less than `m`
+- `Uint<0..n>` is a subtype of `Uint<0..m>` if `n` is less than (or equal to) `m`
- `Uint<0..n>` is a subtype of `Field` for all `n`
-- The tuple type `[T, ...]` is a subtype of the tuple type `[S, ...]`
+- The tuple type `[T, ⋯]` is a subtype of the tuple type `[S, ⋯]`
if they have the same length and each type `T` is a subtype of the
corresponding type `S`.
The *least upper bound* (with respect to subtyping) of a non-empty set of types
-\{`T0`, ..., `Tn`} is a type `S` such that:
+\{`T1`, ⋯, `Tn`} is a type `S` such that:
- **`S` is an upper bound:** `Ti` is a subtype of `S` for all `i` in
- the range 0..`n`, and
+ the range 1..`n`, and
- **`S` is the least upper bound:** for all upper bounds `R` of the set of types
- \{`T0`, ..., `Tn`}, `S` is a subtype of `R`.
+ \{`T1`, ⋯, `Tn`}, `S` is a subtype of `R`.
Note that least upper bounds do not exist for all sets of types, because
some types (such as `Boolean` and `Field`) are not related.
**Tuple and vector types:** Every vector type has an equivalent tuple type:
-`Vector` is equivalent to (in fact, the same type as) `[T1, ..., Tn]`.
+`Vector` is equivalent to (in fact, the same type as) `[T1, ⋯, Tn]`.
The converse is not always true.
For example, neither `[Boolean, Field]` nor `[Uint<8>, Uint<16>]` have an
equivalent vector type.
-We say, however, that a tuple type `[T, ...]` with possibly distinct types `T, ...`
-"*has a vector type*" if the least upper bound `S` of the set of types \{`T`, ...}
+We say, however, that a tuple type [T1, ⋯, Tn] with possibly distinct types `T1, ⋯, Tn`
+"*has a vector type*" if the least upper bound `S` of the set of types \{`T1`, ⋯, `Tn`}
exists.
-In that case, the tuple type has the vector type `Vector` where `n` is the
-length of the tuple.
+In that case, the tuple type has the vector type `Vector`.
Some operations over tuples (such as mapping and folding) require the tuple type
to have a vector type.
@@ -666,8 +665,8 @@ vector type `Vector<2, Uint<16>>`, but the types are not equivalent.
Every vector type is a subtype of the equivalent tuple type and possibly of some
other tuple types.
-In general, a vector type `Vector` is a subtype of a tuple type `[S, ...]`
-if the tuple has length `n` and `T` is a subtype of each of the types `S, ...`.
+In general, a vector type `Vector` is a subtype of a tuple type `[S1, ⋯, Sn]`
+if `T` is a subtype of each of the types `S1`, ⋯, `Sn`.
The means, for instance, that a vector can often be passed to a circuit where a
tuple is expected.
@@ -676,7 +675,7 @@ tuple is expected.
The parameters of a circuit or constructor and the target of a `const` binding
are specified via patterns:
-| pattern | → | id |
| | | | [ patternopt , … , patternopt ,opt ] |
| | | | \{ pattern-struct-elt , … , pattern-struct-elt ,opt } |
+| pattern | → | id |
| | | | [ patternopt , ⋯ , patternopt ,opt ] |
| | | | \{ pattern-struct-elt , ⋯ , pattern-struct-elt ,opt } |
| pattern-struct-elt | → | id |
| | | | id : pattern |
In its simplest form, a pattern is just an identifier.
@@ -819,7 +818,7 @@ circuit sumSomeYs([{y: b1,}, , {y: b3,},]: [S, S, S]): Field {
A compact program is a sequence of zero or more program elements.
-| program | → | pelt … pelt |
+| program | → | pelt ⋯ pelt |
| pelt | → | pragma-form |
| | | | module-definition |
| | | | export-form |
@@ -900,7 +899,7 @@ Any identifier defined at or imported into the top level of a module can be expo
from the module in one of two ways: (1) by prefixing the definition with the
`export` keyword, or by listing the identifier in a separate `export` declaration:
-| export-form | → | export \{ id , … , id ,opt } ;opt |
+| export-form | → | export \{ id , ⋯ , id ,opt } ;opt |
For example, the following module exports `G` and `S` but not `F`.
@@ -925,7 +924,7 @@ A module can be imported into another module or into the program top level, maki
some or all of its exported bindings visible there, potentially with a prefix.
| import-form | → | import import-selectionopt import-name gargsopt import-prefixopt ; |
-| import-selection | → | \{ import-element , … , import-element ,opt } from |
+| import-selection | → | \{ import-element , ⋯ , import-element ,opt } from |
| import-element | → | id |
| | | | id as id |
| import-name | → | id |
| | | | file |
| import-prefix | → | prefix id |
@@ -1148,7 +1147,7 @@ provided by the TypeScript driver.
| witness-declaration | → | exportopt witness id gparamsopt simple-parameter-list : type ; |
-| simple-parameter-list | → | ( typed-identifier , … , typed-identifier ,opt ) |
+| simple-parameter-list | → | ( typed-identifier , ⋯ , typed-identifier ,opt ) |
| typed-identifier | → | id : type |
@@ -1216,7 +1215,7 @@ The following *ledger-state types* are supported.
Each ledger type supports a set of operations, which can be invoked with
```compact
-.()
+.()
```
A ledger field that is declared with a Compact type `T` implicitly has the type
@@ -1402,7 +1401,7 @@ reachable from an exported circuit.
A contract can be initialized via a contract constructor defined at the
program's top level.
-| constructor-definition | → | constructor pattern-parameter-list block |
| pattern-parameter-list | → | ( typed-pattern , … , typed-pattern ,opt ) |
+| constructor-definition | → | constructor pattern-parameter-list block |
| pattern-parameter-list | → | ( typed-pattern , ⋯ , typed-pattern ,opt ) |
| typed-pattern | → | pattern : type |
The constructor, if any, is typically used to initialize public state
@@ -1457,7 +1456,7 @@ in [Circuits and witness calls](#circuits-and-witness-calls).
Named circuit definitions have the following syntax:
| circuit-definition | → | exportopt pureopt circuit function-name gparamsopt pattern-parameter-list : type block |
-| pattern-parameter-list | → | ( typed-pattern , … , typed-pattern ,opt ) |
+| pattern-parameter-list | → | ( typed-pattern , ⋯ , typed-pattern ,opt ) |
| typed-pattern | → | pattern : type |
A circuit definition binds `function-name` to a circuit with the given parameters,
@@ -1521,11 +1520,11 @@ if present, e.g.:
```compact
pure circuit c(a: Field): Field {
- ...
+ ⋯
}
export pure circuit c(a: Field): Field {
- ...
+ ⋯
}
```
@@ -1540,7 +1539,7 @@ Compact program by the Compact compiler.
A `block` is a group of statements enclosed in braces:
-| block | → | \{ stmt … stmt } |
+
A block can be used in place of a single statement anywhere a single statement
is allowed, which is useful for allowing multiple statements to be evaluated by the
@@ -1564,7 +1563,7 @@ A block is evaluated by evaluating the statements in sequence.
The syntax of Compact statements is summarized by the following grammar snippet:
+| stmt0 | → | expr-seq ; |
| | | | const cbinding , ⋯¹ , cbinding ; |
| | | | if ( expr-seq ) stmt0 else stmt |
| | | | for ( const id of nat .. nat ) stmt |
| | | | for ( const id of expr-seq ) stmt |
| | | | return expr-seq ; |
| | | | return ; |
| | | | block |
The snippet shows that a statement (`stmt`) is either a one-armed `if` expression
or some other kinf of statement (`stmt0`).
@@ -1607,7 +1606,7 @@ in the syntax specified by the following grammar snippet:
| cbinding | → | optionally-typed-pattern = expr |
| optionally-typed-pattern | → | pattern |
| | | | typed-pattern |
-| pattern | → | id |
| | | | [ patternopt , … , patternopt ,opt ] |
| | | | \{ pattern-struct-elt , … , pattern-struct-elt ,opt } |
+| pattern | → | id |
| | | | [ patternopt , ⋯ , patternopt ,opt ] |
| | | | \{ pattern-struct-elt , ⋯ , pattern-struct-elt ,opt } |
| pattern-struct-elt | → | id |
| | | | id : pattern |
| typed-pattern | → | pattern : type |
@@ -1811,7 +1810,7 @@ subsequent statements, and it returns to the caller the value of `expr-seq` or
The syntax of Compact expressions is summarized by the following grammar snippet:
-| expr-seq | → | expr |
| | | | expr , …¹ , expr , expr |
+| expr-seq | → | expr |
| | | | expr , ⋯¹ , expr , expr |
| expr | → | expr0 ? expr : expr |
| | | | expr0 = expr |
| | | | expr0 += expr |
| | | | expr0 -= expr |
| | | | expr0 |
| expr0 | → | expr0 || expr1 |
| | | | expr1 |
| expr1 | → | expr1 && expr2 |
| | | | expr2 |
@@ -1821,8 +1820,8 @@ The syntax of Compact expressions is summarized by the following grammar snippet
| expr5 | → | expr5 + expr6 |
| | | | expr5 - expr6 |
| | | | expr6 |
| expr6 | → | expr6 * expr7 |
| | | | expr7 |
| expr7 | → | ! expr7 |
| | | | expr8 |
-| expr8 | → | expr8 [ expr ] |
| | | | expr8 . id |
| | | | expr8 . id ( expr , … , expr ,opt ) |
| | | | expr9 |
-| expr9 | → | fun ( expr , … , expr ,opt ) |
| | | | map ( fun , expr , …¹ , expr ,opt ) |
| | | | fold ( fun , expr , expr , …¹ , expr ,opt ) |
| | | | slice \< tsize > ( expr , expr ) |
| | | | [ tuple-arg , … , tuple-arg ,opt ] |
| | | | Bytes [ bytes-arg , … , bytes-arg ,opt ] |
| | | | tref \{ struct-arg , … , struct-arg ,opt } |
| | | | assert ( expr , str ) |
| | | | disclose ( expr ) |
| | | | term |
+| expr8 | → | expr8 [ expr ] |
| | | | expr8 . id |
| | | | expr8 . id ( expr , ⋯ , expr ,opt ) |
| | | | expr9 |
+| expr9 | → | fun ( expr , ⋯ , expr ,opt ) |
| | | | map ( fun , expr , ⋯¹ , expr ,opt ) |
| | | | fold ( fun , expr , expr , ⋯¹ , expr ,opt ) |
| | | | slice \< tsize > ( expr , expr ) |
| | | | [ tuple-arg , ⋯ , tuple-arg ,opt ] |
| | | | Bytes [ bytes-arg , ⋯ , bytes-arg ,opt ] |
| | | | tref \{ struct-arg , ⋯ , struct-arg ,opt } |
| | | | assert ( expr , str ) |
| | | | disclose ( expr ) |
| | | | term |
| tuple-arg | → | expr |
| | | | ... expr |
| bytes-arg | → | tuple-arg |
| struct-arg | → | expr |
| | | | id : expr |
| | | | ... expr |
| term | → | id |
| | | | true |
| | | | false |
| | | | nat |
| | | | str |
| | | | pad ( nat , str ) |
| | | | default \< type > |
| | | | ( expr-seq ) |
@@ -1910,7 +1909,7 @@ An expression sequence (`expr-seq` in the grammar above) is a comma-separated
sequence of one or more expressions.
```compact
-expression, ..., expression
+expression, ⋯, expression
```
Expression sequences can appear only in a few contexts.
@@ -1918,7 +1917,7 @@ When an expression sequence is required in a context where only a single express
is permitted, the expression sequence can be wrapped in parentheses:
```compact
-(expression, ..., expression)
+(expression, ⋯, expression)
```
The type of an expression sequence is the type of its last subexpression.
@@ -2017,7 +2016,7 @@ are as follows:
- `Boolean`: the value of the literal `false`
- `Uint<0..n>` and `Uint`: `0`
- `Field`: `0`
-- `[T, ...]` where `T, ...` is a sequence of zero or more types: the tuple with
+- `[T, ⋯]` where `T, ⋯` is a sequence of zero or more types: the tuple with
the corresponding length, each of the default value of the corresponding type
- `Bytes`: the byte vector of length `n` with all zero bytes
- `Opaque<"string">`: an empty string, i.e., `""`
@@ -2242,8 +2241,8 @@ message indicating that the cast of the value to `Feet` failed.
### Tuple creation
-New tuple values are created with expressions of the form `[tuple-arg, ...]` where
-`tuple-arg, ...` is a sequence of zero or more comma-separated tuple
+New tuple values are created with expressions of the form `[tuple-arg, ⋯]` where
+`tuple-arg, ⋯` is a sequence of zero or more comma-separated tuple
arguments.
A non-empty sequence can have an optional trailing comma.
Each tuple argument is either an expression or a *spread*.
@@ -2255,8 +2254,8 @@ If a tuple argument is a spread `... expr`, the type `T` of `expr` must be
a tuple type, a Vector type, or a Bytes type.
Otherwise, it is a static error.
-If `expr` has a tuple type `[U, ...]` of length *n*, the spread contributes
-`n` new elements of type `U, ...` to to the new tuple, i.e., the elements
+If `expr` has a tuple type `[U, ⋯]` of length *n*, the spread contributes
+`n` new elements of type `U, ⋯` to to the new tuple, i.e., the elements
of the tuple value of `expr`.
If `expr` has a Vector type `Vector`, the spread contributes
`n` new elements of type `U` to to the new tuple, i.e., the elements
@@ -2277,7 +2276,7 @@ which can be less than or greater than number of tuple arguments.
### Byte-vector creation
New byte vectors are created with expressions of the form
-`Bytes [tuple-arg, ...]`.
+`Bytes [tuple-arg, ⋯]`.
Bytes creation is essentially the same as [tuple creation](#tuple-creation)
except that the types of the contributed elements must all be subtypes of `Uint<8>`
(if not, it is static error), and the result is a new byte vector of type
@@ -2322,10 +2321,10 @@ via the following rules, or it is a static error.
The type of a byte-vector reference is `Uint<8>`.
The type of a vector reference where the vector has type `Vector` is `T`.
-The type of a tuple reference where the tuple has type `[T1, ..., Tn]` is
+The type of a tuple reference where the tuple has type `[T1, ⋯, Tn]` is
`Ti` if `index` is the constant `i` or the value `i` of a generic natural-number
parameter.
-Otherwise, `[T1, ..., Tn]` must have a vector type `Vector` and the
+Otherwise, `[T1, ⋯, Tn]` must have a vector type `Vector` and the
type of the tuple reference is `T`.
The value of a sequence reference is element `i` (zero-based) of the result
@@ -2348,10 +2347,10 @@ references](#tuple-vector-and-byte-vector-references).
The type of a byte-vector slice is `Bytes` where `k` is the constant value of `size`.
The type of a vector slice where the vector has type `Vector` is `Vector`.
-The type of a tuple slice where the tuple has type `[T1, ..., Tn]` is the subsequence
-`[Ti, ..., Tj]` starting with element `i` (zero-based) and ending with element
-`j = i + k - 1` of `[T1, ..., Tn]`.
-Otherwise, `[T1, ..., Tn]` must have a vector type `Vector` and the
+The type of a tuple slice where the tuple has type `[T1, ⋯, Tn]` is the subsequence
+`[Ti, ⋯, Tj]` starting with element `i` (zero-based) and ending with element
+`j = i + k - 1` of `[T1, ⋯, Tn]`.
+Otherwise, `[T1, ⋯, Tn]` must have a vector type `Vector` and the
type of the tuple reference is `Vector`.
The value of a `slice` expression is subsequence of the original tuple, vector,
@@ -2382,9 +2381,9 @@ Bytes[18, 19, 20]
### Structure creation
Structure values are created with structure creation expressions. The
-expression `T {f, ...}` is a structure creation expression, where `T` is a
-structure type name `S` or specialized generic structure type name `S`,
-and `f, ...` is a sequence of zero or more comma-separated field-value specifiers.
+expression `T {f, ⋯}` is a structure creation expression, where `T` is a
+structure type name `S` or specialized generic structure type name `S`,
+and `f, ⋯` is a sequence of zero or more comma-separated field-value specifiers.
A field-value specifier can be one of three things:
@@ -2510,9 +2509,9 @@ type of `e` is an enumeration type.
### Circuit and witness calls
| fun | → | id gargsopt |
| | | | arrow-parameter-list return-typeopt => block |
| | | | arrow-parameter-list return-typeopt => expr |
| | | | ( fun ) |
-| arrow-parameter-list | → | ( optionally-typed-pattern , … , optionally-typed-pattern ,opt ) |
+| arrow-parameter-list | → | ( optionally-typed-pattern , ⋯ , optionally-typed-pattern ,opt ) |
| optionally-typed-pattern | → | pattern |
| | | | typed-pattern |
-| pattern | → | id |
| | | | [ patternopt , … , patternopt ,opt ] |
| | | | \{ pattern-struct-elt , … , pattern-struct-elt ,opt } |
+| pattern | → | id |
| | | | [ patternopt , ⋯ , patternopt ,opt ] |
| | | | \{ pattern-struct-elt , ⋯ , pattern-struct-elt ,opt } |
| pattern-struct-elt | → | id |
| | | | id : pattern |
| typed-pattern | → | pattern : type |
| return-type | → | : type |
From 4130811c992993d25c8565efd330e1e8171d2b6e Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Tue, 10 Mar 2026 16:25:44 +0100
Subject: [PATCH 09/41] latest compact reference, grammar, and keywords mdx
files
---
docs/compact/reference/compact-grammar.mdx | 8 +++++++-
docs/compact/reference/compact-keywords.mdx | 6 ++++++
docs/compact/reference/lang-ref.mdx | 22 +++++++++------------
3 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/docs/compact/reference/compact-grammar.mdx b/docs/compact/reference/compact-grammar.mdx
index 66960f59..8a7ba085 100644
--- a/docs/compact/reference/compact-grammar.mdx
+++ b/docs/compact/reference/compact-grammar.mdx
@@ -1,6 +1,12 @@
+---
+SPDX-License-Identifier: Apache-2.0
+copyright: This file is part of midnight-docs. Copyright (C) 2025 Midnight Foundation. Licensed under the Apache License, Version 2.0 (the "License"); You may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+title: Compact grammar
+---
+
# Compact grammar
-Compact language version 0.21.0.
+Compact language version 0.21.101.
Notational note: In the grammar below, terminals are in `monospaced` font. Non-terminals are in *emphasized* font. Alternation is indicated by a vertical bar (`|`). Optional items are indicated by the superscript opt. Repetition is specified by ellipses. The notation *X* ⋯ *X*, where *X* is a grammar symbol, represents zero or more occurrences of *X*. The notation *X* `,` ⋯ `,` *X*, where *X* is a grammar symbol and `,` is a literal comma, represents zero or more occurrences of *X* separated by commas. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one *X*. When such a sequence is followed by *,*opt, an optional trailing comma is allowed, but only if there is at least one *X*. For example, *id* ⋯ *id* represents zero or more *id*s, and *expr* `,` ⋯¹`,` *expr* `,`opt represents one or more comma-separated *expr*s possibly followed by an extra comma. The rules involving commas apply equally to semicolons, i.e., apply when `,` is replaced by `;`.
diff --git a/docs/compact/reference/compact-keywords.mdx b/docs/compact/reference/compact-keywords.mdx
index bdc7c3c9..02e10527 100644
--- a/docs/compact/reference/compact-keywords.mdx
+++ b/docs/compact/reference/compact-keywords.mdx
@@ -1,3 +1,9 @@
+---
+SPDX-License-Identifier: Apache-2.0
+copyright: This file is part of midnight-docs. Copyright (C) 2025 Midnight Foundation. Licensed under the Apache License, Version 2.0 (the "License"); You may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+title: Compact keywords
+---
+
# Compact keywords
## Module-related keywords
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index 7f281641..317d7de3 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -1,3 +1,9 @@
+---
+SPDX-License-Identifier: Apache-2.0
+copyright: This file is part of midnight-docs. Copyright (C) 2025 Midnight Foundation. Licensed under the Apache License, Version 2.0 (the "License"); You may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+title: Compact reference
+---
+
# Compact reference
## Overview
@@ -244,7 +250,7 @@ Various entities, specifically
[type-alias declarations](#type-aliases),
[circuit definitions](#circuits),
and
-[witness declarations](#declaring-witnesses-for-private-state),
+[witness declarations](#declaring-witnesses-for-private-state-management),
can have *generic parameters*, i.e., compile-time type and numeric (natural-number)
parameters whose values are given at the use site rather than fixed at the point
of declaration.
@@ -1451,7 +1457,7 @@ that circuits cannot be recursive, either directly or indirectly.
Compact supports two kinds of circuits: named circuits and anonymous circuits.
Named circuits are described here, and anonymous circuits are described
-in [Circuits and witness calls](#circuits-and-witness-calls).
+in [Circuit and witness calls](#circuit-and-witness-calls).
Named circuit definitions have the following syntax:
@@ -1681,7 +1687,7 @@ expression as described earlier in
(Patterns and destructuring)[patterns-and-destructuring].
Any variable bound by `const` may not be reused within a block, although a
-`const` binding in a nested block might [shadow it](#scope-and-binding).
+`const` binding in a nested block might [shadow it](#identifiers-bindings-and-scope).
Variables are immutable, although the same variable might take on different values
at different times if is contined within a block of code that is evaluated more
than once, such as would be the case for the body of a `circuit` that is called
@@ -2716,12 +2722,6 @@ The following rules govern when casts are allowed, when casts might cause run-ti
errors, and casts might require run-time conversions.
Any cast not covered by one of the rules is not allowed.
-!!!!!!!! TBD verify all of these claims -- Parisa
-
-!!!!!!!! TBD mention of cast of state-ledger types ?
-
-!!!!!!!! TBD ??? In meeting convo: Do we have all the cases for downcast? check the code in analysis pass to see if it does what the claims say. the downcast isn't correct, even the example isn't correct.
-
#### Upcasts
- Upcasts, i.e., casts from a type to a (supertype)[subtyping-and-least-upper-bounds]
@@ -2729,8 +2729,6 @@ Any cast not covered by one of the rules is not allowed.
(but never required), never result in run-time errors, and, except in the case
where the type and the supertype are the same, might require run-time conversions.
-!!!!!!!! TBD Might want to mention other impliciations of this rule, such as rules for casting tuples to vectors and back
-
#### Downcasts of `Field` and `Uint` types
- `Uint` downcasts, i.e., casts from `Uint` to `Uint`, `m > n`, are always
@@ -3032,8 +3030,6 @@ representation length in bytes (almost always 1).
## TypeScript target
-!!!!!!!! TBD Parisa should check this section to verify it matches reality
-
When compiled, a contract generates several artifacts. Key to these
are the exported circuits from the contract's top level. These are
divided into two categories: [pure circuits and impure circuits](#pure-and-impure-circuits).
From ad442c350930a39deedc8928a168f03e4f7c3c1f Mon Sep 17 00:00:00 2001
From: pataei
Date: Tue, 10 Mar 2026 11:21:45 -0400
Subject: [PATCH 10/41] fix links
---
docs/compact/reference/lang-ref.mdx | 18 +++++++++---------
docs/compact/{ => reference}/writing.mdx | 0
2 files changed, 9 insertions(+), 9 deletions(-)
rename docs/compact/{ => reference}/writing.mdx (100%)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index 317d7de3..08a1a176 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -1878,7 +1878,7 @@ addition, since the left operand can be at the same level while the right
operand is at a higher level.
This means that `x + y - z` can be treated only as the subtraction of `z`
from `x + y` rather than as the addition of `x` and `y - z`.
-Right-associativity is expressed in the opposite manner, e.g.,
+Right-associativity is expressed in the opposite manner, e.g.,
`expr_0 ? expr : expr` enforces the right-associativity of the
ternary `?:` operator.
Non-associative operators such as the relational operators `<`, `<=`, `>=`, `>` have
@@ -2126,7 +2126,7 @@ has a specific structure type, so does the other.
The values are equal if the corresponding members are equal.
- **Enumeration types:**
The values are equal if they are the same enumeration member.
-- **`Opaque types:`**
+- **`Opaque types:`**
The values are equal if the runtime values are equal according to JavaScript's
strict equalty (`===`) operator.
@@ -2153,12 +2153,12 @@ expression as follows:
- For `||`, if the value of the left subexpression is `true` the right
subexpression is *not* evaluated, i.e., short-circuited, and the value
- of the entire expression is `true`.
+ of the entire expression is `true`.
Otherwise, the right subexpression *is* evaluated, and its value is the
value of the entire expression.
- For `&&`, if the value of the left subexpression is `false` the right
subexpression is *not* evaluated, i.e., short-circuited, and the value
- of the entire expression is `false`.
+ of the entire expression is `false`.
Otherwise, the right subexpression *is* evaluated, and its value is the
value of the entire expression.
@@ -2489,7 +2489,7 @@ The value of any structure member access `e.id` is the result of evaluating the
subexpression `e` and extracting the value of the resulting structure's
`id` member.
-Some expressions of the form `e.id` can also be
+Some expressions of the form `e.id` can also be
[enumeration member accesses](#enumeration-member-access) or
[ledger `read` operations](#ledger-state-operations).
`e.id` is recognized as a structure member access only when the
@@ -2506,7 +2506,7 @@ The type of any enumeration member access `E.id` is `E`.
`E.id` is a constant.
That is, the value of any enumeration member access `E.id` is `E.id`.
-Some expressions of the form `e.id` can also be
+Some expressions of the form `e.id` can also be
[structure member accesses](#enumeration-member-access) or
[ledger `read` operations](#ledger-state-operations).
`e.id` is recognized as an enumeration member access only when the
@@ -2965,7 +2965,7 @@ scope of this document, but a few things are worth noting:
the actual disclosure site as possible.
- When disclosing a hashed or otherwise obfuscated variant of witness data,
place the disclosure somewhere on the path between input and disclosure
- *after* the obfuscation to help prevent disclosure of the unobfuscated
+ *after* the obfuscation to help prevent disclosure of the unobfuscated
input.
More details are given in
@@ -3112,7 +3112,7 @@ Note that other `Opaque` types are currently not supported.
Compact compiler version 1.0 limits certain datatype values and sizes:
-- The maximum value of a `Field` value is
+- The maximum value of a `Field` value is
52435875175126190479447740508185965837690552500527637822603658699938581184512.
This value is dictated by the scalar field size of the ZK proving system.
- The maximum value of a `Uint` value is
@@ -3154,4 +3154,4 @@ See [here](explicit-disclosure).
### Writing a contract in Compact
-See [here](../writing).
+See [here](writing).
diff --git a/docs/compact/writing.mdx b/docs/compact/reference/writing.mdx
similarity index 100%
rename from docs/compact/writing.mdx
rename to docs/compact/reference/writing.mdx
From 082713548c924fc156679c249dd5596b7def2ec6 Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Wed, 11 Mar 2026 07:06:48 +0100
Subject: [PATCH 11/41] updated lang ref
---
docs/compact/reference/lang-ref.mdx | 58 +++++++++++++----------------
1 file changed, 25 insertions(+), 33 deletions(-)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index 317d7de3..60f58313 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -388,8 +388,8 @@ The following are the primitive types of Compact:
The current maximum field value is given in
[Implementation-specific limits](#implementation-specific-limits).
-- `[T, ⋯]`, where `T, ⋯` are zero or more comma-separated types, is the type
- of *tuple* values with element types `T, ⋯`.
+- `[T, `⋯`]`, where `T`, ⋯ are zero or more comma-separated types, is the type
+ of *tuple* values with element types `T`, ⋯.
Tuples are heterogeneous: any element type can differ from any of the others.
The *length* of a tuple type is the number of element types.
Two tuple types with different lengths are different types.
@@ -399,7 +399,7 @@ The following are the primitive types of Compact:
- `Vector`, where `n` is a natural number literal or generic natural-number
parameter and `T` is a type, is a shorthand notation for the tuple type
- `[T, ⋯]` with `n` occurrences of the type `T`.
+ `[T, `⋯`]` with `n` occurrences of the type `T`.
Note that a vector type and the corresponding tuple type are two different ways
of writing exactly the same type.
Unless otherwise specified, type rules for vector types are derived from the
@@ -635,7 +635,7 @@ Subtyping is defined by the following rules:
- Any type `T` is a subtype of itself (subtyping is reflexive)
- `Uint<0..n>` is a subtype of `Uint<0..m>` if `n` is less than (or equal to) `m`
- `Uint<0..n>` is a subtype of `Field` for all `n`
-- The tuple type `[T, ⋯]` is a subtype of the tuple type `[S, ⋯]`
+- The tuple type `[T, `⋯`]` is a subtype of the tuple type `[S, `⋯`]`
if they have the same length and each type `T` is a subtype of the
corresponding type `S`.
@@ -651,12 +651,12 @@ Note that least upper bounds do not exist for all sets of types, because
some types (such as `Boolean` and `Field`) are not related.
**Tuple and vector types:** Every vector type has an equivalent tuple type:
-`Vector` is equivalent to (in fact, the same type as) `[T1, ⋯, Tn]`.
+`Vector` is equivalent to (in fact, the same type as) `[T1, `⋯`, Tn]`.
The converse is not always true.
For example, neither `[Boolean, Field]` nor `[Uint<8>, Uint<16>]` have an
equivalent vector type.
-We say, however, that a tuple type [T1, ⋯, Tn] with possibly distinct types `T1, ⋯, Tn`
+We say, however, that a tuple type `[T1, `⋯`, Tn]` with possibly distinct types `T1`, ⋯, `Tn`
"*has a vector type*" if the least upper bound `S` of the set of types \{`T1`, ⋯, `Tn`}
exists.
In that case, the tuple type has the vector type `Vector`.
@@ -671,7 +671,7 @@ vector type `Vector<2, Uint<16>>`, but the types are not equivalent.
Every vector type is a subtype of the equivalent tuple type and possibly of some
other tuple types.
-In general, a vector type `Vector` is a subtype of a tuple type `[S1, ⋯, Sn]`
+In general, a vector type `Vector` is a subtype of a tuple type `[S1, `⋯`, Sn]`
if `T` is a subtype of each of the types `S1`, ⋯, `Sn`.
The means, for instance, that a vector can often be passed to a circuit where a
tuple is expected.
@@ -1220,9 +1220,7 @@ The following *ledger-state types* are supported.
Each ledger type supports a set of operations, which can be invoked with
-```compact
-.()
-```
+`.()`
A ledger field that is declared with a Compact type `T` implicitly has the type
`Cell`, which supports several operations, including `read`, `write`, and
@@ -1524,15 +1522,9 @@ A Compact program can declare a circuit to be pure by prefixing the circuit
definition with the `pure` modifier, which must follow the `export` modifier,
if present, e.g.:
-```compact
-pure circuit c(a: Field): Field {
- ⋯
-}
+`pure circuit c(a: Field): Field { `⋯` }`
-export pure circuit c(a: Field): Field {
- ⋯
-}
-```
+`export pure circuit c(a: Field): Field { `⋯` }`
The only effect of the `pure` modifier is that the compiler flags the
declaration as an error if its own analysis determines that the circuit is
@@ -2022,7 +2014,7 @@ are as follows:
- `Boolean`: the value of the literal `false`
- `Uint<0..n>` and `Uint`: `0`
- `Field`: `0`
-- `[T, ⋯]` where `T, ⋯` is a sequence of zero or more types: the tuple with
+- `[T, `⋯`]` where `T`, ⋯ is a sequence of zero or more types: the tuple with
the corresponding length, each of the default value of the corresponding type
- `Bytes`: the byte vector of length `n` with all zero bytes
- `Opaque<"string">`: an empty string, i.e., `""`
@@ -2247,8 +2239,8 @@ message indicating that the cast of the value to `Feet` failed.
### Tuple creation
-New tuple values are created with expressions of the form `[tuple-arg, ⋯]` where
-`tuple-arg, ⋯` is a sequence of zero or more comma-separated tuple
+New tuple values are created with expressions of the form `[tuple-arg, `⋯`]` where
+`tuple-arg`, ⋯ is a sequence of zero or more comma-separated tuple
arguments.
A non-empty sequence can have an optional trailing comma.
Each tuple argument is either an expression or a *spread*.
@@ -2260,8 +2252,8 @@ If a tuple argument is a spread `... expr`, the type `T` of `expr` must be
a tuple type, a Vector type, or a Bytes type.
Otherwise, it is a static error.
-If `expr` has a tuple type `[U, ⋯]` of length *n*, the spread contributes
-`n` new elements of type `U, ⋯` to to the new tuple, i.e., the elements
+If `expr` has a tuple type `[U, `⋯`]` of length *n*, the spread contributes
+`n` new elements of type `U`, ⋯ to to the new tuple, i.e., the elements
of the tuple value of `expr`.
If `expr` has a Vector type `Vector`, the spread contributes
`n` new elements of type `U` to to the new tuple, i.e., the elements
@@ -2282,7 +2274,7 @@ which can be less than or greater than number of tuple arguments.
### Byte-vector creation
New byte vectors are created with expressions of the form
-`Bytes [tuple-arg, ⋯]`.
+`Bytes [tuple-arg, `⋯`]`.
Bytes creation is essentially the same as [tuple creation](#tuple-creation)
except that the types of the contributed elements must all be subtypes of `Uint<8>`
(if not, it is static error), and the result is a new byte vector of type
@@ -2327,10 +2319,10 @@ via the following rules, or it is a static error.
The type of a byte-vector reference is `Uint<8>`.
The type of a vector reference where the vector has type `Vector` is `T`.
-The type of a tuple reference where the tuple has type `[T1, ⋯, Tn]` is
+The type of a tuple reference where the tuple has type `[T1, `⋯`, Tn]` is
`Ti` if `index` is the constant `i` or the value `i` of a generic natural-number
parameter.
-Otherwise, `[T1, ⋯, Tn]` must have a vector type `Vector` and the
+Otherwise, `[T1, `⋯`, Tn]` must have a vector type `Vector` and the
type of the tuple reference is `T`.
The value of a sequence reference is element `i` (zero-based) of the result
@@ -2353,10 +2345,10 @@ references](#tuple-vector-and-byte-vector-references).
The type of a byte-vector slice is `Bytes` where `k` is the constant value of `size`.
The type of a vector slice where the vector has type `Vector` is `Vector`.
-The type of a tuple slice where the tuple has type `[T1, ⋯, Tn]` is the subsequence
-`[Ti, ⋯, Tj]` starting with element `i` (zero-based) and ending with element
-`j = i + k - 1` of `[T1, ⋯, Tn]`.
-Otherwise, `[T1, ⋯, Tn]` must have a vector type `Vector` and the
+The type of a tuple slice where the tuple has type `[T1, `⋯`, Tn]` is the subsequence
+`[Ti, `⋯`, Tj]` starting with element `i` (zero-based) and ending with element
+`j = i + k - 1` of `[T1, `⋯`, Tn]`.
+Otherwise, `[T1, `⋯`, Tn]` must have a vector type `Vector` and the
type of the tuple reference is `Vector`.
The value of a `slice` expression is subsequence of the original tuple, vector,
@@ -2387,9 +2379,9 @@ Bytes[18, 19, 20]
### Structure creation
Structure values are created with structure creation expressions. The
-expression `T {f, ⋯}` is a structure creation expression, where `T` is a
-structure type name `S` or specialized generic structure type name `S`,
-and `f, ⋯` is a sequence of zero or more comma-separated field-value specifiers.
+expression `T {f, `⋯`}` is a structure creation expression, where `T` is a
+structure type name `S` or specialized generic structure type name `S`,
+and `f, `⋯ is a sequence of zero or more comma-separated field-value specifiers.
A field-value specifier can be one of three things:
From 290eabc9b26c2e6023d43d51838b44f02081198c Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Wed, 11 Mar 2026 11:00:52 +0100
Subject: [PATCH 12/41] latest compact-reference.mdx and compact-grammar.mdx
---
docs/compact/reference/compact-grammar.mdx | 4 +-
docs/compact/reference/lang-ref.mdx | 64 +++++++++++++++++++---
2 files changed, 59 insertions(+), 9 deletions(-)
diff --git a/docs/compact/reference/compact-grammar.mdx b/docs/compact/reference/compact-grammar.mdx
index 8a7ba085..6eeda71a 100644
--- a/docs/compact/reference/compact-grammar.mdx
+++ b/docs/compact/reference/compact-grammar.mdx
@@ -6,9 +6,9 @@ title: Compact grammar
# Compact grammar
-Compact language version 0.21.101.
+Compact language version 0.22.0.
-Notational note: In the grammar below, terminals are in `monospaced` font. Non-terminals are in *emphasized* font. Alternation is indicated by a vertical bar (`|`). Optional items are indicated by the superscript opt. Repetition is specified by ellipses. The notation *X* ⋯ *X*, where *X* is a grammar symbol, represents zero or more occurrences of *X*. The notation *X* `,` ⋯ `,` *X*, where *X* is a grammar symbol and `,` is a literal comma, represents zero or more occurrences of *X* separated by commas. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one *X*. When such a sequence is followed by *,*opt, an optional trailing comma is allowed, but only if there is at least one *X*. For example, *id* ⋯ *id* represents zero or more *id*s, and *expr* `,` ⋯¹`,` *expr* `,`opt represents one or more comma-separated *expr*s possibly followed by an extra comma. The rules involving commas apply equally to semicolons, i.e., apply when `,` is replaced by `;`.
+Notational note: In the grammar below, keywords and punctuation are in `monospaced` font. Terminal and nonterminal names are in *emphasized* font. Alternation is indicated by a vertical bar (`|`). Optional items are indicated by the superscript opt. Repetition is specified by ellipses. The notation *X* ⋯ *X*, where *X* is a grammar symbol, represents zero or more occurrences of *X*. The notation *X* `,` ⋯ `,` *X*, where *X* is a grammar symbol and `,` is a literal comma, represents zero or more occurrences of *X* separated by commas. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one *X*. When such a sequence is followed by *,*opt, an optional trailing comma is allowed, but only if there is at least one *X*. For example, *id* ⋯ *id* represents zero or more *id*s, and *expr* `,` ⋯¹`,` *expr* `,`opt represents one or more comma-separated *expr*s possibly followed by an extra comma. The rules involving commas apply equally to semicolons, i.e., apply when `,` is replaced by `;`.
#### end-of-file (*eof*)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index 3808e3f0..6fa10551 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -91,11 +91,11 @@ separately.
## Notation
-The syntax of Compact programs is given by an EBNF grammar. We use the
-following notational conventions in the grammar:
+The syntax of Compact programs is given by EBNF grammar snippets that
+use the following notational conventions:
-- Terminals are in `monospaced` font.
-- Non-terminals are in *emphasized* font.
+- Keywords and punctuation are in `monospaced` font.
+- Terminal and nonterminal names are in *emphasized* font.
- Alternation is indicated by a vertical bar (`|`).
- Optional items are indicated by the superscript opt.
- Repetition is specified by ellipses.
@@ -114,6 +114,54 @@ following notational conventions in the grammar:
The rules involving commas apply equally to semicolons, i.e., apply when
`,` is replaced by `;`.
+Every program is formed of characters that are organized into atomic
+sequences of characters known as *tokens*.
+Each keyword and punctionation symbol appearing in the grammar snippets
+represents itself exactly, i.e., represents the token consisting of
+the same sequence of characters.
+For example, when the keyword `circuit` appears in a grammar snippet,
+it matches only the token `circuit`, and when the punctuation symbol
+`:` appears, it matches only the token `:`.
+
+Each terminal name appearing in the grammar snippets represents a set
+of possible tokens.
+For example, the terminal name *id* represents the set of all
+identifiers: when *id* appears in a grammar snippet, it matches any
+identifier.
+The sets of tokens represented by the terminal names appearing in
+the grammar snippets are described in
+[Terminal names](#terminal-names) below.
+
+Each nonterminal name appearing in the grammar snippets represents a
+sequence of tokens that comprise some structured piece of a program.
+For example, the terminal name *expr* matches any sequence of tokens
+that can be interpreted as an expression, such as `3 + x` or
+`a ? b : c`.
+The set of structures represented by each nonterminal name is given
+in the various sections of this reference manual along with typing
+and evaluation rules where appropriate.
+For example, the structure of a *circuit-definition* is described
+in [Circuits definitions](#circuit-definitions).
+
+## Terminal names
+
+The following terminal names appear in the grammar snippets.
+
+- *id*, *module-name*, *function-name*, *struct-name*, *enum-name*,
+*contract-name*, *tvar-name*, and *type-name*
+all represent identifier tokens.
+
+- *nat* represents natural-number literals.
+
+- *str* and *file* represent string literals.
+
+- *version* represents version literals (in pragmas).
+
+While identifiers and string literals are each represented by more than one name,
+each representes the entire set of possible identifier or string-literal tokens.
+The grammar snippets use different terminal names only to suggest their use, e.g,
+*module-name* for module names versus *tvar-name* for type variable names.
+
## Static and dynamic errors
The compiler detects various kinds of *static errors*, e.g., malformed syntax,
@@ -248,7 +296,7 @@ Various entities, specifically
[module declarations](#modules-exports-and-imports),
[structure declarations](#structure-types),
[type-alias declarations](#type-aliases),
-[circuit definitions](#circuits),
+[circuit definitions](#circuit-definitions),
and
[witness declarations](#declaring-witnesses-for-private-state-management),
can have *generic parameters*, i.e., compile-time type and numeric (natural-number)
@@ -855,7 +903,7 @@ Briefly:
- A [witness declaration](#declaring-witnesses-for-private-state-management) declare a witness, which is a function provided by the Dapp.
- A [ledger declaration](#declaring-and-maintaining-public-state) declares one field of the contract's public state.
- A [constructor definition](#contract-constructor) defines the contract's constructor, if any.
-- A [circuit definition](#circuits) defines a circuit.
+- A [circuit definition](#circuit-definitions) defines a circuit.
The order of program elements in a program or module is unimportant, except that
any module must be defined before any import of the module, and any program-defined
@@ -1085,6 +1133,8 @@ TypeScript driver for the smart contract.
The circuits exported at the top level of a contract (i.e., not merely exported
from a module) are the entry points of the contract.
+(A Compact program has no "main" entry point, but is more similar to a library
+containing multiple entry points that share a common store.)
Although multiple circuits with the same name are allowed generally to support
[function overloading](#circuit-and-witness-calls), it is a static error if more
than one circuit with the same name is exported from the top level.
@@ -1445,7 +1495,7 @@ The return type of the constructor is always `[]`.
Any attempt to return another type of value using `return expression;` where the
type of `expression` is something other than `[]`, is a static error.
-## Circuits
+## Circuit definitions
The basic operational element in Compact is the `circuit`.
This corresponds closely to a function in most languages but is designed
From 5854c37ec99cfd2eeb97617ab8b5d67a41430c44 Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Wed, 11 Mar 2026 15:27:10 +0100
Subject: [PATCH 13/41] latest lang-ref.mdx
---
docs/compact/reference/lang-ref.mdx | 32 +++++++++++++++++++++--------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index 6fa10551..e502cf3d 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -116,7 +116,7 @@ use the following notational conventions:
Every program is formed of characters that are organized into atomic
sequences of characters known as *tokens*.
-Each keyword and punctionation symbol appearing in the grammar snippets
+Each keyword and punctuation symbol appearing in the grammar snippets
represents itself exactly, i.e., represents the token consisting of
the same sequence of characters.
For example, when the keyword `circuit` appears in a grammar snippet,
@@ -178,7 +178,7 @@ These errors are reported when the generated code is run.
Identifiers are used in Compact, as in most other programming languages, to
name things.
-Syntactally, an *identifier* is a *token* (atomic sequence of characters), beginning
+Syntactically, an *identifier* is a *token* (atomic sequence of characters), beginning
with with an alphabetic character, a dollar sign (`$`), or an underscore (`_`)
followed by one or more alphabetic characters, digits (`0` - `9`), dollar signs,
or underscores.
@@ -895,12 +895,12 @@ Briefly:
contains a sequence of program elements in its own nested scope.
- An [export form](#exports) exports bindings from a module or from [the program itself](#top-level-exports).
- An [import form](#imports) imports bindings from a Compact module.
-- An [include form](#include-files) allows program elements to be included from other Compact programs
+- An [include form](#include-files) allows program elements to be included from other files.
- A [structure definition](#structure-types) defines a structure type.
- An [enumeration definition](#enumeration-types) define an enumeration type.
- A [contract declaration](#contract-types) declares a contract type.
-- A [type alias definition](#type-aliases) defines a type alias, possibly creating a distinct type.
-- A [witness declaration](#declaring-witnesses-for-private-state-management) declare a witness, which is a function provided by the Dapp.
+- A [type-alias definition](#type-aliases) defines a type alias, possibly creating a distinct type.
+- A [witness declaration](#declaring-witnesses-for-private-state-management) declare a witness, which is a callback function provided by the Dapp.
- A [ledger declaration](#declaring-and-maintaining-public-state) declares one field of the contract's public state.
- A [constructor definition](#contract-constructor) defines the contract's constructor, if any.
- A [circuit definition](#circuit-definitions) defines a circuit.
@@ -917,9 +917,8 @@ section.
## Pragmas
-A pragma declares a constraint on either the compiler version or the language
-version. The valid identifiers for the language and compiler versions are
-`language_version` and `compiler_version`, respectively.
+A pragma takes the following form and declares a constraint on either the compiler
+version (*id* = `compiler_version`) or the language version (*id* = `language_version`)
| pragma-form | → | pragma id version-expr ; |
| version-expr | → | version-expr || version-expr0 |
| | | | version-expr0 |
@@ -927,13 +926,28 @@ version. The valid identifiers for the language and compiler versions are
| version-term | → | version-atom |
| | | | ! version-atom |
| | | | \< version-atom |
| | | | \<= version-atom |
| | | | >= version-atom |
| | | | > version-atom |
| | | | ( version-expr ) |
| version-atom | → | nat |
| | | | version |
+*version* is a dot-separated pair or trio of natural numbers, so along
+with *nat* this allows *version* to be either a single natural number,
+a pair of natural numbers separated by a `.`, or a trio of natural numbers
+separate by a `.`, e.g., `1`, `1.2`, or `1.2.7`.
+
+For example, if a program includes the following pragma form:
+
+```compact
+pragma compiler_version >= 1.0.0 && !1.0.5;
+```
+
+All versions of the compiler from 1.0.0 up except for 1.0.5 will accept
+the pragma and compile the program, and all other versions will print an
+appropriate message and discontinue compilation of the program.
+
## Modules, exports, and imports
Modules in Compact are used for namespace management and also possibly to split
programs into multiple files.
A module is a named collection of program elements created via a `module definition`:
-
+
A module definition makes a binding from `module-name` to the module visible in
the program or module containing the module definition.
From 5b5c57672e81a7960adba2288b22a22473f2a7bd Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Wed, 11 Mar 2026 16:21:53 +0100
Subject: [PATCH 14/41] current lang-ref.mdx
---
docs/compact/reference/lang-ref.mdx | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index e502cf3d..b7173359 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -945,7 +945,8 @@ appropriate message and discontinue compilation of the program.
Modules in Compact are used for namespace management and also possibly to split
programs into multiple files.
-A module is a named collection of program elements created via a `module definition`:
+A module is a named collection of program elements created via a module definition,
+which takes the following form:
@@ -1039,7 +1040,7 @@ the file `M.compact` in the same directory as the importing file or in one of th
directories in the compact path.
If *M* is a string `"{prefix/}M"`, where `{prefix/}` is either empty or is
a pathname ending in a directory separator, a definition for a module named
-`M` must be contained within a file `M.compact` that is:
+`M` must be contained within a file `M.compact` that is either:
- (a) if `{prefix/}M.compact` is an absolute pathname, then exactly at
`{prefix/}M.compact`, otherwise
- (b) at `{prefix/}M.compact` relative to the directory of the importing
From 0d3144f98f44bb5f0bb4ce2b1f43168566b08624 Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Wed, 11 Mar 2026 21:48:33 +0100
Subject: [PATCH 15/41] added border: none; to custom.css code {} section to
eliminate the faint border when using the dark on white mode.
---
src/css/custom.css | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/css/custom.css b/src/css/custom.css
index d62d44fb..4af76798 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -528,6 +528,7 @@ code {
background-color: transparent;
padding: 0;
border-radius: 0;
+ border: none;
}
pre {
From 0141f2e96d5d37aa13cacfce3927f4461245a397 Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Thu, 12 Mar 2026 16:04:41 +0100
Subject: [PATCH 16/41] latest lang-ref.mdx and compact-grammar.mdx
---
docs/compact/reference/compact-grammar.mdx | 140 ++++----
docs/compact/reference/lang-ref.mdx | 376 ++++++++++++++++-----
2 files changed, 361 insertions(+), 155 deletions(-)
diff --git a/docs/compact/reference/compact-grammar.mdx b/docs/compact/reference/compact-grammar.mdx
index 6eeda71a..088806f3 100644
--- a/docs/compact/reference/compact-grammar.mdx
+++ b/docs/compact/reference/compact-grammar.mdx
@@ -30,7 +30,7 @@ A string literal has the same syntax as a Typescript string.
A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2.3, representing major, minor, and bugfix versions.
-#### Compact (**program**)
+#### Compact (*program*)
| | | |
@@ -38,7 +38,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *program* | ⟶ | [*pelt*](#Program-element) ⋯ [*pelt*](#Program-element) [*eof*](#end-of-file) |
-#### Program-element (**pelt**)
+#### Program-element (*pelt*)
| | | |
@@ -58,7 +58,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*circuit-definition*](#Circuit-definition) |
-#### Pragma (**pragma-form**)
+#### Pragma (*pragma-form*)
| | | |
@@ -66,7 +66,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *pragma-form* | ⟶ | `pragma` [*id*](#identifier) [*version-expr*](#Version-expression) `;` |
-#### Version-expression (**version-expr**)
+#### Version-expression (*version-expr*)
| | | |
@@ -75,7 +75,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*version-expr0*](#Version-expression0) |
-#### Version-expression0 (**version-expr0**)
+#### Version-expression0 (*version-expr0*)
| | | |
@@ -84,7 +84,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*version-term*](#Version-Term) |
-#### Version-Term (**version-term**)
+#### Version-Term (*version-term*)
| | | |
@@ -98,7 +98,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | `(` [*version-expr*](#Version-expression) `)` |
-#### Version-atom (**version-atom**)
+#### Version-atom (*version-atom*)
| | | |
@@ -107,7 +107,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*version*](#version-literal) |
-#### Include (**include-form**)
+#### Include (*include-form*)
| | | |
@@ -115,7 +115,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *include-form* | ⟶ | `include` [*file*](#string-literal) `;` |
-#### Module-definition (**module-definition**)
+#### Module-definition (*module-definition*)
| | | |
@@ -123,7 +123,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*pelt*](#Program-element) ⋯ [*pelt*](#Program-element) `}` |
-#### Generic-parameter-list (**gparams**)
+#### Generic-parameter-list (*gparams*)
| | | |
@@ -131,7 +131,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *gparams* | ⟶ | `<` [*generic-param*](#Generic-parameter) `,` ⋯ `,` [*generic-param*](#Generic-parameter) `,`opt `>` |
-#### Generic-parameter (**generic-param**)
+#### Generic-parameter (*generic-param*)
| | | |
@@ -140,7 +140,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*tvar-name*](#identifier) |
-#### Import-declaration (**import-form**)
+#### Import-declaration (*import-form*)
| | | |
@@ -148,7 +148,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *import-form* | ⟶ | `import` [*import-selection*](#Import-selection)opt [*import-name*](#Import-name) [*gargs*](#Generic-argument-list)opt [*import-prefix*](#Import-prefix)opt `;` |
-#### Import-selection (**import-selection**)
+#### Import-selection (*import-selection*)
| | | |
@@ -156,7 +156,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *import-selection* | ⟶ | `{` [*import-element*](#Import-element) `,` ⋯ `,` [*import-element*](#Import-element) `,`opt `}` `from` |
-#### Import-element (**import-element**)
+#### Import-element (*import-element*)
| | | |
@@ -165,7 +165,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*id*](#identifier) `as` [*id*](#identifier) |
-#### Import-name (**import-name**)
+#### Import-name (*import-name*)
| | | |
@@ -174,7 +174,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*file*](#string-literal) |
-#### Import-prefix (**import-prefix**)
+#### Import-prefix (*import-prefix*)
| | | |
@@ -182,7 +182,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *import-prefix* | ⟶ | `prefix` [*id*](#identifier) |
-#### Generic-argument-list (**gargs**)
+#### Generic-argument-list (*gargs*)
| | | |
@@ -190,7 +190,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *gargs* | ⟶ | `<` [*garg*](#Generic-argument) `,` ⋯ `,` [*garg*](#Generic-argument) `,`opt `>` |
-#### Generic-argument (**garg**)
+#### Generic-argument (*garg*)
| | | |
@@ -199,7 +199,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*type*](#Type) |
-#### Export-declaration (**export-form**)
+#### Export-declaration (*export-form*)
| | | |
@@ -207,7 +207,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *export-form* | ⟶ | `export` `{` [*id*](#identifier) `,` ⋯ `,` [*id*](#identifier) `,`opt `}` `;`opt |
-#### Ledger-declaration (**ledger-declaration**)
+#### Ledger-declaration (*ledger-declaration*)
| | | |
@@ -215,7 +215,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *ledger-declaration* | ⟶ | `export`opt `sealed`opt `ledger` [*id*](#identifier) `:` [*type*](#Type) `;` |
-#### Witness-declaration (**witness-declaration**)
+#### Witness-declaration (*witness-declaration*)
| | | |
@@ -223,7 +223,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *witness-declaration* | ⟶ | `export`opt `witness` [*id*](#identifier) [*gparams*](#Generic-parameter-list)opt [*simple-parameter-list*](#Simple-parameter-list) `:` [*type*](#Type) `;` |
-#### Constructor (**constructor-definition**)
+#### Constructor (*constructor-definition*)
| | | |
@@ -231,7 +231,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *constructor-definition* | ⟶ | `constructor` [*pattern-parameter-list*](#Pattern-parameter-list) [*block*](#Block) |
-#### Circuit-definition (**circuit-definition**)
+#### Circuit-definition (*circuit-definition*)
| | | |
@@ -239,16 +239,16 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *circuit-definition* | ⟶ | `export`opt `pure`opt `circuit` [*function-name*](#identifier) [*gparams*](#Generic-parameter-list)opt [*pattern-parameter-list*](#Pattern-parameter-list) `:` [*type*](#Type) [*block*](#Block) |
-#### Structure-declaration (**struct-declaration**)
+#### Structure-declaration (*struct-declaration*)
-| | | |
-|----------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *struct-declaration* | ⟶ | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-identifier*](#Typed-identifier) `;` ⋯ `;` [*typed-identifier*](#Typed-identifier) `;`opt `}` `;`opt |
-| | \| | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-identifier*](#Typed-identifier) `,` ⋯ `,` [*typed-identifier*](#Typed-identifier) `,`opt `}` `;`opt |
+| | | |
+|----------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *struct-declaration* | ⟶ | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-id*](#Typed-identifier) `;` ⋯ `;` [*typed-id*](#Typed-identifier) `;`opt `}` `;`opt |
+| | \| | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-id*](#Typed-identifier) `,` ⋯ `,` [*typed-id*](#Typed-identifier) `,`opt `}` `;`opt |
-#### Enum-declaration (**enum-declaration**)
+#### Enum-declaration (*enum-declaration*)
| | | |
@@ -256,7 +256,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *enum-declaration* | ⟶ | `export`opt `enum` [*enum-name*](#identifier) `{` [*id*](#identifier) `,` ⋯¹ `,` [*id*](#identifier) `,`opt `}` `;`opt |
-#### External-contract-declaration (**contract-declaration**)
+#### External-contract-declaration (*contract-declaration*)
| | | |
@@ -265,7 +265,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#External-contract-circuit) `,` ⋯ `,` [*circuit-declaration*](#External-contract-circuit) `,`opt `}` `;`opt |
-#### External-contract-circuit (**circuit-declaration**)
+#### External-contract-circuit (*circuit-declaration*)
| | | |
@@ -273,7 +273,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *circuit-declaration* | ⟶ | `pure`opt `circuit` [*id*](#identifier) [*simple-parameter-list*](#Simple-parameter-list) `:` [*type*](#Type) |
-#### Type-declaration (**type-alias-declaration**)
+#### Type-declaration (*type-alias-declaration*)
| | | |
@@ -281,23 +281,23 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *type-alias-declaration* | ⟶ | `export`opt `new`opt `type` [*type-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `=` [*type*](#Type) `;` |
-#### Typed-identifier (**typed-identifier**)
+#### Typed-identifier (*typed-id*)
-| | | |
-|--------------------|---------|-----------------------------------------|
-| *typed-identifier* | ⟶ | [*id*](#identifier) `:` [*type*](#Type) |
+| | | |
+|------------|---------|-----------------------------------------|
+| *typed-id* | ⟶ | [*id*](#identifier) `:` [*type*](#Type) |
-#### Simple-parameter-list (**simple-parameter-list**)
+#### Simple-parameter-list (*simple-parameter-list*)
-| | | |
-|-------------------------|---------|---------------------------------------------------------------------------------------------------------------------|
-| *simple-parameter-list* | ⟶ | `(` [*typed-identifier*](#Typed-identifier) `,` ⋯ `,` [*typed-identifier*](#Typed-identifier) `,`opt `)` |
+| | | |
+|-------------------------|---------|-----------------------------------------------------------------------------------------------------|
+| *simple-parameter-list* | ⟶ | `(` [*typed-id*](#Typed-identifier) `,` ⋯ `,` [*typed-id*](#Typed-identifier) `,`opt `)` |
-#### Typed-pattern (**typed-pattern**)
+#### Typed-pattern (*typed-pattern*)
| | | |
@@ -305,7 +305,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *typed-pattern* | ⟶ | [*pattern*](#Pattern) `:` [*type*](#Type) |
-#### Pattern-parameter-list (**pattern-parameter-list**)
+#### Pattern-parameter-list (*pattern-parameter-list*)
| | | |
@@ -313,7 +313,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *pattern-parameter-list* | ⟶ | `(` [*typed-pattern*](#Typed-pattern) `,` ⋯ `,` [*typed-pattern*](#Typed-pattern) `,`opt `)` |
-#### Type (**type**)
+#### Type (*type*)
| | | |
@@ -329,7 +329,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | `[` [*type*](#Type) `,` ⋯ `,` [*type*](#Type) `,`opt `]` |
-#### Type-reference (**tref**)
+#### Type-reference (*tref*)
| | | |
@@ -337,7 +337,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *tref* | ⟶ | [*id*](#identifier) [*gargs*](#Generic-argument-list)opt |
-#### Type-size (**tsize**)
+#### Type-size (*tsize*)
| | | |
@@ -346,7 +346,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*id*](#identifier) |
-#### Block (**block**)
+#### Block (*block*)
| | | |
@@ -354,7 +354,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *block* | ⟶ | `{` [*stmt*](#Statement) ⋯ [*stmt*](#Statement) `}` |
-#### Statement (**stmt**)
+#### Statement (*stmt*)
| | | |
@@ -363,7 +363,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*stmt0*](#Statement0) |
-#### Statement0 (**stmt0**)
+#### Statement0 (*stmt0*)
| | | |
@@ -378,7 +378,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*block*](#Block) |
-#### Pattern (**pattern**)
+#### Pattern (*pattern*)
| | | |
@@ -388,7 +388,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | `{` [*pattern-struct-elt*](#Pattern-struct-element) `,` ⋯ `,` [*pattern-struct-elt*](#Pattern-struct-element) `,`opt `}` |
-#### Pattern-struct-element (**pattern-struct-elt**)
+#### Pattern-struct-element (*pattern-struct-elt*)
| | | |
@@ -397,7 +397,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*id*](#identifier) `:` [*pattern*](#Pattern) |
-#### Expression-sequence (**expr-seq**)
+#### Expression-sequence (*expr-seq*)
| | | |
@@ -406,7 +406,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr*](#Expression) `,` ⋯¹ `,` [*expr*](#Expression) `,` [*expr*](#Expression) |
-#### Expression (**expr**)
+#### Expression (*expr*)
| | | |
@@ -418,7 +418,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr0*](#Expression0) |
-#### Expression0 (**expr0**)
+#### Expression0 (*expr0*)
| | | |
@@ -427,7 +427,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr1*](#Expression1) |
-#### Expression1 (**expr1**)
+#### Expression1 (*expr1*)
| | | |
@@ -436,7 +436,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr2*](#Expression2) |
-#### Expression2 (**expr2**)
+#### Expression2 (*expr2*)
| | | |
@@ -446,7 +446,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr3*](#Expression3) |
-#### Expression3 (**expr3**)
+#### Expression3 (*expr3*)
| | | |
@@ -458,7 +458,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr4*](#Expression4) |
-#### Expression4 (**expr4**)
+#### Expression4 (*expr4*)
| | | |
@@ -467,7 +467,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr5*](#Expression5) |
-#### Expression5 (**expr5**)
+#### Expression5 (*expr5*)
| | | |
@@ -477,7 +477,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr6*](#Expression6) |
-#### Expression6 (**expr6**)
+#### Expression6 (*expr6*)
| | | |
@@ -486,7 +486,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr7*](#Expression7) |
-#### Expression7 (**expr7**)
+#### Expression7 (*expr7*)
| | | |
@@ -495,7 +495,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr8*](#Expression8) |
-#### Expression8 (**expr8**)
+#### Expression8 (*expr8*)
| | | |
@@ -506,7 +506,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*expr9*](#Expression9) |
-#### Expression9 (**expr9**)
+#### Expression9 (*expr9*)
| | | |
@@ -523,7 +523,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*term*](#Term) |
-#### Term (**term**)
+#### Term (*term*)
| | | |
@@ -538,7 +538,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | `(` [*expr-seq*](#Expression-sequence) `)` |
-#### Tuple-argument (**tuple-arg**, **bytes-arg**)
+#### Tuple-argument (*tuple-arg*, *bytes-arg*)
| | | |
@@ -548,7 +548,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *bytes-arg* | ⟶ | *tuple-arg* |
-#### Structure-argument (**struct-arg**)
+#### Structure-argument (*struct-arg*)
| | | |
@@ -558,7 +558,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | `...` [*expr*](#Expression) |
-#### Function (**fun**)
+#### Function (*fun*)
| | | |
@@ -569,7 +569,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | `(` [*fun*](#Function) `)` |
-#### Return-type (**return-type**)
+#### Return-type (*return-type*)
| | | |
@@ -577,7 +577,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *return-type* | ⟶ | `:` [*type*](#Type) |
-#### Optionally-typed-pattern (**optionally-typed-pattern**)
+#### Optionally-typed-pattern (*optionally-typed-pattern*)
| | | |
@@ -586,7 +586,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*typed-pattern*](#Typed-pattern) |
-#### Const-Binding (**cbinding**)
+#### Const-Binding (*cbinding*)
| | | |
@@ -594,7 +594,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *cbinding* | ⟶ | [*optionally-typed-pattern*](#Optionally-typed-pattern) `=` [*expr*](#Expression) |
-#### Arrow-parameter-list (**arrow-parameter-list**)
+#### Arrow-parameter-list (*arrow-parameter-list*)
| | | |
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index b7173359..305cdf21 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -315,8 +315,14 @@ Each parameter is either a type name (e.g., `T`) or a hash-prefixed natural-numb
Generic natural-number parameters are prefixed by `#` to distingish them from
generic type parameters.
-
| gparams | → | \< generic-param , ⋯ , generic-param ,opt > |
-| generic-param | → | # tvar-name |
| | | | tvar-name |
+
+| | | |
+|-----------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------|
+| *gparams* | ⟶ | `<` [*generic-param*](#generic-parameters-and-arguments) `,` ⋯ `,` [*generic-param*](#generic-parameters-and-arguments) `,`opt `>` |
+| *generic-param* | ⟶ | `#` [*tvar-name*](#terminal-names) |
+| | \| | [*tvar-name*](#terminal-names) |
+
+
Generic entities must be *specialized* at the point of use to produce non-generic
entities at compile time by supplying them with *generic arguments*.
@@ -325,8 +331,14 @@ Generic arguments are also enclosed in angle brackets.
Each generic argument must be a type, a natural number literal, or the type or
numeric value of a generic parameter.
-
| gargs | → | \< garg , ⋯ , garg ,opt > |
-| garg | → | nat |
| | | | type |
+
+| | | |
+|---------|---------|-----------------------------------------------------------------------------------------------------------------------------|
+| *gargs* | ⟶ | `<` [*garg*](#generic-parameters-and-arguments) `,` ⋯ `,` [*garg*](#generic-parameters-and-arguments) `,`opt `>` |
+| *garg* | ⟶ | [*nat*](#terminal-names) |
+| | \| | [*type*](#primitive-types) |
+
+
The syntax of types allows for type references, including references to generic
parameters, so any generic argument can pass along the value of a generic type
@@ -398,9 +410,23 @@ As with any other generic entity, it must be specialized at the point of use.
The following are the primitive types of Compact:
-
| type | → | tref |
| | | | Boolean |
| | | | Field |
| | | | Uint \< tsize > |
| | | | Uint \< tsize .. tsize > |
| | | | Bytes \< tsize > |
| | | | Opaque \< str > |
| | | | Vector \< tsize , type > |
| | | | [ type , ⋯ , type ,opt ] |
-| tref | → | id gargsopt |
-| tsize | → | nat |
| | | | id |
+
+| | | |
+|---------|---------|-------------------------------------------------------------------------------------------|
+| *type* | ⟶ | [*tref*](#primitive-types) |
+| | \| | `Boolean` |
+| | \| | `Field` |
+| | \| | `Uint` `<` [*tsize*](#primitive-types) `>` |
+| | \| | `Uint` `<` [*tsize*](#primitive-types) `..` [*tsize*](#primitive-types) `>` |
+| | \| | `Bytes` `<` [*tsize*](#primitive-types) `>` |
+| | \| | `Opaque` `<` [*str*](#terminal-names) `>` |
+| | \| | `Vector` `<` [*tsize*](#primitive-types) `,` [*type*](#primitive-types) `>` |
+| | \| | `[` [*type*](#primitive-types) `,` ⋯ `,` [*type*](#primitive-types) `,`opt `]` |
+| *tref* | ⟶ | [*id*](#terminal-names) [*gargs*](#generic-parameters-and-arguments)opt |
+| *tsize* | ⟶ | [*nat*](#terminal-names) |
+| | \| | [*id*](#terminal-names) |
+
+
- `Boolean` is the type of *Boolean* values. There are only two values of
`Boolean` type. They are the values of the expressions `true` and `false`.
@@ -477,8 +503,14 @@ They can also define structural and nominal aliases for existing types.
Structure types are defined via `struct` declarations with the following form:
-
| struct-declaration | → | exportopt struct struct-name gparamsopt \{ typed-identifier ; ⋯ ; typed-identifier ;opt } ;opt |
| | | | exportopt struct struct-name gparamsopt \{ typed-identifier , ⋯ , typed-identifier ,opt } ;opt |
-| typed-identifier | → | id : type |
+
+| | | |
+|----------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *struct-declaration* | ⟶ | `export`opt `struct` [*struct-name*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt `{` [*typed-id*](#structure-types) `;` ⋯ `;` [*typed-id*](#structure-types) `;`opt `}` `;`opt |
+| | \| | `export`opt `struct` [*struct-name*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt `{` [*typed-id*](#structure-types) `,` ⋯ `,` [*typed-id*](#structure-types) `,`opt `}` `;`opt |
+| *typed-id* | ⟶ | [*id*](#terminal-names) `:` [*type*](#primitive-types) |
+
+
A structure declaration has a sequence of named fields which must be separated
either by commas or by semicolons. Comma and semicolon separators cannot be
@@ -586,7 +618,12 @@ and accessed via
Enumeration types are defined via `enum` declarations with the following form:
-
| enum-declaration | → | exportopt enum enum-name \{ id , ⋯¹ , id ,opt } ;opt |
+
+| | | |
+|--------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *enum-declaration* | ⟶ | `export`opt `enum` [*enum-name*](#terminal-names) `{` [*id*](#terminal-names) `,` ⋯¹ `,` [*id*](#terminal-names) `,`opt `}` `;`opt |
+
+
An enumeration declaration has a non-empty sequence of named elements separated by commas.
A trailing comma is allowed but not required.
@@ -614,7 +651,12 @@ contracts is reserved for this use.
Type aliases can be created via `type` declarations of the form:
-
+
+| | | |
+|--------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *type-alias-declaration* | ⟶ | `export`opt `new`opt `type` [*type-name*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt `=` [*type*](#primitive-types) `;` |
+
+
Within the scope of a type-alias declaration of *type-name* for *type*, *type-name*
is itself a type.
@@ -729,8 +771,16 @@ tuple is expected.
The parameters of a circuit or constructor and the target of a `const` binding
are specified via patterns:
-
| pattern | → | id |
| | | | [ patternopt , ⋯ , patternopt ,opt ] |
| | | | \{ pattern-struct-elt , ⋯ , pattern-struct-elt ,opt } |
-| pattern-struct-elt | → | id |
| | | | id : pattern |
+
+| | | |
+|----------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------|
+| *pattern* | ⟶ | [*id*](#terminal-names) |
+| | \| | `[` [*pattern*](#patterns-and-destructuring)opt `,` ⋯ `,` [*pattern*](#patterns-and-destructuring)opt `,`opt `]` |
+| | \| | `{` [*pattern-struct-elt*](#patterns-and-destructuring) `,` ⋯ `,` [*pattern-struct-elt*](#patterns-and-destructuring) `,`opt `}` |
+| *pattern-struct-elt* | ⟶ | [*id*](#terminal-names) |
+| | \| | [*id*](#terminal-names) `:` [*pattern*](#patterns-and-destructuring) |
+
+
In its simplest form, a pattern is just an identifier.
For example, in the code below, the parameter of `sumTuple` is the identifier
@@ -871,22 +921,25 @@ circuit sumSomeYs([{y: b1,}, , {y: b3,},]: [S, S, S]): Field {
A compact program is a sequence of zero or more program elements.
-
+
+| | | |
+|-----------|---------|----------------------------------------------------------------------------|
+| *program* | ⟶ | [*pelt*](#programs) ⋯ [*pelt*](#programs) [*eof*](#dummy) |
+| *pelt* | ⟶ | [*pragma-form*](#pragmas) |
+| | \| | [*module-definition*](#modules-exports-and-imports) |
+| | \| | [*import-form*](#imports) |
+| | \| | [*export-form*](#exports) |
+| | \| | [*include-form*](#include-files) |
+| | \| | [*struct-declaration*](#structure-types) |
+| | \| | [*enum-declaration*](#enumeration-types) |
+| | \| | [*contract-declaration*](#dummy) |
+| | \| | [*type-alias-declaration*](#type-aliases) |
+| | \| | [*ledger-declaration*](#declaring-and-maintaining-public-state) |
+| | \| | [*witness-declaration*](#declaring-witnesses-for-private-state-management) |
+| | \| | [*constructor-definition*](#contract-constructor) |
+| | \| | [*circuit-definition*](#circuit-definitions) |
+
+
Briefly:
@@ -920,11 +973,25 @@ section.
A pragma takes the following form and declares a constraint on either the compiler
version (*id* = `compiler_version`) or the language version (*id* = `language_version`)
-
| pragma-form | → | pragma id version-expr ; |
-| version-expr | → | version-expr || version-expr0 |
| | | | version-expr0 |
-| version-expr0 | → | version-expr0 && version-term |
| | | | version-term |
-| version-term | → | version-atom |
| | | | ! version-atom |
| | | | \< version-atom |
| | | | \<= version-atom |
| | | | >= version-atom |
| | | | > version-atom |
| | | | ( version-expr ) |
-| version-atom | → | nat |
| | | | version |
+
+| | | |
+|----------------------------|---------|--------------------------------------------------------------------------|
+| *pragma-form* | ⟶ | `pragma` [*id*](#terminal-names) [*version-expr*](#pragmas) `;` |
+| *version-expr* | ⟶ | [*version-expr*](#pragmas) `\|\|` [*version-expr0*](#pragmas) |
+| | \| | [*version-expr0*](#pragmas) |
+| *version-expr0* | ⟶ | [*version-expr0*](#pragmas) `&&` [*version-term*](#pragmas) |
+| | \| | [*version-term*](#pragmas) |
+| *version-term* | ⟶ | [*version-atom*](#pragmas) |
+| | \| | `!` [*version-atom*](#pragmas) |
+| | \| | `<` [*version-atom*](#pragmas) |
+| | \| | `<=` [*version-atom*](#pragmas) |
+| | \| | `>=` [*version-atom*](#pragmas) |
+| | \| | `>` [*version-atom*](#pragmas) |
+| | \| | `(` [*version-expr*](#pragmas) `)` |
+| *version-atom* | ⟶ | [*nat*](#terminal-names) |
+| | \| | [*version*](#terminal-names) |
+
+
*version* is a dot-separated pair or trio of natural numbers, so along
with *nat* this allows *version* to be either a single natural number,
@@ -948,7 +1015,12 @@ programs into multiple files.
A module is a named collection of program elements created via a module definition,
which takes the following form:
-
+
+| | | |
+|---------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt `{` [*pelt*](#programs) ⋯ [*pelt*](#programs) `}` |
+
+
A module definition makes a binding from `module-name` to the module visible in
the program or module containing the module definition.
@@ -968,7 +1040,12 @@ Any identifier defined at or imported into the top level of a module can be expo
from the module in one of two ways: (1) by prefixing the definition with the
`export` keyword, or by listing the identifier in a separate `export` declaration:
-
| export-form | → | export \{ id , ⋯ , id ,opt } ;opt |
+
+| | | |
+|---------------|---------|----------------------------------------------------------------------------------------------------------------|
+| *export-form* | ⟶ | `export` `{` [*id*](#terminal-names) `,` ⋯ `,` [*id*](#terminal-names) `,`opt `}` `;`opt |
+
+
For example, the following module exports `G` and `S` but not `F`.
@@ -992,11 +1069,18 @@ Exporting a binding from a module has no effect unless the module is imported.
A module can be imported into another module or into the program top level, making
some or all of its exported bindings visible there, potentially with a prefix.
-
| import-form | → | import import-selectionopt import-name gargsopt import-prefixopt ; |
-| import-selection | → | \{ import-element , ⋯ , import-element ,opt } from |
-| import-element | → | id |
| | | | id as id |
-| import-name | → | id |
| | | | file |
-| import-prefix | → | prefix id |
+
+| | | |
+|--------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *import-form* | ⟶ | `import` [*import-selection*](#imports)opt [*import-name*](#imports) [*gargs*](#generic-parameters-and-arguments)opt [*import-prefix*](#imports)opt `;` |
+| *import-selection* | ⟶ | `{` [*import-element*](#imports) `,` ⋯ `,` [*import-element*](#imports) `,`opt `}` `from` |
+| *import-element* | ⟶ | [*id*](#terminal-names) |
+| | \| | [*id*](#terminal-names) `as` [*id*](#terminal-names) |
+| *import-name* | ⟶ | [*id*](#terminal-names) |
+| | \| | [*file*](#terminal-names) |
+| *import-prefix* | ⟶ | `prefix` [*id*](#terminal-names) |
+
+
For example:
@@ -1184,7 +1268,12 @@ Compact allows programs and modules to be split into multiple files and spliced
togther via `include` forms, which have the following syntax, where `file` is a
string literal specifying a filesystem pathname for file to be included:
-
| include-form | → | include file ; |
+
+| | | |
+|----------------|---------|-----------------------------------------|
+| *include-form* | ⟶ | `include` [*file*](#terminal-names) `;` |
+
+
`file` can be an absolute pathname, one that is relative to the directory
of the including file, or one that is relative to one of the directories in the
@@ -1216,11 +1305,14 @@ Witnesses must be declared to make them visible to the circuits of a contract.
A witness declaration does not include a body, because the implementation is
provided by the TypeScript driver.
-
-| witness-declaration | → | exportopt witness id gparamsopt simple-parameter-list : type ; |
-| simple-parameter-list | → | ( typed-identifier , ⋯ , typed-identifier ,opt ) |
-| typed-identifier | → | id : type |
-
+
+| | | |
+|-------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *witness-declaration* | ⟶ | `export`opt `witness` [*id*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt [*simple-parameter-list*](#declaring-witnesses-for-private-state-management) `:` [*type*](#primitive-types) `;` |
+| *simple-parameter-list* | ⟶ | `(` [*typed-id*](#structure-types) `,` ⋯ `,` [*typed-id*](#structure-types) `,`opt `)` |
+| *typed-id* | ⟶ | [*id*](#terminal-names) `:` [*type*](#primitive-types) |
+
+
Witness declarations can appear anywhere among the program elements of
a module or the contract's top level.
@@ -1253,7 +1345,12 @@ Multiple ledger declarations can appear in a program, or none.
They can appear anywhere among the program elements of a module or the contract's
top level.
-
| ledger-declaration | → | exportopt sealedopt ledger id : type ; |
+
+| | | |
+|----------------------|---------|-------------------------------------------------------------------------------------------------------------------|
+| *ledger-declaration* | ⟶ | `export`opt `sealed`opt `ledger` [*id*](#terminal-names) `:` [*type*](#primitive-types) `;` |
+
+
A ledger declaration binds a ledger field name to one of a
set of predefined [ledger-state types](#ledger-state-types).
@@ -1470,8 +1567,14 @@ reachable from an exported circuit.
A contract can be initialized via a contract constructor defined at the
program's top level.
-
| constructor-definition | → | constructor pattern-parameter-list block |
| pattern-parameter-list | → | ( typed-pattern , ⋯ , typed-pattern ,opt ) |
-| typed-pattern | → | pattern : type |
+
+| | | |
+|--------------------------|---------|-----------------------------------------------------------------------------------------------------------------------|
+| *constructor-definition* | ⟶ | `constructor` [*pattern-parameter-list*](#contract-constructor) [*block*](#blocks) |
+| *pattern-parameter-list* | ⟶ | `(` [*typed-pattern*](#contract-constructor) `,` ⋯ `,` [*typed-pattern*](#contract-constructor) `,`opt `)` |
+| *typed-pattern* | ⟶ | [*pattern*](#patterns-and-destructuring) `:` [*type*](#primitive-types) |
+
+
The constructor, if any, is typically used to initialize public state
and can also be used to initialize private state through witness
@@ -1524,9 +1627,14 @@ in [Circuit and witness calls](#circuit-and-witness-calls).
Named circuit definitions have the following syntax:
-
| circuit-definition | → | exportopt pureopt circuit function-name gparamsopt pattern-parameter-list : type block |
-| pattern-parameter-list | → | ( typed-pattern , ⋯ , typed-pattern ,opt ) |
-| typed-pattern | → | pattern : type |
+
+| | | |
+|--------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *circuit-definition* | ⟶ | `export`opt `pure`opt `circuit` [*function-name*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt [*pattern-parameter-list*](#contract-constructor) `:` [*type*](#primitive-types) [*block*](#blocks) |
+| *pattern-parameter-list* | ⟶ | `(` [*typed-pattern*](#contract-constructor) `,` ⋯ `,` [*typed-pattern*](#contract-constructor) `,`opt `)` |
+| *typed-pattern* | ⟶ | [*pattern*](#patterns-and-destructuring) `:` [*type*](#primitive-types) |
+
+
A circuit definition binds `function-name` to a circuit with the given parameters,
type, and body.
@@ -1602,7 +1710,12 @@ Compact program by the Compact compiler.
A `block` is a group of statements enclosed in braces:
-
+
+| | | |
+|---------|---------|-------------------------------------------------------|
+| *block* | ⟶ | `{` [*stmt*](#statements) ⋯ [*stmt*](#statements) `}` |
+
+
A block can be used in place of a single statement anywhere a single statement
is allowed, which is useful for allowing multiple statements to be evaluated by the
@@ -1625,8 +1738,21 @@ A block is evaluated by evaluating the statements in sequence.
The syntax of Compact statements is summarized by the following grammar snippet:
-
+
+| | | |
+|--------------------|---------|---------------------------------------------------------------------------------------------------------------------------------|
+| *stmt* | ⟶ | `if` `(` [*expr-seq*](#expressions) `)` [*stmt*](#statements) |
+| | \| | [*stmt0*](#statements) |
+| *stmt0* | ⟶ | [*expr-seq*](#expressions) `;` |
+| | \| | `const` [*cbinding*](#const-statements) `,` ⋯¹ `,` [*cbinding*](#const-statements) `;` |
+| | \| | `if` `(` [*expr-seq*](#expressions) `)` [*stmt0*](#statements) `else` [*stmt*](#statements) |
+| | \| | `for` `(` `const` [*id*](#terminal-names) `of` [*nat*](#terminal-names) `..` [*nat*](#terminal-names) `)` [*stmt*](#statements) |
+| | \| | `for` `(` `const` [*id*](#terminal-names) `of` [*expr-seq*](#expressions) `)` [*stmt*](#statements) |
+| | \| | `return` [*expr-seq*](#expressions) `;` |
+| | \| | `return` `;` |
+| | \| | [*block*](#blocks) |
+
+
The snippet shows that a statement (`stmt`) is either a one-armed `if` expression
or some other kinf of statement (`stmt0`).
@@ -1666,13 +1792,16 @@ const cbindings
where `cbindings` is a comma-separated sequence of one or more `cbinding` subforms
in the syntax specified by the following grammar snippet:
-
-| cbinding | → | optionally-typed-pattern = expr |
-| optionally-typed-pattern | → | pattern |
| | | | typed-pattern |
-| pattern | → | id |
| | | | [ patternopt , ⋯ , patternopt ,opt ] |
| | | | \{ pattern-struct-elt , ⋯ , pattern-struct-elt ,opt } |
-| pattern-struct-elt | → | id |
| | | | id : pattern |
-| typed-pattern | → | pattern : type |
-
+
+| | | |
+|----------------------------|---------|----------------------------------------------------------------------------|
+| *cbinding* | ⟶ | [*optionally-typed-pattern*](#const-statements) `=` [*expr*](#expressions) |
+| *optionally-typed-pattern* | ⟶ | [*pattern*](#patterns-and-destructuring) |
+| | \| | [*typed-pattern*](#contract-constructor) |
+| *pattern-struct-elt* | ⟶ | [*id*](#terminal-names) |
+| | \| | [*id*](#terminal-names) `:` [*pattern*](#patterns-and-destructuring) |
+
+
A `const` statement is typed by typing each of its `cbinding` subforms.
A `cbinding` subform is typed by typing the expression on the right-hand side
@@ -1873,21 +2002,67 @@ subsequent statements, and it returns to the caller the value of `expr-seq` or
The syntax of Compact expressions is summarized by the following grammar snippet:
-
| expr-seq | → | expr |
| | | | expr , ⋯¹ , expr , expr |
-| expr | → | expr0 ? expr : expr |
| | | | expr0 = expr |
| | | | expr0 += expr |
| | | | expr0 -= expr |
| | | | expr0 |
-| expr0 | → | expr0 || expr1 |
| | | | expr1 |
-| expr1 | → | expr1 && expr2 |
| | | | expr2 |
-| expr2 | → | expr2 == expr3 |
| | | | expr2 != expr3 |
| | | | expr3 |
-| expr3 | → | expr4 \< expr4 |
| | | | expr4 \<= expr4 |
| | | | expr4 >= expr4 |
| | | | expr4 > expr4 |
| | | | expr4 |
-| expr4 | → | expr4 as type |
| | | | expr5 |
-| expr5 | → | expr5 + expr6 |
| | | | expr5 - expr6 |
| | | | expr6 |
-| expr6 | → | expr6 * expr7 |
| | | | expr7 |
-| expr7 | → | ! expr7 |
| | | | expr8 |
-| expr8 | → | expr8 [ expr ] |
| | | | expr8 . id |
| | | | expr8 . id ( expr , ⋯ , expr ,opt ) |
| | | | expr9 |
-| expr9 | → | fun ( expr , ⋯ , expr ,opt ) |
| | | | map ( fun , expr , ⋯¹ , expr ,opt ) |
| | | | fold ( fun , expr , expr , ⋯¹ , expr ,opt ) |
| | | | slice \< tsize > ( expr , expr ) |
| | | | [ tuple-arg , ⋯ , tuple-arg ,opt ] |
| | | | Bytes [ bytes-arg , ⋯ , bytes-arg ,opt ] |
| | | | tref \{ struct-arg , ⋯ , struct-arg ,opt } |
| | | | assert ( expr , str ) |
| | | | disclose ( expr ) |
| | | | term |
-| tuple-arg | → | expr |
| | | | ... expr |
| bytes-arg | → | tuple-arg |
-| struct-arg | → | expr |
| | | | id : expr |
| | | | ... expr |
-| term | → | id |
| | | | true |
| | | | false |
| | | | nat |
| | | | str |
| | | | pad ( nat , str ) |
| | | | default \< type > |
| | | | ( expr-seq ) |
+
+| | | |
+|--------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *expr-seq* | ⟶ | [*expr*](#expressions) |
+| | \| | [*expr*](#expressions) `,` ⋯¹ `,` [*expr*](#expressions) `,` [*expr*](#expressions) |
+| *expr* | ⟶ | [*expr0*](#expressions) `?` [*expr*](#expressions) `:` [*expr*](#expressions) |
+| | \| | [*expr0*](#expressions) `=` [*expr*](#expressions) |
+| | \| | [*expr0*](#expressions) `+=` [*expr*](#expressions) |
+| | \| | [*expr0*](#expressions) `-=` [*expr*](#expressions) |
+| | \| | [*expr0*](#expressions) |
+| *expr0* | ⟶ | [*expr0*](#expressions) `\|\|` [*expr1*](#expressions) |
+| | \| | [*expr1*](#expressions) |
+| *expr1* | ⟶ | [*expr1*](#expressions) `&&` [*expr2*](#expressions) |
+| | \| | [*expr2*](#expressions) |
+| *expr2* | ⟶ | [*expr2*](#expressions) `==` [*expr3*](#expressions) |
+| | \| | [*expr2*](#expressions) `!=` [*expr3*](#expressions) |
+| | \| | [*expr3*](#expressions) |
+| *expr3* | ⟶ | [*expr4*](#expressions) `<` [*expr4*](#expressions) |
+| | \| | [*expr4*](#expressions) `<=` [*expr4*](#expressions) |
+| | \| | [*expr4*](#expressions) `>=` [*expr4*](#expressions) |
+| | \| | [*expr4*](#expressions) `>` [*expr4*](#expressions) |
+| | \| | [*expr4*](#expressions) |
+| *expr4* | ⟶ | [*expr4*](#expressions) `as` [*type*](#primitive-types) |
+| | \| | [*expr5*](#expressions) |
+| *expr5* | ⟶ | [*expr5*](#expressions) `+` [*expr6*](#expressions) |
+| | \| | [*expr5*](#expressions) `-` [*expr6*](#expressions) |
+| | \| | [*expr6*](#expressions) |
+| *expr6* | ⟶ | [*expr6*](#expressions) `*` [*expr7*](#expressions) |
+| | \| | [*expr7*](#expressions) |
+| *expr7* | ⟶ | `!` [*expr7*](#expressions) |
+| | \| | [*expr8*](#expressions) |
+| *expr8* | ⟶ | [*expr8*](#expressions) `[` [*expr*](#expressions) `]` |
+| | \| | [*expr8*](#expressions) `.` [*id*](#terminal-names) |
+| | \| | [*expr8*](#expressions) `.` [*id*](#terminal-names) `(` [*expr*](#expressions) `,` ⋯ `,` [*expr*](#expressions) `,`opt `)` |
+| | \| | [*expr9*](#expressions) |
+| *expr9* | ⟶ | [*fun*](#circuit-and-witness-calls) `(` [*expr*](#expressions) `,` ⋯ `,` [*expr*](#expressions) `,`opt `)` |
+| | \| | `map` `(` [*fun*](#circuit-and-witness-calls) `,` [*expr*](#expressions) `,` ⋯¹ `,` [*expr*](#expressions) `,`opt `)` |
+| | \| | `fold` `(` [*fun*](#circuit-and-witness-calls) `,` [*expr*](#expressions) `,` [*expr*](#expressions) `,` ⋯¹ `,` [*expr*](#expressions) `,`opt `)` |
+| | \| | `slice` `<` [*tsize*](#primitive-types) `>` `(` [*expr*](#expressions) `,` [*expr*](#expressions) `)` |
+| | \| | `[` [*tuple-arg*](#expressions) `,` ⋯ `,` [*tuple-arg*](#expressions) `,`opt `]` |
+| | \| | `Bytes` `[` [*tuple-arg*](#expressions) `,` ⋯ `,` [*tuple-arg*](#expressions) `,`opt `]` |
+| | \| | [*tref*](#primitive-types) `{` [*struct-arg*](#expressions) `,` ⋯ `,` [*struct-arg*](#expressions) `,`opt `}` |
+| | \| | `assert` `(` [*expr*](#expressions) `,` [*str*](#terminal-names) `)` |
+| | \| | `disclose` `(` [*expr*](#expressions) `)` |
+| | \| | [*term*](#expressions) |
+| *tuple-arg* | ⟶ | [*expr*](#expressions) |
+| | \| | `...` [*expr*](#expressions) |
+| *bytes-arg* | ⟶ | [*tuple-arg*](#expressions) |
+| *struct-arg* | ⟶ | [*expr*](#expressions) |
+| | \| | [*id*](#terminal-names) `:` [*expr*](#expressions) |
+| | \| | `...` [*expr*](#expressions) |
+| *term* | ⟶ | [*id*](#terminal-names) |
+| | \| | `true` |
+| | \| | `false` |
+| | \| | [*nat*](#terminal-names) |
+| | \| | [*str*](#terminal-names) |
+| | \| | `pad` `(` [*nat*](#terminal-names) `,` [*str*](#terminal-names) `)` |
+| | \| | `default` `<` [*type*](#primitive-types) `>` |
+| | \| | `(` [*expr-seq*](#expressions) `)` |
+
+
Every Compact expression must be well-typed (free from static type errors).
If any expression within a program contains a static type error, it is a static
@@ -2571,13 +2746,24 @@ type of `e` is an enumeration type.
### Circuit and witness calls
-
| fun | → | id gargsopt |
| | | | arrow-parameter-list return-typeopt => block |
| | | | arrow-parameter-list return-typeopt => expr |
| | | | ( fun ) |
-| arrow-parameter-list | → | ( optionally-typed-pattern , ⋯ , optionally-typed-pattern ,opt ) |
-| optionally-typed-pattern | → | pattern |
| | | | typed-pattern |
-| pattern | → | id |
| | | | [ patternopt , ⋯ , patternopt ,opt ] |
| | | | \{ pattern-struct-elt , ⋯ , pattern-struct-elt ,opt } |
-| pattern-struct-elt | → | id |
| | | | id : pattern |
-| typed-pattern | → | pattern : type |
-| return-type | → | : type |
+
+| | | |
+|----------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------|
+| *fun* | ⟶ | [*id*](#terminal-names) [*gargs*](#generic-parameters-and-arguments)opt |
+| | \| | [*arrow-parameter-list*](#circuit-and-witness-calls) [*return-type*](#circuit-and-witness-calls)opt `=>` [*block*](#blocks) |
+| | \| | [*arrow-parameter-list*](#circuit-and-witness-calls) [*return-type*](#circuit-and-witness-calls)opt `=>` [*expr*](#expressions) |
+| | \| | `(` [*fun*](#circuit-and-witness-calls) `)` |
+| *arrow-parameter-list* | ⟶ | `(` [*optionally-typed-pattern*](#const-statements) `,` ⋯ `,` [*optionally-typed-pattern*](#const-statements) `,`opt `)` |
+| *optionally-typed-pattern* | ⟶ | [*pattern*](#patterns-and-destructuring) |
+| | \| | [*typed-pattern*](#contract-constructor) |
+| *pattern* | ⟶ | [*id*](#terminal-names) |
+| | \| | `[` [*pattern*](#patterns-and-destructuring)opt `,` ⋯ `,` [*pattern*](#patterns-and-destructuring)opt `,`opt `]` |
+| | \| | `{` [*pattern-struct-elt*](#patterns-and-destructuring) `,` ⋯ `,` [*pattern-struct-elt*](#patterns-and-destructuring) `,`opt `}` |
+| *pattern-struct-elt* | ⟶ | [*id*](#terminal-names) |
+| | \| | [*id*](#terminal-names) `:` [*pattern*](#patterns-and-destructuring) |
+| *return-type* | ⟶ | `:` [*type*](#primitive-types) |
+
+
Circuits and witnesses, collectively referred to as functions, are called via an
expression of the form `f(e, ...)`, where `f` is a function and `e, ...` is a
@@ -2756,6 +2942,11 @@ input vectors.
Values of one type can be cast to another, when allowed, via a *cast*, which
takes the following form:
+```compact
+e as T
+```
+
+where `e` is an expression and `T` is a type.
The effects of casting an expression `e` of type `T` to another type `U` depend
on the specific types involved.
For some types `T` and `U`, the cast is not allowed, which is a static error.
@@ -2786,6 +2977,21 @@ Any cast not covered by one of the rules is not allowed.
(but never required), never result in run-time errors, and, except in the case
where the type and the supertype are the same, might require run-time conversions.
+This rule has three implications:
+
+- Tuple-to-vector upcasts: if a tuple type `[T, ...]` has a vector type `Vector
`
+ (i.e., `S` is the least upper bound of the element types), then the tuple is a subtype
+ of that vector type and can be used where the vector type is expected without an
+ explicit cast. For example, values of type `[Uint<8>, Uint<16>]` can be used where a
+ value of type `Vector<2, Uint<16>>` are required.
+- Vector-to-tuple upcasts: a vector type `Vector` is a subtype of any tuple type
+ `[S, ...]` of length `n` where `T` is a subtype of each `S`, so a vector can be used where
+ such a tuple is expected without an explicit cast. For example, values of type
+ `Vector<2, Uint<8>>` can be used where values of type `[Uint<16>, Uint<16>]` are required.
+- Since `Vector` is the same type as the tuple `[T, ..., T]` with `n` occurrences of `T`,
+ casts between a vector type and its equivalent tuple type are always upcasts in both
+ directions.
+
#### Downcasts of `Field` and `Uint` types
- `Uint` downcasts, i.e., casts from `Uint` to `Uint`, `m > n`, are always
From 980a2d380286e544c4321387ddbd000a021d5a7c Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Thu, 12 Mar 2026 22:20:54 +0100
Subject: [PATCH 17/41] latest lang-ref.mdx and compact-grammar.mdx
---
docs/compact/reference/compact-grammar.mdx | 48 ++++++++++------------
docs/compact/reference/lang-ref.mdx | 38 ++++++++---------
2 files changed, 41 insertions(+), 45 deletions(-)
diff --git a/docs/compact/reference/compact-grammar.mdx b/docs/compact/reference/compact-grammar.mdx
index 088806f3..495cff5e 100644
--- a/docs/compact/reference/compact-grammar.mdx
+++ b/docs/compact/reference/compact-grammar.mdx
@@ -10,10 +10,6 @@ Compact language version 0.22.0.
Notational note: In the grammar below, keywords and punctuation are in `monospaced` font. Terminal and nonterminal names are in *emphasized* font. Alternation is indicated by a vertical bar (`|`). Optional items are indicated by the superscript opt. Repetition is specified by ellipses. The notation *X* ⋯ *X*, where *X* is a grammar symbol, represents zero or more occurrences of *X*. The notation *X* `,` ⋯ `,` *X*, where *X* is a grammar symbol and `,` is a literal comma, represents zero or more occurrences of *X* separated by commas. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one *X*. When such a sequence is followed by *,*opt, an optional trailing comma is allowed, but only if there is at least one *X*. For example, *id* ⋯ *id* represents zero or more *id*s, and *expr* `,` ⋯¹`,` *expr* `,`opt represents one or more comma-separated *expr*s possibly followed by an extra comma. The rules involving commas apply equally to semicolons, i.e., apply when `,` is replaced by `;`.
-#### end-of-file (*eof*)
-
-End of file.
-
#### identifier (*id*, *module-name*, *function-name*, *struct-name*, *enum-name*, *contract-name*, *tvar-name*, *type-name*)
Identifiers have the same syntax as Typescript identifiers.
@@ -33,29 +29,29 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Compact (*program*)
-| | | |
-|-----------|---------|-------------------------------------------------------------------------------|
-| *program* | ⟶ | [*pelt*](#Program-element) ⋯ [*pelt*](#Program-element) [*eof*](#end-of-file) |
+| | | |
+|-----------|---------|--------------------------------------------------------------------------------|
+| *program* | ⟶ | [*program-element*](#Program-element) ⋯ [*program-element*](#Program-element) |
-#### Program-element (*pelt*)
+#### Program-element (*program-element*)
-| | | |
-|--------|---------|----------------------------------------------------------|
-| *pelt* | ⟶ | [*pragma-form*](#Pragma) |
-| | \| | [*module-definition*](#Module-definition) |
-| | \| | [*import-form*](#Import-declaration) |
-| | \| | [*export-form*](#Export-declaration) |
-| | \| | [*include-form*](#Include) |
-| | \| | [*struct-declaration*](#Structure-declaration) |
-| | \| | [*enum-declaration*](#Enum-declaration) |
-| | \| | [*contract-declaration*](#External-contract-declaration) |
-| | \| | [*type-alias-declaration*](#Type-declaration) |
-| | \| | [*ledger-declaration*](#Ledger-declaration) |
-| | \| | [*witness-declaration*](#Witness-declaration) |
-| | \| | [*constructor-definition*](#Constructor) |
-| | \| | [*circuit-definition*](#Circuit-definition) |
+| | | |
+|-------------------|---------|----------------------------------------------------------|
+| *program-element* | ⟶ | [*pragma-form*](#Pragma) |
+| | \| | [*module-definition*](#Module-definition) |
+| | \| | [*import-form*](#Import-declaration) |
+| | \| | [*export-form*](#Export-declaration) |
+| | \| | [*include-form*](#Include) |
+| | \| | [*struct-declaration*](#Structure-declaration) |
+| | \| | [*enum-declaration*](#Enum-declaration) |
+| | \| | [*contract-declaration*](#External-contract-declaration) |
+| | \| | [*type-alias-declaration*](#Type-declaration) |
+| | \| | [*ledger-declaration*](#Ledger-declaration) |
+| | \| | [*witness-declaration*](#Witness-declaration) |
+| | \| | [*constructor-definition*](#Constructor) |
+| | \| | [*circuit-definition*](#Circuit-definition) |
#### Pragma (*pragma-form*)
@@ -118,9 +114,9 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
#### Module-definition (*module-definition*)
-| | | |
-|---------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*pelt*](#Program-element) ⋯ [*pelt*](#Program-element) `}` |
+| | | |
+|---------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*program-element*](#Program-element) ⋯ [*program-element*](#Program-element) `}` |
#### Generic-parameter-list (*gparams*)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index 305cdf21..97ca6d50 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -922,22 +922,22 @@ circuit sumSomeYs([{y: b1,}, , {y: b3,},]: [S, S, S]): Field {
A compact program is a sequence of zero or more program elements.
-| | | |
-|-----------|---------|----------------------------------------------------------------------------|
-| *program* | ⟶ | [*pelt*](#programs) ⋯ [*pelt*](#programs) [*eof*](#dummy) |
-| *pelt* | ⟶ | [*pragma-form*](#pragmas) |
-| | \| | [*module-definition*](#modules-exports-and-imports) |
-| | \| | [*import-form*](#imports) |
-| | \| | [*export-form*](#exports) |
-| | \| | [*include-form*](#include-files) |
-| | \| | [*struct-declaration*](#structure-types) |
-| | \| | [*enum-declaration*](#enumeration-types) |
-| | \| | [*contract-declaration*](#dummy) |
-| | \| | [*type-alias-declaration*](#type-aliases) |
-| | \| | [*ledger-declaration*](#declaring-and-maintaining-public-state) |
-| | \| | [*witness-declaration*](#declaring-witnesses-for-private-state-management) |
-| | \| | [*constructor-definition*](#contract-constructor) |
-| | \| | [*circuit-definition*](#circuit-definitions) |
+| | | |
+|-------------------|---------|----------------------------------------------------------------------------|
+| *program* | ⟶ | [*program-element*](#programs) ⋯ [*program-element*](#programs) |
+| *program-element* | ⟶ | [*pragma-form*](#pragmas) |
+| | \| | [*module-definition*](#modules-exports-and-imports) |
+| | \| | [*import-form*](#imports) |
+| | \| | [*export-form*](#exports) |
+| | \| | [*include-form*](#include-files) |
+| | \| | [*struct-declaration*](#structure-types) |
+| | \| | [*enum-declaration*](#enumeration-types) |
+| | \| | [*contract-declaration*](#contract-types) |
+| | \| | [*type-alias-declaration*](#type-aliases) |
+| | \| | [*ledger-declaration*](#declaring-and-maintaining-public-state) |
+| | \| | [*witness-declaration*](#declaring-witnesses-for-private-state-management) |
+| | \| | [*constructor-definition*](#contract-constructor) |
+| | \| | [*circuit-definition*](#circuit-definitions) |
@@ -1016,9 +1016,9 @@ A module is a named collection of program elements created via a module definiti
which takes the following form:
-| | | |
-|---------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt `{` [*pelt*](#programs) ⋯ [*pelt*](#programs) `}` |
+| | | |
+|---------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt `{` [*program-element*](#programs) ⋯ [*program-element*](#programs) `}` |
From 55a0fc5d43bbba1c2fb3cc7dc2b26a391109b24e Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Fri, 13 Mar 2026 22:14:34 +0100
Subject: [PATCH 18/41] latest lang-ref.mdx and compact-grammar.mdx
---
docs/compact/reference/compact-grammar.mdx | 388 +++++++++++----------
docs/compact/reference/lang-ref.mdx | 57 ++-
2 files changed, 219 insertions(+), 226 deletions(-)
diff --git a/docs/compact/reference/compact-grammar.mdx b/docs/compact/reference/compact-grammar.mdx
index 495cff5e..1052c2c7 100644
--- a/docs/compact/reference/compact-grammar.mdx
+++ b/docs/compact/reference/compact-grammar.mdx
@@ -10,91 +10,95 @@ Compact language version 0.22.0.
Notational note: In the grammar below, keywords and punctuation are in `monospaced` font. Terminal and nonterminal names are in *emphasized* font. Alternation is indicated by a vertical bar (`|`). Optional items are indicated by the superscript opt. Repetition is specified by ellipses. The notation *X* ⋯ *X*, where *X* is a grammar symbol, represents zero or more occurrences of *X*. The notation *X* `,` ⋯ `,` *X*, where *X* is a grammar symbol and `,` is a literal comma, represents zero or more occurrences of *X* separated by commas. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one *X*. When such a sequence is followed by *,*opt, an optional trailing comma is allowed, but only if there is at least one *X*. For example, *id* ⋯ *id* represents zero or more *id*s, and *expr* `,` ⋯¹`,` *expr* `,`opt represents one or more comma-separated *expr*s possibly followed by an extra comma. The rules involving commas apply equally to semicolons, i.e., apply when `,` is replaced by `;`.
-#### identifier (*id*, *module-name*, *function-name*, *struct-name*, *enum-name*, *contract-name*, *tvar-name*, *type-name*)
+#### identifier
+*id*, *module-name*, *function-name*, *struct-name*, *enum-name*, *contract-name*, *tvar-name*, *type-name*
Identifiers have the same syntax as Typescript identifiers.
-#### field-literal (*nat*)
+#### field-literal
+*nat*
A field literal is 0 or a natural number formed from a sequence of digits starting with 1-9, e.g. 723, whose value does not exceed the maximum field value.
-#### string-literal (*str*, *file*)
+#### string-literal
+*str*, *file*
A string literal has the same syntax as a Typescript string.
-#### version-literal (*version*)
+#### version-literal
+*version*
-A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2.3, representing major, minor, and bugfix versions.
+A version literal takes the form nat.nat representing major and minor versions or nat.nat.nat representing major, minor, and bugfix versions. Where version literals are allowed, a plain nat representing just the major version is also allowed.
-#### Compact (*program*)
+#### Compact
| | | |
|-----------|---------|--------------------------------------------------------------------------------|
-| *program* | ⟶ | [*program-element*](#Program-element) ⋯ [*program-element*](#Program-element) |
+| *program* | ⟶ | [*program-element*](#program-element) ⋯ [*program-element*](#program-element) |
-#### Program-element (*program-element*)
+#### Program-element
| | | |
|-------------------|---------|----------------------------------------------------------|
-| *program-element* | ⟶ | [*pragma-form*](#Pragma) |
-| | \| | [*module-definition*](#Module-definition) |
-| | \| | [*import-form*](#Import-declaration) |
-| | \| | [*export-form*](#Export-declaration) |
-| | \| | [*include-form*](#Include) |
-| | \| | [*struct-declaration*](#Structure-declaration) |
-| | \| | [*enum-declaration*](#Enum-declaration) |
-| | \| | [*contract-declaration*](#External-contract-declaration) |
-| | \| | [*type-alias-declaration*](#Type-declaration) |
-| | \| | [*ledger-declaration*](#Ledger-declaration) |
-| | \| | [*witness-declaration*](#Witness-declaration) |
-| | \| | [*constructor-definition*](#Constructor) |
-| | \| | [*circuit-definition*](#Circuit-definition) |
+| *program-element* | ⟶ | [*pragma-form*](#pragma) |
+| | \| | [*module-definition*](#module-definition) |
+| | \| | [*import-form*](#import-declaration) |
+| | \| | [*export-form*](#export-declaration) |
+| | \| | [*include-form*](#include) |
+| | \| | [*struct-declaration*](#structure-declaration) |
+| | \| | [*enum-declaration*](#enum-declaration) |
+| | \| | [*contract-declaration*](#external-contract-declaration) |
+| | \| | [*type-alias-declaration*](#type-declaration) |
+| | \| | [*ledger-declaration*](#ledger-declaration) |
+| | \| | [*witness-declaration*](#witness-declaration) |
+| | \| | [*constructor-definition*](#constructor) |
+| | \| | [*circuit-definition*](#circuit-definition) |
-#### Pragma (*pragma-form*)
+#### Pragma
| | | |
|---------------|---------|------------------------------------------------------------------------|
-| *pragma-form* | ⟶ | `pragma` [*id*](#identifier) [*version-expr*](#Version-expression) `;` |
+| *pragma-form* | ⟶ | `pragma` [*id*](#identifier) [*version-expr*](#version-expression) `;` |
-#### Version-expression (*version-expr*)
+#### Version-expression
| | | |
|----------------|---------|-------------------------------------------------------------------------------------------------|
-| *version-expr* | ⟶ | [*version-expr*](#Version-expression) `\|\|` [*version-expr0*](#Version-expression0) |
-| | \| | [*version-expr0*](#Version-expression0) |
+| *version-expr* | ⟶ | [*version-expr*](#version-expression) `\|\|` [*version-expr0*](#version-expression0) |
+| | \| | [*version-expr0*](#version-expression0) |
-#### Version-expression0 (*version-expr0*)
+#### Version-expression0
| | | |
|----------------------------|---------|-----------------------------------------------------------------------------------------|
-| *version-expr0* | ⟶ | [*version-expr0*](#Version-expression0) `&&` [*version-term*](#Version-Term) |
-| | \| | [*version-term*](#Version-Term) |
+| *version-expr0* | ⟶ | [*version-expr0*](#version-expression0) `&&` [*version-term*](#version-term) |
+| | \| | [*version-term*](#version-term) |
-#### Version-Term (*version-term*)
+#### Version-Term
| | | |
|----------------|---------|-----------------------------------------------|
-| *version-term* | ⟶ | [*version-atom*](#Version-atom) |
-| | \| | `!` [*version-atom*](#Version-atom) |
-| | \| | `<` [*version-atom*](#Version-atom) |
-| | \| | `<=` [*version-atom*](#Version-atom) |
-| | \| | `>=` [*version-atom*](#Version-atom) |
-| | \| | `>` [*version-atom*](#Version-atom) |
-| | \| | `(` [*version-expr*](#Version-expression) `)` |
+| *version-term* | ⟶ | [*version-atom*](#version-atom) |
+| | \| | `!` [*version-atom*](#version-atom) |
+| | \| | `<` [*version-atom*](#version-atom) |
+| | \| | `<=` [*version-atom*](#version-atom) |
+| | \| | `>=` [*version-atom*](#version-atom) |
+| | \| | `>` [*version-atom*](#version-atom) |
+| | \| | `(` [*version-expr*](#version-expression) `)` |
-#### Version-atom (*version-atom*)
+#### Version-atom
| | | |
@@ -103,7 +107,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*version*](#version-literal) |
-#### Include (*include-form*)
+#### Include
| | | |
@@ -111,23 +115,23 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *include-form* | ⟶ | `include` [*file*](#string-literal) `;` |
-#### Module-definition (*module-definition*)
+#### Module-definition
| | | |
|---------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*program-element*](#Program-element) ⋯ [*program-element*](#Program-element) `}` |
+| *module-definition* | ⟶ | `export`opt `module` [*module-name*](#identifier) [*gparams*](#generic-parameter-list)opt `{` [*program-element*](#program-element) ⋯ [*program-element*](#program-element) `}` |
-#### Generic-parameter-list (*gparams*)
+#### Generic-parameter-list
| | | |
|-----------|---------|-----------------------------------------------------------------------------------------------------------------|
-| *gparams* | ⟶ | `<` [*generic-param*](#Generic-parameter) `,` ⋯ `,` [*generic-param*](#Generic-parameter) `,`opt `>` |
+| *gparams* | ⟶ | `<` [*generic-param*](#generic-parameter) `,` ⋯ `,` [*generic-param*](#generic-parameter) `,`opt `>` |
-#### Generic-parameter (*generic-param*)
+#### Generic-parameter
| | | |
@@ -136,23 +140,23 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*tvar-name*](#identifier) |
-#### Import-declaration (*import-form*)
+#### Import-declaration
| | | |
|---------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *import-form* | ⟶ | `import` [*import-selection*](#Import-selection)opt [*import-name*](#Import-name) [*gargs*](#Generic-argument-list)opt [*import-prefix*](#Import-prefix)opt `;` |
+| *import-form* | ⟶ | `import` [*import-selection*](#import-selection)opt [*import-name*](#import-name) [*gargs*](#generic-argument-list)opt [*import-prefix*](#import-prefix)opt `;` |
-#### Import-selection (*import-selection*)
+#### Import-selection
| | | |
|--------------------|---------|--------------------------------------------------------------------------------------------------------------------|
-| *import-selection* | ⟶ | `{` [*import-element*](#Import-element) `,` ⋯ `,` [*import-element*](#Import-element) `,`opt `}` `from` |
+| *import-selection* | ⟶ | `{` [*import-element*](#import-element) `,` ⋯ `,` [*import-element*](#import-element) `,`opt `}` `from` |
-#### Import-element (*import-element*)
+#### Import-element
| | | |
@@ -161,7 +165,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*id*](#identifier) `as` [*id*](#identifier) |
-#### Import-name (*import-name*)
+#### Import-name
| | | |
@@ -170,7 +174,7 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*file*](#string-literal) |
-#### Import-prefix (*import-prefix*)
+#### Import-prefix
| | | |
@@ -178,24 +182,24 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *import-prefix* | ⟶ | `prefix` [*id*](#identifier) |
-#### Generic-argument-list (*gargs*)
+#### Generic-argument-list
| | | |
|---------|---------|---------------------------------------------------------------------------------------------|
-| *gargs* | ⟶ | `<` [*garg*](#Generic-argument) `,` ⋯ `,` [*garg*](#Generic-argument) `,`opt `>` |
+| *gargs* | ⟶ | `<` [*garg*](#generic-argument) `,` ⋯ `,` [*garg*](#generic-argument) `,`opt `>` |
-#### Generic-argument (*garg*)
+#### Generic-argument
| | | |
|--------|---------|-------------------------|
| *garg* | ⟶ | [*nat*](#field-literal) |
-| | \| | [*type*](#Type) |
+| | \| | [*type*](#type) |
-#### Export-declaration (*export-form*)
+#### Export-declaration
| | | |
@@ -203,48 +207,48 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *export-form* | ⟶ | `export` `{` [*id*](#identifier) `,` ⋯ `,` [*id*](#identifier) `,`opt `}` `;`opt |
-#### Ledger-declaration (*ledger-declaration*)
+#### Ledger-declaration
| | | |
|----------------------|---------|----------------------------------------------------------------------------------------------------|
-| *ledger-declaration* | ⟶ | `export`opt `sealed`opt `ledger` [*id*](#identifier) `:` [*type*](#Type) `;` |
+| *ledger-declaration* | ⟶ | `export`opt `sealed`opt `ledger` [*id*](#identifier) `:` [*type*](#type) `;` |
-#### Witness-declaration (*witness-declaration*)
+#### Witness-declaration
| | | |
|-----------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *witness-declaration* | ⟶ | `export`opt `witness` [*id*](#identifier) [*gparams*](#Generic-parameter-list)opt [*simple-parameter-list*](#Simple-parameter-list) `:` [*type*](#Type) `;` |
+| *witness-declaration* | ⟶ | `export`opt `witness` [*id*](#identifier) [*gparams*](#generic-parameter-list)opt [*simple-parameter-list*](#simple-parameter-list) `:` [*type*](#type) `;` |
-#### Constructor (*constructor-definition*)
+#### Constructor
| | | |
|--------------------------|---------|-------------------------------------------------------------------------------------|
-| *constructor-definition* | ⟶ | `constructor` [*pattern-parameter-list*](#Pattern-parameter-list) [*block*](#Block) |
+| *constructor-definition* | ⟶ | `constructor` [*pattern-parameter-list*](#pattern-parameter-list) [*block*](#block) |
-#### Circuit-definition (*circuit-definition*)
+#### Circuit-definition
| | | |
|----------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *circuit-definition* | ⟶ | `export`opt `pure`opt `circuit` [*function-name*](#identifier) [*gparams*](#Generic-parameter-list)opt [*pattern-parameter-list*](#Pattern-parameter-list) `:` [*type*](#Type) [*block*](#Block) |
+| *circuit-definition* | ⟶ | `export`opt `pure`opt `circuit` [*function-name*](#identifier) [*gparams*](#generic-parameter-list)opt [*pattern-parameter-list*](#pattern-parameter-list) `:` [*type*](#type) [*block*](#block) |
-#### Structure-declaration (*struct-declaration*)
+#### Structure-declaration
| | | |
|----------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *struct-declaration* | ⟶ | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-id*](#Typed-identifier) `;` ⋯ `;` [*typed-id*](#Typed-identifier) `;`opt `}` `;`opt |
-| | \| | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `{` [*typed-id*](#Typed-identifier) `,` ⋯ `,` [*typed-id*](#Typed-identifier) `,`opt `}` `;`opt |
+| *struct-declaration* | ⟶ | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#generic-parameter-list)opt `{` [*typed-id*](#typed-identifier) `;` ⋯ `;` [*typed-id*](#typed-identifier) `;`opt `}` `;`opt |
+| | \| | `export`opt `struct` [*struct-name*](#identifier) [*gparams*](#generic-parameter-list)opt `{` [*typed-id*](#typed-identifier) `,` ⋯ `,` [*typed-id*](#typed-identifier) `,`opt `}` `;`opt |
-#### Enum-declaration (*enum-declaration*)
+#### Enum-declaration
| | | |
@@ -252,88 +256,88 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| *enum-declaration* | ⟶ | `export`opt `enum` [*enum-name*](#identifier) `{` [*id*](#identifier) `,` ⋯¹ `,` [*id*](#identifier) `,`opt `}` `;`opt |
-#### External-contract-declaration (*contract-declaration*)
+#### External-contract-declaration
| | | |
|------------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *contract-declaration* | ⟶ | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#External-contract-circuit) `;` ⋯ `;` [*circuit-declaration*](#External-contract-circuit) `;`opt `}` `;`opt |
-| | \| | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#External-contract-circuit) `,` ⋯ `,` [*circuit-declaration*](#External-contract-circuit) `,`opt `}` `;`opt |
+| *contract-declaration* | ⟶ | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#external-contract-circuit) `;` ⋯ `;` [*circuit-declaration*](#external-contract-circuit) `;`opt `}` `;`opt |
+| | \| | `export`opt `contract` [*contract-name*](#identifier) `{` [*circuit-declaration*](#external-contract-circuit) `,` ⋯ `,` [*circuit-declaration*](#external-contract-circuit) `,`opt `}` `;`opt |
-#### External-contract-circuit (*circuit-declaration*)
+#### External-contract-circuit
| | | |
|-----------------------|---------|--------------------------------------------------------------------------------------------------------------------------|
-| *circuit-declaration* | ⟶ | `pure`opt `circuit` [*id*](#identifier) [*simple-parameter-list*](#Simple-parameter-list) `:` [*type*](#Type) |
+| *circuit-declaration* | ⟶ | `pure`opt `circuit` [*id*](#identifier) [*simple-parameter-list*](#simple-parameter-list) `:` [*type*](#type) |
-#### Type-declaration (*type-alias-declaration*)
+#### Type-declaration
| | | |
|--------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *type-alias-declaration* | ⟶ | `export`opt `new`opt `type` [*type-name*](#identifier) [*gparams*](#Generic-parameter-list)opt `=` [*type*](#Type) `;` |
+| *type-alias-declaration* | ⟶ | `export`opt `new`opt `type` [*type-name*](#identifier) [*gparams*](#generic-parameter-list)opt `=` [*type*](#type) `;` |
-#### Typed-identifier (*typed-id*)
+#### Typed-identifier
| | | |
|------------|---------|-----------------------------------------|
-| *typed-id* | ⟶ | [*id*](#identifier) `:` [*type*](#Type) |
+| *typed-id* | ⟶ | [*id*](#identifier) `:` [*type*](#type) |
-#### Simple-parameter-list (*simple-parameter-list*)
+#### Simple-parameter-list
| | | |
|-------------------------|---------|-----------------------------------------------------------------------------------------------------|
-| *simple-parameter-list* | ⟶ | `(` [*typed-id*](#Typed-identifier) `,` ⋯ `,` [*typed-id*](#Typed-identifier) `,`opt `)` |
+| *simple-parameter-list* | ⟶ | `(` [*typed-id*](#typed-identifier) `,` ⋯ `,` [*typed-id*](#typed-identifier) `,`opt `)` |
-#### Typed-pattern (*typed-pattern*)
+#### Typed-pattern
| | | |
|-----------------|---------|-------------------------------------------|
-| *typed-pattern* | ⟶ | [*pattern*](#Pattern) `:` [*type*](#Type) |
+| *typed-pattern* | ⟶ | [*pattern*](#pattern) `:` [*type*](#type) |
-#### Pattern-parameter-list (*pattern-parameter-list*)
+#### Pattern-parameter-list
| | | |
|--------------------------|---------|---------------------------------------------------------------------------------------------------------|
-| *pattern-parameter-list* | ⟶ | `(` [*typed-pattern*](#Typed-pattern) `,` ⋯ `,` [*typed-pattern*](#Typed-pattern) `,`opt `)` |
+| *pattern-parameter-list* | ⟶ | `(` [*typed-pattern*](#typed-pattern) `,` ⋯ `,` [*typed-pattern*](#typed-pattern) `,`opt `)` |
-#### Type (*type*)
+#### Type
| | | |
|--------|---------|---------------------------------------------------------------------|
-| *type* | ⟶ | [*tref*](#Type-reference) |
+| *type* | ⟶ | [*tref*](#type-reference) |
| | \| | `Boolean` |
| | \| | `Field` |
-| | \| | `Uint` `<` [*tsize*](#Type-size) `>` |
-| | \| | `Uint` `<` [*tsize*](#Type-size) `..` [*tsize*](#Type-size) `>` |
-| | \| | `Bytes` `<` [*tsize*](#Type-size) `>` |
+| | \| | `Uint` `<` [*tsize*](#type-size) `>` |
+| | \| | `Uint` `<` [*tsize*](#type-size) `..` [*tsize*](#type-size) `>` |
+| | \| | `Bytes` `<` [*tsize*](#type-size) `>` |
| | \| | `Opaque` `<` [*str*](#string-literal) `>` |
-| | \| | `Vector` `<` [*tsize*](#Type-size) `,` [*type*](#Type) `>` |
-| | \| | `[` [*type*](#Type) `,` ⋯ `,` [*type*](#Type) `,`opt `]` |
+| | \| | `Vector` `<` [*tsize*](#type-size) `,` [*type*](#type) `>` |
+| | \| | `[` [*type*](#type) `,` ⋯ `,` [*type*](#type) `,`opt `]` |
-#### Type-reference (*tref*)
+#### Type-reference
| | | |
|--------|---------|---------------------------------------------------------------------|
-| *tref* | ⟶ | [*id*](#identifier) [*gargs*](#Generic-argument-list)opt |
+| *tref* | ⟶ | [*id*](#identifier) [*gargs*](#generic-argument-list)opt |
-#### Type-size (*tsize*)
+#### Type-size
| | | |
@@ -342,184 +346,184 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*id*](#identifier) |
-#### Block (*block*)
+#### Block
| | | |
|---------|---------|-----------------------------------------------------|
-| *block* | ⟶ | `{` [*stmt*](#Statement) ⋯ [*stmt*](#Statement) `}` |
+| *block* | ⟶ | `{` [*stmt*](#statement) ⋯ [*stmt*](#statement) `}` |
-#### Statement (*stmt*)
+#### Statement
| | | |
|--------|---------|----------------------------------------------------------------------|
-| *stmt* | ⟶ | `if` `(` [*expr-seq*](#Expression-sequence) `)` [*stmt*](#Statement) |
-| | \| | [*stmt0*](#Statement0) |
+| *stmt* | ⟶ | `if` `(` [*expr-seq*](#expression-sequence) `)` [*stmt*](#statement) |
+| | \| | [*stmt0*](#statement0) |
-#### Statement0 (*stmt0*)
+#### Statement0
| | | |
|--------------------|---------|--------------------------------------------------------------------------------------------------------------------------|
-| *stmt0* | ⟶ | [*expr-seq*](#Expression-sequence) `;` |
-| | \| | `const` [*cbinding*](#Const-Binding) `,` ⋯¹ `,` [*cbinding*](#Const-Binding) `;` |
-| | \| | `if` `(` [*expr-seq*](#Expression-sequence) `)` [*stmt0*](#Statement0) `else` [*stmt*](#Statement) |
-| | \| | `for` `(` `const` [*id*](#identifier) `of` [*nat*](#field-literal) `..` [*nat*](#field-literal) `)` [*stmt*](#Statement) |
-| | \| | `for` `(` `const` [*id*](#identifier) `of` [*expr-seq*](#Expression-sequence) `)` [*stmt*](#Statement) |
-| | \| | `return` [*expr-seq*](#Expression-sequence) `;` |
+| *stmt0* | ⟶ | [*expr-seq*](#expression-sequence) `;` |
+| | \| | `const` [*cbinding*](#const-binding) `,` ⋯¹ `,` [*cbinding*](#const-binding) `;` |
+| | \| | `if` `(` [*expr-seq*](#expression-sequence) `)` [*stmt0*](#statement0) `else` [*stmt*](#statement) |
+| | \| | `for` `(` `const` [*id*](#identifier) `of` [*nat*](#field-literal) `..` [*nat*](#field-literal) `)` [*stmt*](#statement) |
+| | \| | `for` `(` `const` [*id*](#identifier) `of` [*expr-seq*](#expression-sequence) `)` [*stmt*](#statement) |
+| | \| | `return` [*expr-seq*](#expression-sequence) `;` |
| | \| | `return` `;` |
-| | \| | [*block*](#Block) |
+| | \| | [*block*](#block) |
-#### Pattern (*pattern*)
+#### Pattern
| | | |
|-----------|---------|-------------------------------------------------------------------------------------------------------------------------------------|
| *pattern* | ⟶ | [*id*](#identifier) |
-| | \| | `[` [*pattern*](#Pattern)opt `,` ⋯ `,` [*pattern*](#Pattern)opt `,`opt `]` |
-| | \| | `{` [*pattern-struct-elt*](#Pattern-struct-element) `,` ⋯ `,` [*pattern-struct-elt*](#Pattern-struct-element) `,`opt `}` |
+| | \| | `[` [*pattern*](#pattern)opt `,` ⋯ `,` [*pattern*](#pattern)opt `,`opt `]` |
+| | \| | `{` [*pattern-struct-elt*](#pattern-struct-element) `,` ⋯ `,` [*pattern-struct-elt*](#pattern-struct-element) `,`opt `}` |
-#### Pattern-struct-element (*pattern-struct-elt*)
+#### Pattern-struct-element
| | | |
|----------------------|---------|-----------------------------------------------|
| *pattern-struct-elt* | ⟶ | [*id*](#identifier) |
-| | \| | [*id*](#identifier) `:` [*pattern*](#Pattern) |
+| | \| | [*id*](#identifier) `:` [*pattern*](#pattern) |
-#### Expression-sequence (*expr-seq*)
+#### Expression-sequence
| | | |
|------------|---------|-----------------------------------------------------------------------------------|
-| *expr-seq* | ⟶ | [*expr*](#Expression) |
-| | \| | [*expr*](#Expression) `,` ⋯¹ `,` [*expr*](#Expression) `,` [*expr*](#Expression) |
+| *expr-seq* | ⟶ | [*expr*](#expression) |
+| | \| | [*expr*](#expression) `,` ⋯¹ `,` [*expr*](#expression) `,` [*expr*](#expression) |
-#### Expression (*expr*)
+#### Expression
| | | |
|--------|---------|----------------------------------------------------------------------------------------|
-| *expr* | ⟶ | [*expr0*](#Expression0) `?` [*expr*](#Expression) `:` [*expr*](#Expression) |
-| | \| | [*expr0*](#Expression0) `=` [*expr*](#Expression) |
-| | \| | [*expr0*](#Expression0) `+=` [*expr*](#Expression) |
-| | \| | [*expr0*](#Expression0) `-=` [*expr*](#Expression) |
-| | \| | [*expr0*](#Expression0) |
+| *expr* | ⟶ | [*expr0*](#expression0) `?` [*expr*](#expression) `:` [*expr*](#expression) |
+| | \| | [*expr0*](#expression0) `=` [*expr*](#expression) |
+| | \| | [*expr0*](#expression0) `+=` [*expr*](#expression) |
+| | \| | [*expr0*](#expression0) `-=` [*expr*](#expression) |
+| | \| | [*expr0*](#expression0) |
-#### Expression0 (*expr0*)
+#### Expression0
| | | |
|--------------------|---------|------------------------------------------------------------------------------|
-| *expr0* | ⟶ | [*expr0*](#Expression0) `\|\|` [*expr1*](#Expression1) |
-| | \| | [*expr1*](#Expression1) |
+| *expr0* | ⟶ | [*expr0*](#expression0) `\|\|` [*expr1*](#expression1) |
+| | \| | [*expr1*](#expression1) |
-#### Expression1 (*expr1*)
+#### Expression1
| | | |
|--------------------|---------|----------------------------------------------------------------------------|
-| *expr1* | ⟶ | [*expr1*](#Expression1) `&&` [*expr2*](#Expression2) |
-| | \| | [*expr2*](#Expression2) |
+| *expr1* | ⟶ | [*expr1*](#expression1) `&&` [*expr2*](#expression2) |
+| | \| | [*expr2*](#expression2) |
-#### Expression2 (*expr2*)
+#### Expression2
| | | |
|--------------------|---------|----------------------------------------------------------------------------|
-| *expr2* | ⟶ | [*expr2*](#Expression2) `==` [*expr3*](#Expression3) |
-| | \| | [*expr2*](#Expression2) `!=` [*expr3*](#Expression3) |
-| | \| | [*expr3*](#Expression3) |
+| *expr2* | ⟶ | [*expr2*](#expression2) `==` [*expr3*](#expression3) |
+| | \| | [*expr2*](#expression2) `!=` [*expr3*](#expression3) |
+| | \| | [*expr3*](#expression3) |
-#### Expression3 (*expr3*)
+#### Expression3
| | | |
|--------------------|---------|----------------------------------------------------------------------------|
-| *expr3* | ⟶ | [*expr4*](#Expression4) `<` [*expr4*](#Expression4) |
-| | \| | [*expr4*](#Expression4) `<=` [*expr4*](#Expression4) |
-| | \| | [*expr4*](#Expression4) `>=` [*expr4*](#Expression4) |
-| | \| | [*expr4*](#Expression4) `>` [*expr4*](#Expression4) |
-| | \| | [*expr4*](#Expression4) |
+| *expr3* | ⟶ | [*expr4*](#expression4) `<` [*expr4*](#expression4) |
+| | \| | [*expr4*](#expression4) `<=` [*expr4*](#expression4) |
+| | \| | [*expr4*](#expression4) `>=` [*expr4*](#expression4) |
+| | \| | [*expr4*](#expression4) `>` [*expr4*](#expression4) |
+| | \| | [*expr4*](#expression4) |
-#### Expression4 (*expr4*)
+#### Expression4
| | | |
|--------------------|---------|---------------------------------------------------------|
-| *expr4* | ⟶ | [*expr4*](#Expression4) `as` [*type*](#Type) |
-| | \| | [*expr5*](#Expression5) |
+| *expr4* | ⟶ | [*expr4*](#expression4) `as` [*type*](#type) |
+| | \| | [*expr5*](#expression5) |
-#### Expression5 (*expr5*)
+#### Expression5
| | | |
|--------------------|---------|---------------------------------------------------------------------------|
-| *expr5* | ⟶ | [*expr5*](#Expression5) `+` [*expr6*](#Expression6) |
-| | \| | [*expr5*](#Expression5) `-` [*expr6*](#Expression6) |
-| | \| | [*expr6*](#Expression6) |
+| *expr5* | ⟶ | [*expr5*](#expression5) `+` [*expr6*](#expression6) |
+| | \| | [*expr5*](#expression5) `-` [*expr6*](#expression6) |
+| | \| | [*expr6*](#expression6) |
-#### Expression6 (*expr6*)
+#### Expression6
| | | |
|--------------------|---------|---------------------------------------------------------------------------|
-| *expr6* | ⟶ | [*expr6*](#Expression6) `*` [*expr7*](#Expression7) |
-| | \| | [*expr7*](#Expression7) |
+| *expr6* | ⟶ | [*expr6*](#expression6) `*` [*expr7*](#expression7) |
+| | \| | [*expr7*](#expression7) |
-#### Expression7 (*expr7*)
+#### Expression7
| | | |
|--------------------|---------|----------------------------------------|
-| *expr7* | ⟶ | `!` [*expr7*](#Expression7) |
-| | \| | [*expr8*](#Expression8) |
+| *expr7* | ⟶ | `!` [*expr7*](#expression7) |
+| | \| | [*expr8*](#expression8) |
-#### Expression8 (*expr8*)
+#### Expression8
| | | |
|--------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------|
-| *expr8* | ⟶ | [*expr8*](#Expression8) `[` [*expr*](#Expression) `]` |
-| | \| | [*expr8*](#Expression8) `.` [*id*](#identifier) |
-| | \| | [*expr8*](#Expression8) `.` [*id*](#identifier) `(` [*expr*](#Expression) `,` ⋯ `,` [*expr*](#Expression) `,`opt `)` |
-| | \| | [*expr9*](#Expression9) |
+| *expr8* | ⟶ | [*expr8*](#expression8) `[` [*expr*](#expression) `]` |
+| | \| | [*expr8*](#expression8) `.` [*id*](#identifier) |
+| | \| | [*expr8*](#expression8) `.` [*id*](#identifier) `(` [*expr*](#expression) `,` ⋯ `,` [*expr*](#expression) `,`opt `)` |
+| | \| | [*expr9*](#expression9) |
-#### Expression9 (*expr9*)
+#### Expression9
| | | |
|--------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------|
-| *expr9* | ⟶ | [*fun*](#Function) `(` [*expr*](#Expression) `,` ⋯ `,` [*expr*](#Expression) `,`opt `)` |
-| | \| | `map` `(` [*fun*](#Function) `,` [*expr*](#Expression) `,` ⋯¹ `,` [*expr*](#Expression) `,`opt `)` |
-| | \| | `fold` `(` [*fun*](#Function) `,` [*expr*](#Expression) `,` [*expr*](#Expression) `,` ⋯¹ `,` [*expr*](#Expression) `,`opt `)` |
-| | \| | `slice` `<` [*tsize*](#Type-size) `>` `(` [*expr*](#Expression) `,` [*expr*](#Expression) `)` |
-| | \| | `[` [*tuple-arg*](#Tuple-argument) `,` ⋯ `,` [*tuple-arg*](#Tuple-argument) `,`opt `]` |
-| | \| | `Bytes` `[` [*tuple-arg*](#Tuple-argument) `,` ⋯ `,` [*tuple-arg*](#Tuple-argument) `,`opt `]` |
-| | \| | [*tref*](#Type-reference) `{` [*struct-arg*](#Structure-argument) `,` ⋯ `,` [*struct-arg*](#Structure-argument) `,`opt `}` |
-| | \| | `assert` `(` [*expr*](#Expression) `,` [*str*](#string-literal) `)` |
-| | \| | `disclose` `(` [*expr*](#Expression) `)` |
-| | \| | [*term*](#Term) |
+| *expr9* | ⟶ | [*fun*](#function) `(` [*expr*](#expression) `,` ⋯ `,` [*expr*](#expression) `,`opt `)` |
+| | \| | `map` `(` [*fun*](#function) `,` [*expr*](#expression) `,` ⋯¹ `,` [*expr*](#expression) `,`opt `)` |
+| | \| | `fold` `(` [*fun*](#function) `,` [*expr*](#expression) `,` [*expr*](#expression) `,` ⋯¹ `,` [*expr*](#expression) `,`opt `)` |
+| | \| | `slice` `<` [*tsize*](#type-size) `>` `(` [*expr*](#expression) `,` [*expr*](#expression) `)` |
+| | \| | `[` [*tuple-arg*](#tuple-argument) `,` ⋯ `,` [*tuple-arg*](#tuple-argument) `,`opt `]` |
+| | \| | `Bytes` `[` [*bytes-arg*](#tuple-argument) `,` ⋯ `,` [*bytes-arg*](#tuple-argument) `,`opt `]` |
+| | \| | [*tref*](#type-reference) `{` [*struct-arg*](#structure-argument) `,` ⋯ `,` [*struct-arg*](#structure-argument) `,`opt `}` |
+| | \| | `assert` `(` [*expr*](#expression) `,` [*str*](#string-literal) `)` |
+| | \| | `disclose` `(` [*expr*](#expression) `)` |
+| | \| | [*term*](#term) |
-#### Term (*term*)
+#### Term
| | | |
@@ -530,71 +534,71 @@ A version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2
| | \| | [*nat*](#field-literal) |
| | \| | [*str*](#string-literal) |
| | \| | `pad` `(` [*nat*](#field-literal) `,` [*str*](#string-literal) `)` |
-| | \| | `default` `<` [*type*](#Type) `>` |
-| | \| | `(` [*expr-seq*](#Expression-sequence) `)` |
+| | \| | `default` `<` [*type*](#type) `>` |
+| | \| | `(` [*expr-seq*](#expression-sequence) `)` |
-#### Tuple-argument (*tuple-arg*, *bytes-arg*)
+#### Tuple-argument
-| | | |
-|-------------|---------|-----------------------------|
-| *tuple-arg* | ⟶ | [*expr*](#Expression) |
-| | \| | `...` [*expr*](#Expression) |
-| *bytes-arg* | ⟶ | *tuple-arg* |
+| | | |
+|-------------|---------|--------------------------------|
+| *tuple-arg* | ⟶ | [*expr*](#expression) |
+| | \| | `...` [*expr*](#expression) |
+| *bytes-arg* | ⟶ | [*tuple-arg*](#tuple-argument) |
-#### Structure-argument (*struct-arg*)
+#### Structure-argument
| | | |
|--------------|---------|-----------------------------------------------|
-| *struct-arg* | ⟶ | [*expr*](#Expression) |
-| | \| | [*id*](#identifier) `:` [*expr*](#Expression) |
-| | \| | `...` [*expr*](#Expression) |
+| *struct-arg* | ⟶ | [*expr*](#expression) |
+| | \| | [*id*](#identifier) `:` [*expr*](#expression) |
+| | \| | `...` [*expr*](#expression) |
-#### Function (*fun*)
+#### Function
| | | |
|-------|---------|------------------------------------------------------------------------------------------------------------------------|
-| *fun* | ⟶ | [*id*](#identifier) [*gargs*](#Generic-argument-list)opt |
-| | \| | [*arrow-parameter-list*](#Arrow-parameter-list) [*return-type*](#Return-type)opt `=>` [*block*](#Block) |
-| | \| | [*arrow-parameter-list*](#Arrow-parameter-list) [*return-type*](#Return-type)opt `=>` [*expr*](#Expression) |
-| | \| | `(` [*fun*](#Function) `)` |
+| *fun* | ⟶ | [*id*](#identifier) [*gargs*](#generic-argument-list)opt |
+| | \| | [*arrow-parameter-list*](#arrow-parameter-list) [*return-type*](#return-type)opt `=>` [*block*](#block) |
+| | \| | [*arrow-parameter-list*](#arrow-parameter-list) [*return-type*](#return-type)opt `=>` [*expr*](#expression) |
+| | \| | `(` [*fun*](#function) `)` |
-#### Return-type (*return-type*)
+#### Return-type
| | | |
|---------------|---------|---------------------|
-| *return-type* | ⟶ | `:` [*type*](#Type) |
+| *return-type* | ⟶ | `:` [*type*](#type) |
-#### Optionally-typed-pattern (*optionally-typed-pattern*)
+#### Optionally-typed-pattern
| | | |
|----------------------------|---------|-----------------------------------|
-| *optionally-typed-pattern* | ⟶ | [*pattern*](#Pattern) |
-| | \| | [*typed-pattern*](#Typed-pattern) |
+| *optionally-typed-pattern* | ⟶ | [*pattern*](#pattern) |
+| | \| | [*typed-pattern*](#typed-pattern) |
-#### Const-Binding (*cbinding*)
+#### Const-Binding
| | | |
|------------|---------|-----------------------------------------------------------------------------------|
-| *cbinding* | ⟶ | [*optionally-typed-pattern*](#Optionally-typed-pattern) `=` [*expr*](#Expression) |
+| *cbinding* | ⟶ | [*optionally-typed-pattern*](#optionally-typed-pattern) `=` [*expr*](#expression) |
-#### Arrow-parameter-list (*arrow-parameter-list*)
+#### Arrow-parameter-list
| | | |
|------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
-| *arrow-parameter-list* | ⟶ | `(` [*optionally-typed-pattern*](#Optionally-typed-pattern) `,` ⋯ `,` [*optionally-typed-pattern*](#Optionally-typed-pattern) `,`opt `)` |
+| *arrow-parameter-list* | ⟶ | `(` [*optionally-typed-pattern*](#optionally-typed-pattern) `,` ⋯ `,` [*optionally-typed-pattern*](#optionally-typed-pattern) `,`opt `)` |
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index 97ca6d50..ec8badfb 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -23,7 +23,7 @@ kinds of program elements:
- module and import forms for management of namespaces and separate files,
- declarations of program-defined types,
- declarations of the data that the contract stores in the public ledger,
-- declarations of *witnesses*, which are callback functions supplied by the TypeScript runner, and
+- declarations of *witnesses*, which are callback functions supplied by the TypeScript runner,
- definitions of *circuits*, which are functions serving as the operational core of a smart contract, and
- the definition of at most one *constructor*, which is a function used to intialize the public ledger.
@@ -38,7 +38,8 @@ Compact deviates intentionally from TypeScript, however, in several important wa
Compact as well as preventing external application of a Compact circuit with
more or fewer than the declared number of arguments.
- Compact provides namespace management via static rather than dynamic modules, and
- these modules can be parameterized via compile-time generic parameters, which include size as
+ these modules can be parameterized via compile-time
+ [generic parameters](#generic-parameters-and-arguments), which include size as
well as type parameters.
- Because every Compact program must compile into a set of finite proving circuits,
all Compact types have sizes that are fixed at compile time, loops are bounded either
@@ -56,7 +57,7 @@ Compact deviates intentionally from TypeScript, however, in several important wa
[Explicit disclosure in Compact](explicit-disclosure).
Like TypeScript, Compact compiles into JavaScript, but it also produces a TypeScript
-definition file so that it effectively also compiles into TypeScript.
+definition file so it effectively also compiles into TypeScript.
It produces separate TypeScript definition files and JavaScript implementation files
rather than simply producing TypeScript for three reasons:
- to allow compiled Compact programs to be used without requiring an additional
@@ -345,7 +346,7 @@ parameters, so any generic argument can pass along the value of a generic type
or natural-number parameter that is visible at the point of specialization.
The `#` used to distinguish generic natural-number parameters from generic type parameters
-need not and must not used at the point of specialization.
+need not and must not be used at the point of specialization.
It is a static error, however, if a generic argument supplied for a generic
parameter is not numeric when a numeric value is expected or is not a type when
a type is expected.
@@ -1310,7 +1311,6 @@ provided by the TypeScript driver.
|-------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| *witness-declaration* | ⟶ | `export`opt `witness` [*id*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt [*simple-parameter-list*](#declaring-witnesses-for-private-state-management) `:` [*type*](#primitive-types) `;` |
| *simple-parameter-list* | ⟶ | `(` [*typed-id*](#structure-types) `,` ⋯ `,` [*typed-id*](#structure-types) `,`opt `)` |
-| *typed-id* | ⟶ | [*id*](#terminal-names) `:` [*type*](#primitive-types) |
@@ -1628,11 +1628,9 @@ in [Circuit and witness calls](#circuit-and-witness-calls).
Named circuit definitions have the following syntax:
-| | | |
-|--------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| *circuit-definition* | ⟶ | `export`opt `pure`opt `circuit` [*function-name*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt [*pattern-parameter-list*](#contract-constructor) `:` [*type*](#primitive-types) [*block*](#blocks) |
-| *pattern-parameter-list* | ⟶ | `(` [*typed-pattern*](#contract-constructor) `,` ⋯ `,` [*typed-pattern*](#contract-constructor) `,`opt `)` |
-| *typed-pattern* | ⟶ | [*pattern*](#patterns-and-destructuring) `:` [*type*](#primitive-types) |
+| | | |
+|----------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| *circuit-definition* | ⟶ | `export`opt `pure`opt `circuit` [*function-name*](#terminal-names) [*gparams*](#generic-parameters-and-arguments)opt [*pattern-parameter-list*](#contract-constructor) `:` [*type*](#primitive-types) [*block*](#blocks) |
@@ -1798,8 +1796,6 @@ in the syntax specified by the following grammar snippet:
| *cbinding* | ⟶ | [*optionally-typed-pattern*](#const-statements) `=` [*expr*](#expressions) |
| *optionally-typed-pattern* | ⟶ | [*pattern*](#patterns-and-destructuring) |
| | \| | [*typed-pattern*](#contract-constructor) |
-| *pattern-struct-elt* | ⟶ | [*id*](#terminal-names) |
-| | \| | [*id*](#terminal-names) `:` [*pattern*](#patterns-and-destructuring) |
@@ -2042,17 +2038,11 @@ The syntax of Compact expressions is summarized by the following grammar snippet
| | \| | `fold` `(` [*fun*](#circuit-and-witness-calls) `,` [*expr*](#expressions) `,` [*expr*](#expressions) `,` ⋯¹ `,` [*expr*](#expressions) `,`opt `)` |
| | \| | `slice` `<` [*tsize*](#primitive-types) `>` `(` [*expr*](#expressions) `,` [*expr*](#expressions) `)` |
| | \| | `[` [*tuple-arg*](#expressions) `,` ⋯ `,` [*tuple-arg*](#expressions) `,`opt `]` |
-| | \| | `Bytes` `[` [*tuple-arg*](#expressions) `,` ⋯ `,` [*tuple-arg*](#expressions) `,`opt `]` |
+| | \| | `Bytes` `[` [*bytes-arg*](#expressions) `,` ⋯ `,` [*bytes-arg*](#expressions) `,`opt `]` |
| | \| | [*tref*](#primitive-types) `{` [*struct-arg*](#expressions) `,` ⋯ `,` [*struct-arg*](#expressions) `,`opt `}` |
| | \| | `assert` `(` [*expr*](#expressions) `,` [*str*](#terminal-names) `)` |
| | \| | `disclose` `(` [*expr*](#expressions) `)` |
| | \| | [*term*](#expressions) |
-| *tuple-arg* | ⟶ | [*expr*](#expressions) |
-| | \| | `...` [*expr*](#expressions) |
-| *bytes-arg* | ⟶ | [*tuple-arg*](#expressions) |
-| *struct-arg* | ⟶ | [*expr*](#expressions) |
-| | \| | [*id*](#terminal-names) `:` [*expr*](#expressions) |
-| | \| | `...` [*expr*](#expressions) |
| *term* | ⟶ | [*id*](#terminal-names) |
| | \| | `true` |
| | \| | `false` |
@@ -2061,6 +2051,12 @@ The syntax of Compact expressions is summarized by the following grammar snippet
| | \| | `pad` `(` [*nat*](#terminal-names) `,` [*str*](#terminal-names) `)` |
| | \| | `default` `<` [*type*](#primitive-types) `>` |
| | \| | `(` [*expr-seq*](#expressions) `)` |
+| *struct-arg* | ⟶ | [*expr*](#expressions) |
+| | \| | [*id*](#terminal-names) `:` [*expr*](#expressions) |
+| | \| | `...` [*expr*](#expressions) |
+| *bytes-arg* | ⟶ | [*tuple-arg*](#expressions) |
+| *tuple-arg* | ⟶ | [*expr*](#expressions) |
+| | \| | `...` [*expr*](#expressions) |
@@ -2747,21 +2743,14 @@ type of `e` is an enumeration type.
### Circuit and witness calls
-| | | |
-|----------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------|
-| *fun* | ⟶ | [*id*](#terminal-names) [*gargs*](#generic-parameters-and-arguments)opt |
-| | \| | [*arrow-parameter-list*](#circuit-and-witness-calls) [*return-type*](#circuit-and-witness-calls)opt `=>` [*block*](#blocks) |
-| | \| | [*arrow-parameter-list*](#circuit-and-witness-calls) [*return-type*](#circuit-and-witness-calls)opt `=>` [*expr*](#expressions) |
-| | \| | `(` [*fun*](#circuit-and-witness-calls) `)` |
-| *arrow-parameter-list* | ⟶ | `(` [*optionally-typed-pattern*](#const-statements) `,` ⋯ `,` [*optionally-typed-pattern*](#const-statements) `,`opt `)` |
-| *optionally-typed-pattern* | ⟶ | [*pattern*](#patterns-and-destructuring) |
-| | \| | [*typed-pattern*](#contract-constructor) |
-| *pattern* | ⟶ | [*id*](#terminal-names) |
-| | \| | `[` [*pattern*](#patterns-and-destructuring)opt `,` ⋯ `,` [*pattern*](#patterns-and-destructuring)opt `,`opt `]` |
-| | \| | `{` [*pattern-struct-elt*](#patterns-and-destructuring) `,` ⋯ `,` [*pattern-struct-elt*](#patterns-and-destructuring) `,`opt `}` |
-| *pattern-struct-elt* | ⟶ | [*id*](#terminal-names) |
-| | \| | [*id*](#terminal-names) `:` [*pattern*](#patterns-and-destructuring) |
-| *return-type* | ⟶ | `:` [*type*](#primitive-types) |
+| | | |
+|------------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------|
+| *fun* | ⟶ | [*id*](#terminal-names) [*gargs*](#generic-parameters-and-arguments)opt |
+| | \| | [*arrow-parameter-list*](#circuit-and-witness-calls) [*return-type*](#circuit-and-witness-calls)opt `=>` [*block*](#blocks) |
+| | \| | [*arrow-parameter-list*](#circuit-and-witness-calls) [*return-type*](#circuit-and-witness-calls)opt `=>` [*expr*](#expressions) |
+| | \| | `(` [*fun*](#circuit-and-witness-calls) `)` |
+| *arrow-parameter-list* | ⟶ | `(` [*optionally-typed-pattern*](#const-statements) `,` ⋯ `,` [*optionally-typed-pattern*](#const-statements) `,`opt `)` |
+| *return-type* | ⟶ | `:` [*type*](#primitive-types) |
From 58f6a6c5f0ce6076df189d4c0a97f4ab4c7e3cd7 Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Sun, 15 Mar 2026 12:00:02 +0100
Subject: [PATCH 19/41] latest version of lang-ref.mdx
---
docs/compact/reference/lang-ref.mdx | 490 ++++++++++++++--------------
1 file changed, 243 insertions(+), 247 deletions(-)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index ec8badfb..93658949 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -2,6 +2,7 @@
SPDX-License-Identifier: Apache-2.0
copyright: This file is part of midnight-docs. Copyright (C) 2025 Midnight Foundation. Licensed under the Apache License, Version 2.0 (the "License"); You may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
title: Compact reference
+DO NOT EDIT. This file is automatically generated.
---
# Compact reference
@@ -25,7 +26,7 @@ kinds of program elements:
- declarations of the data that the contract stores in the public ledger,
- declarations of *witnesses*, which are callback functions supplied by the TypeScript runner,
- definitions of *circuits*, which are functions serving as the operational core of a smart contract, and
-- the definition of at most one *constructor*, which is a function used to intialize the public ledger.
+- the definition of at most one *constructor*, which is a function used to initialize the public ledger.
Compact is similar to TypeScript: it has a syntax similar to that of JavaScript,
and it layers a type system over the JavaScript syntax.
@@ -159,7 +160,7 @@ all represent identifier tokens.
- *version* represents version literals (in pragmas).
While identifiers and string literals are each represented by more than one name,
-each representes the entire set of possible identifier or string-literal tokens.
+each represents the entire set of possible identifier or string-literal tokens.
The grammar snippets use different terminal names only to suggest their use, e.g,
*module-name* for module names versus *tvar-name* for type variable names.
@@ -172,8 +173,10 @@ for the errors and terminates without generating any output.
The code the compiler generates and the run-time libraries it uses detect various
kinds of *dynamic errors*, e.g., attempts from code outside of Compact to call
-Compact circuits with wrong numbers or types of arguments.
-These errors are reported when the generated code is run.
+Compact circuits with wrong numbers or types of arguments or attempts to cast
+an unsigned value to an unsigned type that is too small for the value.
+These errors are reported when the generated code is run and cause evaluation
+of the current circuit to halt.
## Identifiers, bindings, and scope
@@ -212,7 +215,7 @@ and/or different numbers or types of run-time parameters.
The scope of each binding depends upon where it appears, as described below.
(The caveat "except where shadowed" is not explicitly stated but applies in each case.)
-- Identifiers bound at the outermost level of a contract (refered to as the *top
+- Identifiers bound at the outermost level of a contract (referred to as the *top
level*) are visible throughout the contract, but not within any modules that are
imported from separate files.
- Identifiers bound at the outermost level of a module are visible throughout the module.
@@ -258,7 +261,7 @@ For circuit and witness bindings, the lifetime is effectively permanent, i.e.,
the binding is always available for use whenever the program is run.
The lifetimes of ledger-field bindings begin when they are first initialized
-and are effectively permanant from that point on; although the value of a
+and are effectively permanent from that point on; although the value of a
field can change over time, the association of the ledger-field name with the
ledger field's location in the (replicated) public state of a contract never
changes.
@@ -305,7 +308,7 @@ parameters whose values are given at the use site rather than fixed at the point
of declaration.
This allows the same *generic* code to be used with different specific types,
bounds, and sizes.
-Except where shadowed, generic parameters are visible thoughout the entire entity.
+Except where shadowed, generic parameters are visible throughout the entire entity.
In particular, the generic parameters of a module are visible within the program
elements that appear within the body of the module.
@@ -313,7 +316,7 @@ When present, generic parameters are enclosed in angle brackets following the
name of the generic entity (module, structure, type alias, circuit, or witness).
Each parameter is either a type name (e.g., `T`) or a hash-prefixed natural-number name
(e.g., `#N`).
-Generic natural-number parameters are prefixed by `#` to distingish them from
+Generic natural-number parameters are prefixed by `#` to distinguish them from
generic type parameters.
@@ -1266,7 +1269,7 @@ It is a static error to export any other kind of binding from the top level.
## Include files
Compact allows programs and modules to be split into multiple files and spliced
-togther via `include` forms, which have the following syntax, where `file` is a
+together via `include` forms, which have the following syntax, where `file` is a
string literal specifying a filesystem pathname for file to be included:
@@ -1439,7 +1442,7 @@ is created to minimize the chance of the transaction being rejected when the
proof is checked on chain.
For example, `Counter` increment and decrement do not commit to the current value
of the counter.
-While the preceding example could be written a Cell instead:
+While the preceding example could be written using a Cell instead:
```compact
ledger F: Uint<64>;
@@ -1483,10 +1486,14 @@ export circuit initNestedCounter(b: Boolean, n: Field): [] {
fld.lookup(b).insert(disclose(n), default);
}
-export circuit incrementNestedCounter(b: Boolean, n: Field, k: Uint<16>): [] {
+export circuit incrementNestedCounter1(b: Boolean, n: Field, k: Uint<16>): [] {
fld.lookup(b).lookup(n).increment(disclose(k));
}
+export circuit incrementNestedCounter2(b: Boolean, n: Field, k: Uint<16>): [] {
+ fld.lookup(b).lookup(n) += disclose(k);
+}
+
export circuit readNestedCounter1(b: Boolean, n: Field): Uint<64> {
return fld.lookup(b).lookup(n).read();
}
@@ -1500,7 +1507,8 @@ In this example,
- `fld` is bound to a `Map` from `Boolean` values to `Map`s from `Field` values to `Counter`s
- `initNestedMap` can be used to create the inner `Map` for a particular outer-`Map` key
- `initNestedCounter` can be used to create a `Counter` for a given outer-`Map` key and a given inner-`Map` key
-- `incrementNestedCounter` can be used to increment an existing `Counter` for a given outer-`Map` key and a given inner-`Map` key
+- either `incrementNestedCounter1` or `incrementNestedCounter2` can be used to increment
+ an existing `Counter` for a given outer-`Map` key and a given inner-`Map` key
- either `readNestedCounter1` or `readNestedCounter2` can be used to read the value of an existing `Counter`
for a given outer-`Map` key and a given inner-`Map` key.
@@ -1520,11 +1528,16 @@ Notes:
fld.lookup(b); // ERROR: incomplete chain of indirects
}
```
-4. When the last lookup is a read of a base type one can omit the
- explicit `read()` indirect, as illustrated by the definitions of
- `readNestedCounter1` and `readNestedCounter2` above, which have the
+4. When the last operation is a write of a base type, increment of a Counter type,
+ or decrement of a Counter type, one can replace the `write`, `increment`, or
+ `decrement` operation with the `=`, `+=`, or `-=` assignment syntax, as
+ illustrated by `incrementNestedCounter1` and `incrementNestedCounter2`,
+ which have the same behavior.
+5. When the last operation is a read of a Counter or base type one can omit the
+ explicit `read()` indirect, as illustrated by
+ `readNestedCounter1` and `readNestedCounter2`, which have the
same behavior.
-5. For convenience, local variables can hold default values of ledger-state types,
+6. For convenience, local variables can hold default values of ledger-state types,
so the following definition of `initNestedMap` is equivalent to the one
above.
```compact
@@ -1607,15 +1620,15 @@ constructor(v: Field) {
Each constructor parameter must be explicitly typed.
The type of each variable binding arising from the binding of identifiers in
each parameter pattern to the corresponding pieces of the input is the type of
-the corresonding part of the declared type's structure.
+the corresponding part of the declared type's structure.
The return type of the constructor is always `[]`.
-Any attempt to return another type of value using `return expression;` where the
-type of `expression` is something other than `[]`, is a static error.
+Any attempt to return another type of value using `return` *expr*`;` where the
+type of *expr* is something other than `[]`, is a static error.
## Circuit definitions
-The basic operational element in Compact is the `circuit`.
+The basic operational element in Compact is the *circuit*.
This corresponds closely to a function in most languages but is designed
to be compilable into a zero-knowledge circuit.
The key limitation of circuits relative to functions in most languages is
@@ -1634,7 +1647,7 @@ Named circuit definitions have the following syntax:
-A circuit definition binds `function-name` to a circuit with the given parameters,
+A circuit definition binds *function-name* to a circuit with the given parameters,
type, and body.
The optional `export` modifier indicates that the circuit binding should
be exported from the enclosing module or the program itself, if the circuit
@@ -1642,7 +1655,7 @@ is defined outside of any module.
The optional `pure` modifier indicates that the
[circuit is pure](#pure-and-impure-circuits).
-If any generic parameters are present (`gparams` is present and is nonempty),
+If any generic parameters are present (*gparams* is present and is nonempty),
the circuit is [generic][#generic-parameters-and-arguments] and must be specialized
(provided with generic arguments) at the point of call.
@@ -1652,13 +1665,13 @@ to be bound to selected pieces of the argument values.
In the simplest case, a pattern is just an identifier and is bound to the argument
value as a whole.
The bindings established by the parameters are visible within (and only within)
-the `block` that constitutes the body of the circuit.
+the *block* that constitutes the body of the circuit.
Each parameter must be explicitly typed, and at the point of every call to the
circuit, the type of the corresponding argument expression must be a subtype of
that type.
The type of each variable binding arising from the binding of identifiers in
each parameter pattern to the corresponding pieces of the input is the type of
-the corresonding part of the declared type's structure.
+the corresponding part of the declared type's structure.
For example, in the body of `sumStruct` below:
```compact
@@ -1675,7 +1688,7 @@ Every named circuit's return type must be explicitly declared, and it is a
static error if the circuit can return a value that is not a subtype of that
type.
-The body is evaluated each time the circuit it is called.
+The body is evaluated each time the circuit is called.
### Pure and impure circuits
@@ -1706,7 +1719,7 @@ Compact program by the Compact compiler.
## Blocks
-A `block` is a group of statements enclosed in braces:
+A *block* is a group of statements enclosed in braces:
| | | |
@@ -1717,14 +1730,14 @@ A `block` is a group of statements enclosed in braces:
A block can be used in place of a single statement anywhere a single statement
is allowed, which is useful for allowing multiple statements to be evaluated by the
-`then` and `else` parts of an `if` statement or the body of a `for`.
+"then" and "else" parts of an `if` statement or the body of a `for` statement.
The body of every circuit definition and the body of the constructor, if any,
is always a block.
The right-hand side of the arrow in an anonymous circuit can be either a block
or an expression.
-The statements within a block occupy a nested scope: `const` bindings created by
+The statements within a block occupy a nested scope: variable bindings created by
`const` statements within the block are not visible outside the block, and they can
shadow identifier bindings with the same names that exist outside the block.
@@ -1753,42 +1766,39 @@ The syntax of Compact statements is summarized by the following grammar snippet:
The snippet shows that a statement (`stmt`) is either a one-armed `if` expression
-or some other kinf of statement (`stmt0`).
-This structure is used to enforce the restriction that the *then* part of a
+or some other kind of statement (`stmt0`).
+This structure is used to enforce the restriction that the "then" part of a
two-armed cannot be a one-armed `if` expression.
-This is often left ambiguous in the grammar, with a separate note to say
-that the ambiguity is resolved by assocating an *else* part with the closest
+This is often left ambiguous in a language grammar, with a separate note to say
+that the ambiguity is resolved by associating each "else" part with the closest
enclosing `if` expression, but we prefer to make the constraint explicit in
the grammar and avoid any ambiguity.
The first kind of `stmt0` is `expr-seq`.
An `expr-seq`, or *expression sequence*, is a comma separated sequence of one
or more expressions to be evaluated in sequence.
-This simply means that any expression or comma-separated sequence also qualifies
-as a statement.
+This simply means that any expression or comma-separated sequence of expressions
+also qualifies as a statement.
Expression sequences are described more fully in
-(their own section)[expression-sequences].
+[their own section](#expression-sequences).
The remaining subsections of this section describe each of the other kinds of
-statement.
+statements.
Statements either do not have a value or (in the case of expression sequences
-serving as statements) their value is ignored.
+serving as statements) the type and value are ignored.
Thus it is not necessary to talk about the type of a statement.
Nevertheless, each statement has typing rules that must be followed, such as that
-the type of the test expression of an `if` expression must be `Boolean`.
+the type of the test expression of an `if` statement must be `Boolean`.
### `const` statements
`const` statements create local variable bindings.
Every `const` statement takes the following form:
-```compact
-const cbindings
-```
+`const` *cbinding* `,` ⋯¹ `,` *cbinding* `;`
-where `cbindings` is a comma-separated sequence of one or more `cbinding` subforms
-in the syntax specified by the following grammar snippet:
+where each *cbinding* takes the following form:
| | | |
@@ -1799,18 +1809,18 @@ in the syntax specified by the following grammar snippet:
-A `const` statement is typed by typing each of its `cbinding` subforms.
-A `cbinding` subform is typed by typing the expression on the right-hand side
+A `const` statement is typed by typing each of its *cbinding* subforms.
+A *cbinding* subform is typed by typing the expression on the right-hand side
of the `=`.
-If a type `T` is included on the left-hand side, the type of the expression
-must be a subtype of `T`, otherwise it is a static error.
+If a type *T* is declared on the left-hand side, the type of the expression
+must be a subtype of *T*, otherwise it is a static error.
It is also a static error if the pattern implies a different structure from
the type of the expression.
For example, it is a static error if the pattern implies that the expression's
value is a tuple when the type is actually, say, `Field`.
The type of each variable binding arising from the binding of identifiers in each
-pattern to the corresponding pieces of the input is the type of the corresonding
+pattern to the corresponding pieces of the input is the type of the corresponding
part of the structure of the declared type, if present, otherwise of the inferred
type.
For example, in the following code, the binding for `x` has type `Boolean`, and
@@ -1850,7 +1860,7 @@ circuit foo(a: Uint<16>): Field {
}
```
-Similarly, the reference to `x` in the first `cbinding` of the `const`
+Similarly, the reference to `x` in the first *cbinding* of the `const`
statement below is also a static error.
```compact
@@ -1858,57 +1868,49 @@ const y = x, x = 7;
}
```
-A `const` statement is evaluated by evaluating the `cbinding` subforms in order
-so that the variables given values by each `cbinding` is available to the
-cbindings that follow.
+A `const` statement is evaluated by evaluating the *cbinding* subforms in order
+so that the variables given values by each *cbinding* are available to be
+referenced by the cbindings that follow.
-The evaluation of each `cbinding` involves evaluating the expression
-on the right-hand side of the `=` and then giving values to identifiers
-in the pattern `p` on the left-hand side to the value `v` of the
-expression as described earlier in
-(Patterns and destructuring)[patterns-and-destructuring].
+The evaluation of each *cbinding* involves determining the value *v* of the
+expression on the right-hand side of the `=`, then giving values to identifiers
+in the pattern *p* on the left-hand side to the corresponding pieces of *v*
+as described earlier in [Patterns and destructuring](#patterns-and-destructuring).
Any variable bound by `const` may not be reused within a block, although a
`const` binding in a nested block might [shadow it](#identifiers-bindings-and-scope).
Variables are immutable, although the same variable might take on different values
-at different times if is contined within a block of code that is evaluated more
-than once, such as would be the case for the body of a `circuit` that is called
+at different times if is contained within a block of code that is evaluated more
+than once, such as would be the case for the body of a circuit that is called
more than once.
### `if` statements
An `if` statement is used to determine the flow of control through the
statements of a circuit or constructor body.
-A *one-armed* `if` expression has a *test part* (an `expr-seq` enclosed
-in parentheses) and a *then part* (`then-statement`):
+A *one-armed* `if` expression has a "test part" (an *expr-seq* enclosed
+in parentheses) and a "then part" (*then-statement*):
-```compact
-if (expr-seq) then-statement
-```
+`if (`*expr-seq*`)` *then-statement*
-A *two-armed* `if` expression has a *test part* (an `expr-seq` enclosed
-in parentheses), a *then part* (`then-statement`), and an *else part*
-(`else-statement`):
+A *two-armed* `if` statement has a test part, a then part, and an "else part"
+(*else-statement*):
-```compact
-if (expr-seq)
- then-statement
-else
- else-statement
-```
+`if (`*expr-seq*`)` *then-statement* `else` *else-statement*
-The typing of an `if` expression requires only that the type of `expr-seq` must be
+The typing of an `if` statement requires only that the type of *expr-seq* must be
`Boolean`.
-Evaluating an `if` expression involves first evaluating the `expr-seq`.
-If it evaluates to `true`, `then-statement` is evaluated.
-Otherwise, it must evaluate to `false`, in which case `else-statement`
+Evaluating an `if` expression involves first determining the value *v* of
+*expr-seq*.
+If *v* is `true`, *then-statement* is evaluated.
+Otherwise, *v* must be `false`, in which case *else-statement*
(if present), is evaluated.
### `for` statements
`for` statements are used to iterate over a sequence of values.
-In Compact, in constrast to most languages, the number of iterations can
+In Compact, in contrast to most languages, the number of iterations can
always be determined at compile time.
That is, the number of iterations is bounded either by constant numeric
bounds or by size of an object of constant size.
@@ -1919,60 +1921,53 @@ Compact supports two kinds of `for` statements.
The first iterates over vectors, tuples, and byte-vectors and takes the
following form:
-```compact
-for (const x of expression) statement
-```
+`for (const` *x* `of` *expr*`)` *stmt*
-This kind of `for` statement is typed by typing `expression` and verifying that
-it is a `Vector` type, a tuple type that (has a vector type)[Subtyping and least
-upper bounds], or a `Bytes` type.
+This kind of `for` statement is typed by typing *expr* and verifying that
+it is a `Vector` type, a tuple type that
+[has a vector type](#subtyping-and-least-upper-bounds), or a `Bytes` type.
-Evaluating this kind of `for` requires evaluating `expression` then evaluating
-`statement` once for each element with `x` bound to the value of each element
-in turn.
+Evaluating this kind of `for` requires determining the vector, tuple, or
+byte-vector value *v* of *expr* then evaluating
+*stmt* once for each element of *v* with *x* bound to the value of each element
+of *v* in turn.
The second form iterates over a range of unsigned integer values and takes the
following form:
-```compact
-for (const i of start..end) statement
-```
+`for (const` *i* `of` *start* `..` *end*`)` *stmt*
-In this form, each of `start` and `end` must be a literal unsigned integer
-or a generic natural-number parameter, and `end` must be greater than or
-equal to `start`.
+In this form, each of *start* and *end* must be a literal unsigned integer
+or reference to a generic natural-number parameter, and *end* must be
+greater than or equal to *start*.
Otherwise, it is a static error.
This form is always well-typed.
-Evaluating this kind of `for` requires evaluating statement with `i` bound
-to *k* for each *k* in the range `start` (inclusive) to `end` (exclusive).
+Evaluating this kind of `for` requires evaluating *stmt* with *i* bound
+to *k* for each *k* in the range *start* (inclusive) to *end* (exclusive).
`return` statements cannot be used to return from within `for` statements.
-It is therefore a static error for `statement` to be a `return` statement
-or for a `return` statement to appear within `statement` (except where it
-appears nested within an anoymous circuit).
+It is therefore a static error for *stmt* to be a `return` statement
+or for a `return` statement to appear within *stmt* (except where it
+appears nested within an anonymous circuit).
Iteration can also be accomplished via
-(`map` and `fold` expressions)[map-and-fold-expressions].
+[`map` and `fold` expressions](#map-and-fold-expressions).
### `return` statements
A `return` statement can be used to exit from the closest enclosing
-[anonymous circuit](#circuit-and-witness-calls) circuit, if any, or otherwise from
+[anonymous circuit](#circuit-and-witness-calls), if any, or otherwise from
the enclosing constructor or named circuit, and to return to the caller either
-an explicit return value, i.e., the value of (`expr-seq`)[expression-sequences]
+an explicit return value, i.e., the value of [`expr-seq`](#expression-sequences)
in this form of `return`:
-```compact
-return expr-seq;
-```
+`return` *expr-seq*`;`
or the default value `[]` in this form of `return`:
-```compact
-return;
-```
+`return;`
A circuit or constructor body can also exit without an explicit `return` statement:
any path through the body that does not end in an explicit `return` statement is
@@ -1980,8 +1975,8 @@ treated as if ended with `return;`.
A `return` statement is always well-typed if it exits from an anonymous circuit
without a declared return type.
-Otherwise, a `return` statement is well-typed if the type of `expr-seq`, or
-`[]` if no `expr-seq` is present, is a subtype the expected return type.
+Otherwise, a `return` statement is well-typed if the type of *expr-seq*, or
+`[]` if no *expr-seq* is present, is a subtype the expected return type.
If the `return` form exits from a named circuit or an anonymous circuit
with a declared return type, the expected type is the declared return type,
while if it exits from the constructor, the expected return type is `[]`.
@@ -1989,10 +1984,10 @@ while if it exits from the constructor, the expected return type is `[]`.
An implication of these rules is that it is a static error to exit without an
explicit return value from a circuit with a declared return type other than `[]`.
-When a `return` statement is evaluated, the `expr-seq`, if present, is evaluated,
+When a `return` statement is evaluated, the *expr-seq*, if present, is evaluated,
the circuit or constructor exits immediately without evaluating any
-subsequent statements, and it returns to the caller the value of `expr-seq` or
-`[]` if no `expr-seq` is present.
+subsequent statements, and it returns to the caller the value of *expr-seq* or
+`[]` if no *expr-seq* is present.
## Expressions
@@ -2067,51 +2062,51 @@ error: the Compact compiler reports the error and does not produce any target co
The static type of a well-typed expression is either a Compact type or a
ledger-state type.
-Every Compact expression either evaluates to a value or raises an exception,
-and it might have have an effect.
+Every well-typed Compact expression either evaluates to a value or causes a
+dynamic error, and it might have effects.
The evaluation of an expression is defined in terms of the evaluation of its
subexpressions.
-If the evaluation of a subexpression raises an exception, then the evaluation of
-the containing expression halts and raises the same exception.
The first section below discusses how the grammar reflects the rules
for precedence and associativity of operators, and the remaining sections
describe the typing and evaluation rules for each kind of expression.
-
### Precedence and associativity
The structure of the expression grammar unambiguously reflects the precedence
and associativity of operators.
-Each subscripted nonterminal `expr_n` represents a precedence level, with higher
-subscripts representing higher levels of precedence.
-For example, `expr_6` (multiplication) binds more tightly than `expr_5` (addition)
-because the grammar permits the operands of an addition expression to be
-multiplication expressions, but not vice versa.
+Each group from *expr-seq* through *term* represents a precedence level,
+with *expr-seq* at a higher precedence level than *expr*, *expr* at a higher level
+than *expr
0*, and so on.
+For example, *expr
6* (multiplication) is at a higher precedence level
+and so binds more tightly than *expr
5* (addition) because the grammar
+permits the operands of an addition expression to be multiplication expressions,
+but not vice versa.
For example, `x * y + z` is parsed as the addition of `x * y` and `z`
-rather than the multiplication of `x` and `y + z`, because the `expr_5` production
-for addition is not reachable from the `expr_6` production for multiplication.
-One can still write `x * (y + z)` because an `expr_6` can be a `term` (via the
-"fall through" productions `expr_6 → expr_7`, `expr_7 → expr_8`, and so on),
-and a term can be a parenthesized `expr-seq`.
-
-The grammar enforces associativity by allowing either the left or right
-operand of an operator to be at the same precedence level while requiring
-the other to be at a higher level.
-Specifically, left-associativity is expressed by allowing the left operand to be
-at the same level while requring the right operand to be at a higher level.
-For instance, `expr_5 → expr_5 + expr_6` enforces the left-associativity of
-addition, since the left operand can be at the same level while the right
-operand is at a higher level.
-This means that `x + y - z` can be treated only as the subtraction of `z`
+rather than the multiplication of `x` and `y + z`, because the *expr
5*
+production for addition is not reachable from the *expr
6* production
+for multiplication.
+One can still write `x * (y + z)` because an *expr
6* can be a *term* (via the
+"fall through" productions *expr
6* ⟶ *expr
7*,
+*expr
7* ⟶ *expr
8*, and so on),
+a *term* can be a parenthesized *expr-seq*, and an *expr-seq* can be an *expr*.
+
+The grammar enforces associativity by requiring the left or right
+operand of an operator or both to be at a higher precedence level.
+Specifically, left-associativity is expressed by requiring the right operand to
+be at a higher level while allowing the left operand to be at the same level.
+For instance, *expr
5* ⟶ *expr
5* `+` *expr
6*
+enforces the left-associativity of addition, since the left operand must be at
+a higher level.
+This means, for example, that `x + y - z` can be treated only as the subtraction of `z`
from `x + y` rather than as the addition of `x` and `y - z`.
Right-associativity is expressed in the opposite manner, e.g.,
-`expr_0 ? expr : expr` enforces the right-associativity of the
+*expr
0* `?` *expr* `:` *expr* enforces the right-associativity of the
ternary `?:` operator.
-Non-associative operators such as the relational operators `<`, `<=`, `>=`, `>` have
-both operands at a strictly higher level (`expr_4` on both sides of `expr_3`),
-preventing chaining like `a < b < c`.
+Non-associative operators such as the relational operators `<`, `<=`, `>=`, and
+`>` require both operands to be at a strictly higher level (*expr
4*
+on both sides of *expr
3*), preventing chaining like `a < b < c`.
The middle operand of the ternary `?:` operator plays no roll in determining
precedence and associativity and can be any kind of expression.
@@ -2124,37 +2119,34 @@ expression where it can be confused as an operand of some other operator.
### Parenthesized expressions
-Compact allows parenthesized expressions of the form `(e)`, where `e` is an
-expression.
-They can be used to control the order of operations or simply to make the default
-order of operations to be explicit.
+Compact allows parenthesized expressions of the form `(`*e*`)`, where
+*e* is an expression or, more generally, an expression sequence.
+Parenthesized expressions can be used to control the order of operations or simply
+to make the default order of operations explicit.
For example, `x + y * z` computes the product of `y` and `z` and adds `x` to the
result, because `*` has higher precedence than `+`.
`x + (y * z)` computes the same thing but more makes the order of operations more
clear, while `(x + y) * z` computes the sum of `x` and `y` and multiplies it by `z`.
-The type of a parenthesized expression is the type of the embedded expression,
-and its value is the value of the subexpression.
+The type of a parenthesized expression is the type of the embedded expression
+sequence, and its value is the value of the subexpression.
### Expression sequences
-An expression sequence (`expr-seq` in the grammar above) is a comma-separated
+An expression sequence (*expr-seq* in the grammar above) is a comma-separated
sequence of one or more expressions.
-```compact
-expression, ⋯, expression
-```
+*expr*`,` ⋯`,` *expr*
Expression sequences can appear only in a few contexts.
When an expression sequence is required in a context where only a single expression
is permitted, the expression sequence can be wrapped in parentheses:
-```compact
-(expression, ⋯, expression)
-```
+`(`*expr*`,` ⋯`,` *expr*`)`
The type of an expression sequence is the type of its last subexpression.
+The types of the other subexpressions are ignored and are not constrained in any way.
An expression sequence is evaluated by evaluating the subexpressions from
left to right, and its value is the value of the last subexpression.
@@ -2205,18 +2197,18 @@ circuit foo(): Uint<16> {
This is treated exactly as if the numeric literal appeared in place of the
reference to `N` in the source code of the program.
-It is a static error if the number `n` denoted by a numeric literal exceeds the
+It is a static error if the number *n* denoted by a numeric literal exceeds the
maximum unsigned value and the maximum field value.
-If `n` does not exceed the maximum representable unsigned value, the literal's
-type is `Uint<0..k>`, `k = n + 1`, and its value is the unsigned integer `n`.
+If *n* does not exceed the maximum representable unsigned value, the literal's
+type is `Uint<0..`*k*`>`, *k* `=` *n*+1, and its value is the unsigned integer *n*.
-If `n` exceeds the maximum representable unsigned value but not the
+If *n* exceeds the maximum representable unsigned value but not the
maximum representable field value, the literal must be directly cast to
-`Field`, i.e., `
as Field`.
+`Field`, i.e., *n* `as Field`.
Otherwise it is a static error.
-The type of ` as Field` is `Field`, and its value is the
-field value `n`.
+The type of *n* `as Field` is `Field`, and its value is the
+field value *n*.
__String literals__ can be either simple string literals or `pad` expressions.
String literals produce byte vectors; Compact has no dedicated String type.
@@ -2224,53 +2216,46 @@ String literals produce byte vectors; Compact has no dedicated String type.
Simple string literals use TypeScript string literal syntax.
They can be enclosed in either single (`'`) or double (`"`) quotes, and they can
contain escaped characters.
-The length `n` of a simple string literal is the length of its UTF-8 encoding.
-The static type of a string literal is `Bytes`, and its value is a
-byte vector containing its UTF-8 encoding.
+The length *n* of a simple string literal is the length of its UTF-8 encoding.
+The static type of a string literal of length *n* is `Bytes<`*n*`>`, and its
+value is a byte vector containing its UTF-8 encoding.
-A `pad` expression `pad(n, s)` is also a string literal, where `pad` is a reserved
-word, `n` is a natural number literal, and `s` is a simple string literal whose
-length must be less than or equal to `n`.
-The static type of a padded string literal `pad(n, s)` is `Bytes`, and its
-value is a byte vector containing the UTF-8 encoding of `s` followed by `0`
-bytes up to the padded length `n`.
+A `pad` expression `pad(`*n*`,` *s*`)` is also a string literal, where `pad` is a reserved
+word, *n* is a natural number literal, and *s* is a simple string literal whose
+length must be less than or equal to *n*.
+The static type of a padded string literal `pad(`*n*`,` *s*`)` is `Bytes<`*n*`>`, and its
+value is a byte vector containing the UTF-8 encoding of *s* followed by `0`
+bytes up to the padded length *n*.
### Default values of a type
-Every Compact type and ledger-state type has a default value.
-
-The expression `default`, where `T` is a Compact type or a ledger-state type,
-has static type `T`. It evaluates to the default value of that type.
-
-Note that default value expressions can have ledger-state types.
-
-Every type in Compact has a *default value* of that type. The default values
-are as follows:
+The expression `default<`*T*`>`, where *T* is a Compact type or a ledger-state type,
+has static type *T* and evaluates to the default value of that type as follows:
- `Boolean`: the value of the literal `false`
-- `Uint<0..n>` and `Uint`: `0`
+- `Uint<0..`*n*`>` and `Uint<`*n*`>`: `0`
- `Field`: `0`
-- `[T, `⋯`]` where `T`, ⋯ is a sequence of zero or more types: the tuple with
- the corresponding length, each of the default value of the corresponding type
-- `Bytes`: the byte vector of length `n` with all zero bytes
-- `Opaque<"string">`: an empty string, i.e., `""`
-- `Opaque<"Uint8Array">`: a zero-length `Uint8Array`, i.e., `new Uint8Array(0)`
-- structure types: the struct with all fields set to the default value of their
- type
-- enumeration types: the first value listed in the declaration
+- `[`*T1*`, `⋯`, `*Tn*`]`: a tuple with *n* elements,
+ each of which is the default value of the corresponding type *Ti*
+- `Vector<`*n*`, `*T*`>`: a vector with *n* elements, each of which is
+ the default value of type *T*.
+- `Bytes<`*n*`>`: a byte vector of length *n*, each element of which is `0`.
+- `Opaque<"string">`: a zero-length string
+- `Opaque<"Uint8Array">`: a zero-length `Uint8Array`
+- Structure types: a struct with each element set to the default value of its type
+- Enumeration types: the value of *E*`.`*id* where *E* is the name of the enumeration
+ type and *id* is the first element
- alias types: the default value of the underlying type
-- `Counter`: `0`
-- `Set`, for any Compact type `T`: an empty set
-- `Map`, for any Compact types `K` and `T`: an empty map
-- `Map`, for any Compact type `K` and ledger-state type `V`: an empty map
-- `List`, for any Compact type `T`: an empty list
-- `MerkleTree`, for a compile time integer `1 < n <= 32`, and any Compact
- type `T`: an empty Merkle tree
-- `HistoricMerkleTree`, for a compile time integer `1 < n <= 32`, and any
- Compact type `T`: an empty Merkle tree
+- `Counter`: a Counter initialized to `0`
+- `Set<`*T*`>`: an empty Set
+- `Map<`*K*`, `*T*`>`: an empty Map
+- `List<`*T*`>`: an empty List
+- `MerkleTree<`*n*`, `*T*`>`: an empty Merkle tree
+- `HistoricMerkleTree<`*n*`, `*T*`>`: an empty historic Merkle tree
-Default is not ddefined for contract types and `Kernel` type (which is defined
-in `CompactStandardLibrary`).
+Default values are not defined for contract types or the `CompactStandardLibrary`
+`Kernel` type, so it is a static error if *T* in `default<`*T*`>` is one of
+these types.
### Variable references
@@ -2282,88 +2267,99 @@ Each call to a circuit (or constructor) associates a new set of values with each
variable bound by the circuit's (or constructor's) parameters, and each block
in the circuit (or constructor) associates a new set of values with each of the
`const` bindings created within the block.
-The value of each variable reference is the value associated with the variable
-by the current activation.
+The value of each variable reference is the value currently associated with the
+variable.
### Conditional expressions
-Compact supports conditional expressions of the form `e0 ? e1 : e2` where `e0`,
-`e1`, and `e2` are expressions.
+Compact supports conditional expressions of the form
-Conditional expressions require the type of `e0` to be `Boolean`. The types of
-`e1` and `e2` must be in the subtype relation. That is, the type of
-`e1` is a subtype of the type of `e2` or the type of `e2` is a subtype of
-the type of `e1`.
+*e0* `?` *e1* `:` *e2*
-The type of the entire expression is the type of `e2` if `e1` is a subtype of
-`e2` and the type of `e1` if `e2` is a subtype of `e1`.
+where *e0*, *e1*, and *e2* are expressions.
-Conditional expressions are evaluated by first evaluating `e0`. Then, the
-value of that expression determines which of the other subexpressions is
+The type of *e0* must be `Boolean`.
+The types of *e1* and *e2* must be related.
+That is, the type of *e1* must be a subtype of the type of *e2*,
+or the type of *e2* must be a subtype of the type of *e1*.
+
+The type of the entire expression is the type of *e2* if *e1*
+is a subtype of *e2* and the type of *e1* if *e2*
+is a subtype of *e1*.
+
+Conditional expressions are evaluated by first evaluating *e0*.
+The value *v* of that expression determines which of the other subexpressions is
evaluated:
-- if the value of `e0` is `true`, then `e1` is evaluated and its value is the
+- if *v* is `true`, then *e1* is evaluated and its value is the
value of the entire expression
-- if the value of `e0` is `false`, then `e2` is evaluated and its value is the
+- if *v* is `false`, then *e2* is evaluated and its value is the
value of the entire expression
-The evaluation rules ensure that only one of `e1` and `e2` is evaluated.
+The evaluation rules ensure that only one of *e1* and *e2*
+is evaluated.
### Relational comparison expressions
-Relational comparison expressions are of the form `e0 op e1` where `e0`
-and `e1` are expressions and `op` is one of Compact's relational operators.
+Relational comparison expressions take the form *e0* `op` *e1*
+where *e0* and *e1* are expressions and `op` is one of
+Compact's relational operators.
The relational operators are **equals** (`==`), **not equals** (`!=`), **less
than** (`<`), **greater than** (`>`), **less than or equals** (`<=`), and
**greater than or equals** (`>=`).
-Equals and not equals require the types of the subexpressions to be in the
-subtype relation.
-That is, the type of the first subexpression must be a subtype of the type of
-the second subexpression, or the type of the second subexpression must be
-a subtype of the type of the first subexpression.
+Equals and not equals require the types of *e1* and *e2*
+to be related.
+That is, the type of *e1* must be a subtype of the type of *e2*,
+or the type of *e2* must be a subtype of the type of *e1*.
Less than, greater than, less than or equals, and greater than or equals require
-the type of both subexpressions to be unsigned integer types. (Values of type
-`Field` cannot be compared with these operators.)
+the types of *e1* and *e2* to be unsigned integer types.
+(Values of type `Field` cannot be compared with these operators.)
The type of the result is `Boolean`.
-Relational comparison expressions are evaluated by evaluating the subexpressions
-in order from left to right.
-Then the comparison is performed as described below.
+A relational comparison expression *e0* `op` *e1* is
+evaluated by evaluating *e0*, then evaluating *e1*, then
+comparing the resulting values as described below.
**Equals and not equals**
Equality depends on the types of the operands according to the following rules.
-The rules implicitly do not and need not cover cases where one operand is not a
-subtype of the other.
+The rules need not and therefore do not cover cases where one operand is not a subtype of
+the other.
For example, if one operand has type `Boolean`, so does the other; if one
operand has a `Bytes` type of length `n`, so does the other; and if one
has a specific structure type, so does the other.
- **`Boolean` == `Boolean`:**
- The values are equal if both are `true` or both are `false`.
+ the values are equal if both are `true` or both are `false`.
- **`Uint` or `Field` == `Uint` or `Field`:**
- The values are equal if the integer values are equal.
-- **`Bytes`**
- The values are equal if the corresponding bytes at each index are equal.
+ the values are equal if the integer values are equal.
+- **`Bytes`:**
+ the values are equal if the corresponding bytes at each index are equal.
- **`Tuple` and `Vector`:**
- The values are equal if the corresponding values at each index are equal.
+ the values are equal if the corresponding values at each index are equal.
- **Structure types:**
- The values are equal if the corresponding members are equal.
+ the values are equal if the corresponding members are equal.
- **Enumeration types:**
- The values are equal if they are the same enumeration member.
+ the values are equal if they are the same enumeration member.
- **`Opaque types:`**
- The values are equal if the runtime values are equal according to JavaScript's
- strict equalty (`===`) operator.
+ the values are equal if the runtime values are equal according to JavaScript's
+ strict equality (`===`) operator.
+
+Otherwise the values are not equal.
-Otherwise the operands are not equal.
+For *equal*, the relational comparison expression evaluates to `true` if the
+values are equal; otherwise it evaluates to `false`.
+Likewise, for *not equals*, the relational comparison expression evaluates to
+`false` if the values are equal; otherwise it evaluates to `true`.
**Less than, greater than, less than or equals, and greater than or equals**
-The unsigned integer values of the operands are compared according to the
-corredponding relational operation.
+The values are compared according to the corresponding relational operation.
+The relational comparison expression evaluates to `true` if the relation holds;
+otherwise it evaluates to `false`.
### Short-circuit logical expressions
@@ -2468,7 +2464,7 @@ circuit foo(x: Feet, y: Feet, scale: Uint<32>): Feet {
}
```
-computes the sum of `x` and `y` multipled by `scale`.
+computes the sum of `x` and `y` multiplied by `scale`.
If the value of this computation fits in 32 bits, `foo` returns the value.
Otherwise, the enclosing top-level circuit or constructor halts with a
message indicating that the cast of the value to `Feet` failed.
@@ -2827,9 +2823,9 @@ Type checking a function call depends on the form of the underlying function.
- If there is no type annotation for a parameter, the parameter's type is
inferred as the type of the corresponding argument expression.
- Within the body of the anoymous circuit, the type of each variable binding arising
+ Within the body of the anonymous circuit, the type of each variable binding arising
from the binding of identifiers in each parameter pattern to the corresponding
- pieces of the corresponding argument is the type of the corresonding part of
+ pieces of the corresponding argument is the type of the corresponding part of
the structure of the declared or inferred parameter type.
If there is a return type annotation, it is a static error if the body can
@@ -2961,7 +2957,7 @@ Any cast not covered by one of the rules is not allowed.
#### Upcasts
-- Upcasts, i.e., casts from a type to a (supertype)[subtyping-and-least-upper-bounds]
+- Upcasts, i.e., casts from a type to a [supertype](#subtyping-and-least-upper-bounds)
(e.g., from `Vector<3, Uint<8>>` to `Vector<3, Uint<16>>`), are always allowed
(but never required), never result in run-time errors, and, except in the case
where the type and the supertype are the same, might require run-time conversions.
@@ -3157,12 +3153,12 @@ is the exception.
The mechanism for explicitly declaring disclosure is simple: disclosure of private
data (exported circuit arguments, witness return values, and anything derived from
private data) must be acknowledged by wrapping an expression whose value contains
-private data in a `disclose()` wrapper before storing it in the public state, returing
+private data in a `disclose()` wrapper before storing it in the public state, returning
it from an exported circuit, or using it in conditional expressions that might
affect what is stored in the public state or or returned from an exported circuit.
-For example, the following contract attempts to disclose privata data without
-explictly declaring the disclosure when it stores the value of the exported
+For example, the following contract attempts to disclose private data without
+explicitly declaring the disclosure when it stores the value of the exported
parameter `x` into the ledger field `F`:
```compact
From 962e8c20567c0b43063bed13d1efbe7d62e7473c Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Sun, 15 Mar 2026 22:10:51 +0100
Subject: [PATCH 20/41] latest lang-ref.mdx
---
docs/compact/reference/lang-ref.mdx | 512 ++++++++++++++--------------
1 file changed, 261 insertions(+), 251 deletions(-)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index 93658949..84ba297c 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -537,7 +537,7 @@ struct NumberAnd {
```
The first declaration introduces a structure type named `Thing` with two fields:
-`triple` (a vector with 3 field elements) and `flag` (a Boolean).
+`triple` (a vector with three `Field` elements) and `flag` (a Boolean).
The second introduces a *generic* structure type named `NumberAnd` with generic
parameter `T` and two fields: `num` (a 32-bit unsigned integer) and `item`
(a value of type `T`).
@@ -616,7 +616,7 @@ export circuit doesntWork(s: Even): Odd {
Values of structure types are created with
[**structure-creation** expressions](#structure-creation)
and accessed via
-[**structure-member-access** expressions](#structure-member-access).
+[**structure-field-access** expressions](#structure-field-access).
#### Enumeration types
@@ -1514,38 +1514,38 @@ In this example,
Notes:
-1. Nesting is permitted only within `Map` values. That is, nesting is not permitted in
- `Map` keys or within any ledger-state type other than `Map`.
-2. Nested values must be initialized before first use. The syntax `default`
- is used to create default ledger-state type values, just as it can be used to
- create default Compact type values.
-3. Ledger state type values are not first-class objects, so when
- accessing a nested value, the entire indirection chain must be
- used. For example, the following results in a compiler error:
-
- ```compact
- export circuit incrementNestedCounter(b: Boolean, n: Field, k: Uint<16>): [] {
- fld.lookup(b); // ERROR: incomplete chain of indirects
- }
- ```
-4. When the last operation is a write of a base type, increment of a Counter type,
- or decrement of a Counter type, one can replace the `write`, `increment`, or
- `decrement` operation with the `=`, `+=`, or `-=` assignment syntax, as
- illustrated by `incrementNestedCounter1` and `incrementNestedCounter2`,
- which have the same behavior.
-5. When the last operation is a read of a Counter or base type one can omit the
- explicit `read()` indirect, as illustrated by
- `readNestedCounter1` and `readNestedCounter2`, which have the
- same behavior.
-6. For convenience, local variables can hold default values of ledger-state types,
- so the following definition of `initNestedMap` is equivalent to the one
- above.
- ```compact
- export circuit initNestedMap(b: Boolean): [] {
- const t = default
-The snippet shows that a statement (`stmt`) is either a one-armed `if` expression
-or some other kind of statement (`stmt0`).
+The snippet shows that a statement (*stmt*) is either a one-armed `if` expression
+or some other kind of statement (*stmt
0*).
This structure is used to enforce the restriction that the "then" part of a
two-armed cannot be a one-armed `if` expression.
This is often left ambiguous in a language grammar, with a separate note to say
@@ -1774,8 +1774,8 @@ that the ambiguity is resolved by associating each "else" part with the closest
enclosing `if` expression, but we prefer to make the constraint explicit in
the grammar and avoid any ambiguity.
-The first kind of `stmt0` is `expr-seq`.
-An `expr-seq`, or *expression sequence*, is a comma separated sequence of one
+The first kind of *stmt
0* is *expr-seq*`;`.
+An *expr-seq*, or *expression sequence*, is a comma separated sequence of one
or more expressions to be evaluated in sequence.
This simply means that any expression or comma-separated sequence of expressions
also qualifies as a statement.
@@ -1960,7 +1960,7 @@ Iteration can also be accomplished via
A `return` statement can be used to exit from the closest enclosing
[anonymous circuit](#circuit-and-witness-calls), if any, or otherwise from
the enclosing constructor or named circuit, and to return to the caller either
-an explicit return value, i.e., the value of [`expr-seq`](#expression-sequences)
+an explicit return value, i.e., the value of [*expr-seq*](#expression-sequences)
in this form of `return`:
`return` *expr-seq*`;`
@@ -2158,8 +2158,8 @@ are evaluated solely for their effects.
Compact has syntax for Boolean, numeric, and string literal expressions.
A __Boolean literal__ is one of the reserved words `true` or `false`.
-The static type of a boolean literal is `Boolean` and its value is the
-corresponding boolean value.
+The static type of a Boolean literal is `Boolean` and its value is the
+corresponding Boolean value.
A __numeric literal__ is a non-negative integer written in decimal, binary,
octal, or hexadecimal notation as follows:
@@ -2287,9 +2287,9 @@ The type of the entire expression is the type of *e
2* if *e
12* and the type of *e
1* if *e
2*
is a subtype of *e
1*.
-Conditional expressions are evaluated by first evaluating *e
0*.
-The value *v* of that expression determines which of the other subexpressions is
-evaluated:
+A conditional expression *e
0* `?` *e
1* `:` *e
2*
+is evaluated by first evaluating *e
0*. The value *v* of *e
0*
+determines which of the other subexpressions is evaluated:
- if *v* is `true`, then *e
1* is evaluated and its value is the
value of the entire expression
@@ -2301,8 +2301,8 @@ is evaluated.
### Relational comparison expressions
-Relational comparison expressions take the form *e
0* `op` *e
1*
-where *e
0* and *e
1* are expressions and `op` is one of
+Relational comparison expressions take the form *e
1 op e
2*
+where *e
1* and *e
2* are expressions and *op* is one of
Compact's relational operators.
The relational operators are **equals** (`==`), **not equals** (`!=`), **less
than** (`<`), **greater than** (`>`), **less than or equals** (`<=`), and
@@ -2319,8 +2319,8 @@ the types of *e
1* and *e
2* to be unsigned integer types.
The type of the result is `Boolean`.
-A relational comparison expression *e
0* `op` *e
1* is
-evaluated by evaluating *e
0*, then evaluating *e
1*, then
+A relational comparison expression *e
1 op e
2* is
+evaluated by evaluating *e
1*, then evaluating *e
2*, then
comparing the resulting values as described below.
**Equals and not equals**
@@ -2329,7 +2329,7 @@ Equality depends on the types of the operands according to the following rules.
The rules need not and therefore do not cover cases where one operand is not a subtype of
the other.
For example, if one operand has type `Boolean`, so does the other; if one
-operand has a `Bytes` type of length `n`, so does the other; and if one
+operand has a `Bytes` type of length *n*, so does the other; and if one
has a specific structure type, so does the other.
- **`Boolean` == `Boolean`:**
@@ -2341,7 +2341,7 @@ has a specific structure type, so does the other.
- **`Tuple` and `Vector`:**
the values are equal if the corresponding values at each index are equal.
- **Structure types:**
- the values are equal if the corresponding members are equal.
+ the values are equal if the values of the corresponding fields are equal.
- **Enumeration types:**
the values are equal if they are the same enumeration member.
- **`Opaque types:`**
@@ -2363,98 +2363,96 @@ otherwise it evaluates to `false`.
### Short-circuit logical expressions
-Compact supports short-circuit logical expressions of the form `e0 op e1`
-where `e0` and `e1` are expressions and `op` is one of the logical operators
-**or** (`||`) or **and** (`&&`).
+Compact supports short-circuit logical expressions of the form
+*e
1 op e
2* where *e
1* and *e
2*
+are expressions and *op* is one of the logical operators **or** (`||`) or **and**
+(`&&`).
Logical expressions require the types of both subexpressions to be `Boolean`.
Otherwise it is a static error.
The logical expression itself also has type `Boolean`.
-Logical expressions are evaluated by first evaluating the left subexpression.
-Then, the value of that expression determines the value of the entire
-expression as follows:
+Evaluating *e
1 op e
2* involves first evaluating
+*e
1*, then:
-- For `||`, if the value of the left subexpression is `true` the right
- subexpression is *not* evaluated, i.e., short-circuited, and the value
- of the entire expression is `true`.
- Otherwise, the right subexpression *is* evaluated, and its value is the
- value of the entire expression.
-- For `&&`, if the value of the left subexpression is `false` the right
- subexpression is *not* evaluated, i.e., short-circuited, and the value
- of the entire expression is `false`.
- Otherwise, the right subexpression *is* evaluated, and its value is the
+- For `||`, if *v* is `true`, *e
2* is *not* evaluated,
+ and the value of the entire expression is `true`.
+ Otherwise, *e
2* *is* evaluated, and its value is the
value of the entire expression.
+- For `&&`, if *v* is `false`, *e
2* is *not* evaluated,
+ and the value of the entire expression is `false`.
+ Otherwise, *e
2* *is* evaluated, and its value is the value of the
+ entire expression.
-These are short circuiting operators because they do not evaluate the second
+These are short-circuiting operators because they do not evaluate the second
operand if the final value is determined from the first.
### Boolean negation expressions
-Compact supports unary boolean negation expressions of the form `!e` where`e`
+Compact supports unary Boolean negation expressions of the form `!`*e* where *e*
is an expression.
-The type of the subexpression must be of type `Boolean`, otherwise it is a
+The type of *e* must be of type `Boolean`, otherwise it is a
static error.
The Boolean-negation expression itself also has type `Boolean`.
-Negation expressions are evaluated by first evaluating the subexpression and
-checking its value.
-If the subexpression's value is `true`, the value of the Boolean negation expression is `false`.
-If the subexpression's value is `false`, the value of the Boolean negation expression is `true`.
+A Boolean negation expression `!`*e* is evaluated by evaluating *e* to
+determine its value *v*.
+Then if *v* is `true`, the value of the Boolean negation expression is `false`,
+and If *v* is `false`, the value of the Boolean negation expression is `true`.
### Binary arithmetic expressions
-Binary arithmetic expressions have the form `e0 op e1`, where `e0` and `e1`
-are expressions and `op` is one of Compact's binary arithmetic operators. The
-binary arithmetic operators are **add** (`+`), **subtract** (`-`) and
+Binary arithmetic expressions have the form *e
1 op e
2*,
+where *e
1* and *e
2* are expressions and *op* is one of
+Compact's binary arithmetic operators.
+The binary arithmetic operators are **add** (`+`), **subtract** (`-`) and
**multiply** (`*`).
-Arithmetic expressions require the type of both subexpressions to be numeric
+Arithmetic expressions require the types of both subexpressions to be numeric
types, that is, either a `Field`, a `Uint`, or a type alias for a `Field` or
a `Uint`.
Putting aside type aliases for now, the type of the result depends on the
types of the subexpressions as follows:
- If either subexpression has type `Field`, the result has type `Field`.
-- Otherwise the left subexpression has type `Uint<0..m>`,
- and the right subexpression has type `Uint<0..n>`
- for some bounds `m` and `n`.
+- Otherwise *e
1* must have type `Uint<0..`*m*`>`, and
+ *e
2* must have type `Uint<0..`*n*`>` for some bounds *m* and *n*.
The type of the result depends on the operation as follows:
- - for add, the result has type `Uint<0..m+n>`,
- - for subtract, the result has type `Uint<0..m>`, and
- - for multiply, the result has type `Uint<0..m*n>`.
+ - for add, the result has type `Uint<0..`*m+n*`>`,
+ - for subtract, the result has type `Uint<0..`*m*`>`, and
+ - for multiply, the result has type `Uint<0..`*m⋅n*`>`.
For arithmetic operations with `Uint` result types, it is a static error if
the result's bound would be greater than the maximum unsigned integer.
-Evaluating an arithmetic expression involves first evaluating the subexpressions in
-order from left to right. Integer addition, subtraction, or multiplication is
-then used on the subexpression values. The overflow and underflow behavior
-differs for `Field` and `Uint` operations:
+Evaluating an arithmetic expression *e
1 op e
2* involves
+first evaluating *e
1*, then evaluating *e
2*.
+Integer addition, subtraction, or multiplication is then used on the subexpression
+values.
+The overflow and underflow behavior differs for `Field` (either operand has
+type `Field`) and `Uint` operations (both operands have a `Uint` type):
- `Field` arithmetic overflow and underflow wraps around 0; that is, the result
of an arithmetic operation whose result is a `Field` is the actual arithmetic
- value modulo `k`, where `k` is one more than the maximum field value.
+ value modulo *k*, where *k* is one more than the
+ [maximum field value](#implementation-specific-limits).
- `Uint` addition and multiplication cannot overflow: the static type of the
result is always large enough to hold the result value.
-- `Uint` subtraction checks if the value of the right subexpression is greater
- than the value of the left subexpression. If so, it is a runtime error, since
- the result would be negative. Otherwise the unsigned subtraction is performed.
-
-The static typing rules imply that if `Field` arithmetic semantics is desired,
-then at least one of the operands must have static type `Field`.
+- `Uint` subtraction results in a dynamic error if the resulting value would
+ be negative, i.e., if the value of *e
2* is greater the the value
+ of *e
1*.
If the type of either subexpression is a structural type alias for a `Field` or
`Uint` it is treated identically to that `Field` or `Uint`, both in type checking
and evaluation.
On the other hand, if the type of either subexpression is a nominal type alias
-`T` for a `Field` or a `Uint`, the type of the other subexpression must also have
-type `T`, and the type of the result also has type `T`.
+*T* for a `Field` or a `Uint`, the type of the other subexpression must also have
+type *T*, and the type of the result also has type *T*.
Evaluation proceeds as if the two operands had the underlying `Field` or `Uint`
-type with the value cast back to `T`, which can result in a run-time error if
-`T` is a nominal alias for a type `Uint<0..n>` and the value is not less than `n`.
+type with the value cast back to *T*, which can result in a run-time error if *T*
+is a nominal alias for a type `Uint<0..`*n*`>` and the value is not less than *n*.
For example:
```compact
@@ -2471,28 +2469,28 @@ message indicating that the cast of the value to `Feet` failed.
### Tuple creation
-New tuple values are created with expressions of the form `[tuple-arg, `⋯`]` where
-`tuple-arg`, ⋯ is a sequence of zero or more comma-separated tuple
+New tuple values are created with expressions of the form `[`*tuple-arg*, ⋯, *tuple-arg*`]` where
+*tuple-arg*, ⋯, *tuple-arg* is a sequence of zero or more comma-separated tuple
arguments.
A non-empty sequence can have an optional trailing comma.
Each tuple argument is either an expression or a *spread*.
-If a tuple argument is an expression `expr` of type `T`, it contributes a single
-element of type `T` to the new tuple: the value of `expr`.
+If a tuple argument is an expression *e* of type *T*, it contributes a single
+element of type *T* to the new tuple: the value of *e*.
-If a tuple argument is a spread `... expr`, the type `T` of `expr` must be
+If a tuple argument is a spread `... `*e*, the type *T* of *e* must be
a tuple type, a Vector type, or a Bytes type.
Otherwise, it is a static error.
-If `expr` has a tuple type `[U, `⋯`]` of length *n*, the spread contributes
-`n` new elements of type `U`, ⋯ to to the new tuple, i.e., the elements
-of the tuple value of `expr`.
-If `expr` has a Vector type `Vector
`, the spread contributes
-`n` new elements of type `U` to to the new tuple, i.e., the elements
-of the Vector value of `expr`.
-If `expr` has a Bytes type `Bytes`, the spread contributes `n` new elements of
+If *T* is a tuple type `[`*U1*, ⋯, *Un*`]`, the
+spread contributes *n* new elements of types *U1*, ⋯, *Un*
+to to the new tuple, i.e., the elements of the tuple value of *e*.
+If *T* is a Vector type `Vector<`*n*, *U*`>`, the spread contributes
+*n* new elements of type *U* to the new tuple, i.e., the elements
+of the Vector value of *e*.
+If *T* is a Bytes type `Bytes<`*n*`>`, the spread contributes *n* new elements of
type `Uint<8>` to to the new tuple, i.e., the elements of the byte-vector value
-of `expr`.
+of *e*.
The type of a tuple-creation expression is the tuple type whose elements are
the types contributed by each of the tuple arguments in order.
@@ -2506,41 +2504,38 @@ which can be less than or greater than number of tuple arguments.
### Byte-vector creation
New byte vectors are created with expressions of the form
-`Bytes [tuple-arg, `⋯`]`.
+`Bytes [`*tuple-arg*, ⋯, *tuple-arg*`]`.
Bytes creation is essentially the same as [tuple creation](#tuple-creation)
except that the types of the contributed elements must all be subtypes of `Uint<8>`
(if not, it is static error), and the result is a new byte vector of type
-`Bytes` where `n` is the number of contributed elements.
+`Bytes<`*n*`>` where *n* is the number of contributed elements.
### Tuple, vector, and byte-vector references
Compact allows references to individual elements of sequence values (tuples,
-vectors, and byte vectors) via the syntax `expr[index]` where `expr` is
-an expression and `index` is a numeric literal, generic natural-number parameter reference,
+vectors, and byte vectors) via the syntax *e*`[`*index*`]` where *e* is
+an expression and *index* is a numeric literal, generic natural-number parameter reference,
or an expression that can be reduced to a numeric constant at compile time as
described below.
-The type of `expr` must be a sequence type, i.e., a tuple type, a vector type,
+The type of *e* must be a sequence type, i.e., a tuple type, a vector type,
or a Bytes type.
-The type of `index` must be `Uint` for any `n`.
-The eventual constant value of `index` must be less than the length of the
+The type of *index* must be `Uint<`*n*`>` for any *n*.
+The eventual constant value of *index* must be less than the length of the
sequence value as determined by its type.
Violating any of these constraints is a static error.
-The unsigned integer value of `index` must be computable at compile time
+The unsigned integer value of *index* must be computable at compile time
via the following rules, or it is a static error.
-
-- Any `index` can be a constant, i.e., a numeric literal or a generic natural-number
+- Any *index* can be a constant, i.e., a numeric literal or a generic natural-number
parameter reference.
-
-- If the type of `expr` is a tuple type that has a vector type, the rule for
- vector types below applies, with `expr` treated as having the vector type.
- If the type of `expr` is a tuple type that does not have a vector type,
- however, `index` must be a constant.
+- If the type of *e* is a tuple type that [has a vector type](#subtyping-and-least-upper-bounds), the rule for
+ vector types below applies, with *e* treated as having the vector type.
+ If the type of *e* is a tuple type that does not have a vector type,
+ however, *index* must be a constant.
This restriction allows the compiler to compute a type for tuple reference
- expressions without first attempting to reduce `index` to a numeric value.
-
-- If the type of `expr` a vector or byte-vector type, `index` must be a
+ expressions without first attempting to reduce *index* to a numeric value.
+- If the type of *e* is a vector or byte-vector type, *index* must be a
*constant-valued* expression, where a constant-valued expression is:
- a constant,
- a reference to a generic natural-number parameter,
@@ -2550,16 +2545,16 @@ via the following rules, or it is a static error.
expressions.
The type of a byte-vector reference is `Uint<8>`.
-The type of a vector reference where the vector has type `Vector` is `T`.
-The type of a tuple reference where the tuple has type `[T1, `⋯`, Tn]` is
-`Ti` if `index` is the constant `i` or the value `i` of a generic natural-number
-parameter.
-Otherwise, `[T1, `⋯`, Tn]` must have a vector type `Vector` and the
-type of the tuple reference is `T`.
+The type of a vector reference where the vector has element type *T* is *T*.
+The type of a tuple reference where the tuple has type `[`*T1*, ⋯,
+*Tn*`]` and *index* is the constant *i* or the value
+*i* of a generic natural-number parameter is *Ti*.
+Otherwise, the tuple type must have a vector type
+`Vector<`*n*, *T*`>` and the type of the tuple reference is *T*.
-The value of a sequence reference is element `i` (zero-based) of the result
-of evaluating `expr`, where `i` is the (eventually) compile-time constant
-value of `index`.
+The value of a sequence reference is the value of the *ith* (zero-based) element
+of the result of evaluating *e*, where *i* is the (eventually) compile-time constant
+value of *index*.
### Tuple, vector, and byte-vector slices
@@ -2568,25 +2563,30 @@ subsequence of the original value.
It is similar to a sequence reference but extracts a sequence of values rather
than a single value from the sequence value.
-Slice expressions take the form `slice(expr, index)`, where `slice`
-is a keyword, `size` is a constant or numeric generic parameter reference, `expr` is
-an expression, and `index` is a numeric literal, a generic natural-number
-parameter reference, or an expression that can be reduced to a numeric constant at
-compile time as described above in the section on [Tuple, vector, and byte-vector
-references](#tuple-vector-and-byte-vector-references).
-
-The type of a byte-vector slice is `Bytes` where `k` is the constant value of `size`.
-The type of a vector slice where the vector has type `Vector` is `Vector`.
-The type of a tuple slice where the tuple has type `[T1, `⋯`, Tn]` is the subsequence
-`[Ti, `⋯`, Tj]` starting with element `i` (zero-based) and ending with element
-`j = i + k - 1` of `[T1, `⋯`, Tn]`.
-Otherwise, `[T1, `⋯`, Tn]` must have a vector type `Vector` and the
-type of the tuple reference is `Vector`.
-
-The value of a `slice` expression is subsequence of the original tuple, vector,
-or byte vector from `i` (zero-based, inclusive) through `i + k` (zero-based,
-exclusive) of the resulting of evaluating `expr`, where `i` is the (eventually)
-compile-time constant value of `index` and `k` is the constant value of `size`.
+Slice expressions take the form `slice<`*k*`>(`*e*, *index*`)`, where `slice`
+is a keyword, *k* is a constant or numeric generic parameter reference specifying
+the fixed size of the slice, *e* is an expression, and *index* is a numeric
+literal, a generic natural-number parameter reference, or an expression that can be
+reduced to a numeric constant at compile time as described above in the section on
+[sequence references](#tuple-vector-and-byte-vector-references).
+
+The type of a byte-vector slice is `Bytes<`*k*`>`.
+The type of a vector slice where the vector has element type *T* is
+`Vector<`*k*, *T*`>`.
+The type of a tuple slice where the tuple has type
+`[`*T1*, ⋯, *Tn*`]` and *index* is the constant *i*
+or the value *i* of a generic natural-number parameter
+is the subsequence `[`*Ti*, ⋯, *Tj*`]` starting with
+element *i* (zero-based) and ending with element *j=i+k-1* of `[`*T1*,
+⋯, *Tn*`]`.
+Otherwise, the tuple type must [have a vector
+type](#subtyping-and-least-upper-bounds) `Vector<`*n*, *T*`>` and the type of
+the slice is `Vector<`*k*, *T*`>`.
+
+The value of a `slice` expression `slice<`*k*`>(`*e*, *index*`)` is the subsequence
+of the original tuple, vector, or byte vector from *i* (zero-based, inclusive)
+through *i+k* (zero-based, exclusive) of the result of evaluating *e*, where *i*
+is the (eventually) compile-time constant value of *index*.
For example, if `getMiddle` is defined as follows:
@@ -2610,30 +2610,41 @@ Bytes[18, 19, 20]
### Structure creation
-Structure values are created with structure creation expressions. The
-expression `T {f, `⋯`}` is a structure creation expression, where `T` is a
-structure type name `S` or specialized generic structure type name `S`,
-and `f, `⋯ is a sequence of zero or more comma-separated field-value specifiers.
-
-A field-value specifier can be one of three things:
-
-* A **positional** field-value specifier is an expression. Evaluating the expression
- gives the value for the field. Positional field values must be given in the
- order that fields are declared in the corresponding structure declaration.
-* A **named** field-value specifier is of the form `id: e` where `id` is a field name and
- `e` is an expression. Evaluating the expression gives the value for the
- corresponding named field. Named fields can appear in any order. If named
- and positional fields are mixed, all the named fields must appear after all
- the positional fields.
-* A **spread** field-value specifier is of the form `...e` where `...` is the
- literal three dots (ellipsis) token and `e` is an expression.
- Evaluating the expression must give a value of the same structure type as the
- one being created.
- Each field of the created structure is given the value of the corresponding
- field from the spread structure, if not overridden by a named field value,
- as described below.
- If a spread expression is present, it must occur as the first field-value
- specifier, and all other specifiers must be named field values.
+Structure values are created with structure-creation expressions of the form
+*T* `{`*struct-arg*, ⋯, *struct-arg*`}`, where *T* is a structure type name *S*
+or specialized generic structure type *S*`<`*garg*, ⋯, *garg*`>`, and
+*struct-arg*, ⋯, *struct-arg* is a sequence of zero or more comma-separated
+structure arguments.
+
+A structure argument can be one of three things:
+
+- a **positional** argument, which takes the form of an expression *e*,
+- a **named** argument, which takes the form *id*`:` *e*, where *id* is a field
+ name and *e* is an expression, or
+- a **spread** argument, which takes the form `...`*e*, where `...` is the
+ literal three dots (ellipsis) token and *e* is an expression.
+
+The sequence of structure arguments within a structure-creation expression can consist
+either of:
+- zero or more positional arguments followed by zero or more named arguments, or
+- a spread argument followed by zero or more named arguments.
+
+In the first case, the values of the *n* positional arguments become the values
+of the first *n* fields of the created structure and must be given in the same
+order as the fields in the structure declaration.
+The named elements specify the values of the remaining fields by name; that is,
+the value of *e* in the named argument *id*`:` *e* becomes the value of the
+field named *id*.
+
+In the second case, the expression *e* in the spread argument `...`*e* must
+have the same structure type *T* as the one being created, and each field of the
+created structure is given the value of the corresponding field from the value
+of *e* if not overridden by one of the named arguments.
+
+Named arguments need not appear in any particular order.
+
+It is possible for only positional or only named arguments to be present.
+It is also possible, though not useful, for only a spread argument to be present.
The examples below demonstrate the use of positional and spread field values:
@@ -2656,85 +2667,84 @@ circuit f(x: Uint<32>, y: Boolean, z: Bytes<8>): S {
}
```
-The structure type name must be bound to a structure type in scope. If the
-structure is generic, then it must be explicitly specialized with generic
-arguments enclosed in angle brackets. Generic structures must be fully
-specialized: the number of generic arguments must match the number of generic
-parameters.
-
-The static type of a non-generic structure creation expression is the named
-structure type.
-
-The generic arguments to a generic structure can be types, natural number
-literals, or the names of generic parameters in scope.
-The static type of a generic structure-creation expression is a structure with
-the same name as the generic type and field types obtained by substituting the
-generic arguments for the generic parameters in the structure's declaration.
-
-**If a spread field specifier is not present:** It is a static error if the number of
-field specifiers does not match the number of fields in the corresponding
-structure declaration: a value must be given for every field. It is a static
-error if a named field specifier occurs before a positional field specifier. It
-is a static error if a field name occurs more than once, and it is a static
-error if a field name occurs that is not the name of a field in the
-corresponding structure declaration. It is a static error if the type of a
-positional field subexpression is not a subtype of the declared type of the
-(positionally) corresponding field in the structure declaration. It is a static
-error if the type of a named field subexpression is not a subtype of the
+The structure type name must be bound to a structure type in scope.
+If the structure is generic, it must be fully specialized with generic arguments
+enclosed in angle brackets.
+
+The static type of a non-generic structure-creation expression is the named
+structure type, while the static type of a generic structure-creation expression
+is a structure with the same name as the generic type and field types obtained by
+substituting the generic arguments for the generic parameters in the structure's
+declaration.
+
+**If a spread argument is not present:**
+The number of structure arguments must match the number of fields in the corresponding
+structure declaration: a value must be given for every field.
+Positional arguments must appear before named arguments.
+A field name must not occur more than once among the named arguments, and each
+field name that does occur must be the name of a field in the corresponding
+structure declaration whose value is not given positionally.
+The type of a positional field subexpression must be a subtype of the
+declared type of the (positionally) corresponding field in the structure
+declaration.
+Similarly, the type of a named field subexpression must be a subtype of the
declared type of the corresponding (named) field in the structure declaration.
-**If a spread field specifier is present:** It is a static error if the spread
-field specifier does not come first in the sequence. It is a static error
-if the type of the spread subexpression is not the same type as the structure to be
-created. It is a static error if there are any positional field specifiers. It
-is a static error if a field name occurs that is not the name of a field in the
-corresponding structure declaration. It is a static error if the type of a
-named field subexpression is not a subtype of the declared type of the
-corresponding (named) field in the structure declaration.
-
-A structure creation expression is evaluated by evaluating the field specifier
-subexpressions in order from left to right, and its value is a structure value
-whose fields have values based on the corresponding field specifier: if there is
-a positional or named field specifier for the field, the field value is the
-value of the subexpression, otherwise there must be a spread expression and the
-field value is the value of the corresponding field in the (structure) value of
-the spread subexpression.
-
-### Structure member access
-
-An expression of the form `e.id` where `e` is an expression with a structure
-type `S` and `id` is an identifier is a structure member access.
-It is a static error if `S` does not have a member named `id`.
-
-The type of any structure member access `e.id` where `e` has type `S`
-is the type of the corresponding named member of `S`.
-
-The value of any structure member access `e.id` is the result of evaluating the
-subexpression `e` and extracting the value of the resulting structure's
-`id` member.
-
-Some expressions of the form `e.id` can also be
+**If a spread argument is present:**
+The spread argument must come first in the sequence of structure arguments.
+The type of the spread subexpression must be the same as the structure to be
+created.
+There must not be any positional arguments.
+A field name must not occur more than once among the named arguments, and
+each field name that does occur must be the name of a field in the corresponding
+structure declaration.
+The type of a named field subexpression must be a subtype of the
+declared type of the corresponding (named) field in the structure declaration.
+
+Violating any of the above constraints is a static error.
+
+A structure-creation expression is evaluated by evaluating the structure argument
+expressions in order from left to right and constructing a structure value
+whose fields values are based on the corresponding structure arguments: if there
+is a positional or named argument for a field, the field's value is the
+value of the expression, otherwise there must be a spread argument and the
+field's value is the value of the corresponding field in the (structure) value
+of the spread expression.
+
+### Structure field access
+
+A structure field access is an expression of the form *e*`.`*id* where *e* is
+an expression with a structure type *T* and *id* is an identifier.
+It is a static error if *T* does not have a field named *id*.
+
+The type of any structure field access *e*`.`*id* where *e* has type *T* is the
+type of the *id* field of *T*.
+
+The value of any structure field access *e*`.`*id* is the result of evaluating the
+subexpression *e* and extracting the value of the resulting structure's *id* field.
+
+Some expressions of the form *e*`.`*id* can also be
[enumeration member accesses](#enumeration-member-access) or
-[ledger `read` operations](#ledger-state-operations).
-`e.id` is recognized as a structure member access only when the
-type of `e` is a structure type.
+[ledger-state operations](#ledger-state-operations).
+*e*`.`*id* is recognized as a structure field access only when the
+type of *e* is a structure type.
### Enumeration member access
-An expression of the form `E.id` where `E` is the name of an enumeration
-type and `id` is an identifier is an enumeration member access.
-It is a static error if `E` does not have a member named `id`.
+An expression of the form *E*`.`*id* where *E* is the name of an enumeration
+type and *id* is an identifier is an enumeration member access.
+It is a static error if *E* does not have a member named *id*.
-The type of any enumeration member access `E.id` is `E`.
+The type of any enumeration member access *E*`.`*id* is *E*.
-`E.id` is a constant.
-That is, the value of any enumeration member access `E.id` is `E.id`.
+*E*`.`*id* is a constant.
+That is, the value of any enumeration member access *E*`.`*id* is *E*`.`*id*.
-Some expressions of the form `e.id` can also be
-[structure member accesses](#enumeration-member-access) or
-[ledger `read` operations](#ledger-state-operations).
-`e.id` is recognized as an enumeration member access only when the
-type of `e` is an enumeration type.
+Some expressions of the form *E*`.`*id* can also be
+[structure field accesses](#structure-field-access) or
+[ledger-state operations](#ledger-state-operations).
+*E*`.`*id* is recognized as an enumeration member access only when the
+type of *e* is an enumeration type.
### Circuit and witness calls
@@ -3225,7 +3235,7 @@ The TypeScript type representing a Compact type is defined in [Representations
in TypeScript](#representations-in-typescript).
Compact represents values exactly as TypeScript represents values, i.e., as
-ordinary JavaScript values. So a Compact boolean is represented at run time
+ordinary JavaScript values. So a Compact Boolean is represented at run time
as a JavaScript boolean, a Compact tuple is represented as a JavaScript
array, and enum values are represented by numbers.
From d8d8304b67e844da2b1098faa6a8e026c4b77dbb Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Mon, 16 Mar 2026 07:52:10 +0100
Subject: [PATCH 21/41] latest lang-ref.mdx
---
docs/compact/reference/lang-ref.mdx | 163 +++++++++++++---------------
1 file changed, 78 insertions(+), 85 deletions(-)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index 84ba297c..c2141372 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -2748,6 +2748,12 @@ type of *e* is an enumeration type.
### Circuit and witness calls
+Circuits and witnesses, collectively referred to as functions, are called via
+expressions of the form *fun*`(`*e*, ⋯, *e*`)`, where *fun* is a function expression
+and *e*, ⋯, *e* is a sequence of zero or more comma-separated argument expressions.
+
+The function expression *fun* can take one of the following forms:
+
| | | |
|------------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------|
@@ -2760,42 +2766,28 @@ type of *e* is an enumeration type.
-Circuits and witnesses, collectively referred to as functions, are called via an
-expression of the form `f(e, ...)`, where `f` is a function and `e, ...` is a
-sequence of zero or more comma-separated argument expressions.
-
-The function expression can take several different forms:
-
-A **function name** is the name of a circuit or witness from a circuit or
-witness declaration in scope.
-
-An **anonymous circuit** is an inline circuit definition having the form `(P,
-...) => body` or `(P, ...): R => body`, where `P, ...` are zero or more
-comma-separated parameter declarations, `R` is an optional return type
-annotation, and `body` is the circuit's body.
-Each parameter is a [pattern](#patterns-and-destructuring) with an optional type
-annotation `: T` where `T` is a Compact type.
-The optional return type `R` is a Compact type.
-The body is either a [block](#blocks) or an expression.
+In the simplest form, *fun* is just a identifier *id* referring to a witness or
+named circuit.
+When *id* refers to a generic witness or circuit, it must be fully specialized via
+generic parameters.
-There is no syntax for generic anonymous circuits. This is because circuits are
-not first-class values: they cannot be passed around or stored in data
-structures, they *must* be called. And generic circuits must be specialized to
-call them, so anonymous generic circuits would have to be immediately
-specialized. In that case, the programmer can just write the non-generic
-version themselves.
+*fun* can also be an *anonymous circuit*, also known as an *arrow circuit*.
+This form consists of a parameter list
+`(`*optionally-typed-pattern*, ⋯, *optionally-typed-pattern*`)` followed
+by an optional return type `:` *type*,
+an arrow (`=>`), and a body, which can be a *block* or an *expr*.
+Each *optionally-typed-pattern* is a [pattern](#patterns-and-destructuring)
+with an optional type annotation `:` *type*.
-A **parenthesized function** has the form `(f)` where `f` is a function expression,
-i.e., a function name, anonymous circuit, or parenthesized function.
+Finally, *fun* can be a parenthesized function `(`*fun*`)`.
-Because circuits and witnesses are not first class, parameter names and constant
-names are not allowed as the circuit or witness part of a call. Nor are
-arbitrary expressions allowed, for the same reason.
+Because circuits and witnesses are not first class, *fun* cannot be a variable
+name or arbitary expresison.
-Generic functions cannot be called without explicitly specializing them with
-generic arguments enclosed in angle brackets. Calls to generic functions must
-be fully specialized: the number of generic arguments must match the number of
-generic parameters.
+Anonymous circuits cannot have generic parameters.
+Since they appear only in contexts where they are directly called, the circuit
+would have to be immediately specialized, in which case only one specialization
+can exist and the non-generic version would be clearer.
The *underlying function* of a function expression is a non-parenthesized
function expression. For a function name it is the function name, for an
@@ -2811,7 +2803,7 @@ Type checking a function call depends on the form of the underlying function.
present in the scope of the call.
A candidate function is not necessarily compatible with the number and kinds
- of the generic parameter values, nor with the number and types of the argument
+ of the generic parameter values nor with the number and types of the argument
expressions provided at the call site. It is compatible if and only if the
number of generic parameters is the same as the number of generic arguments,
each generic argument is of the required kind (numeric or type), the number
@@ -2838,13 +2830,13 @@ Type checking a function call depends on the form of the underlying function.
pieces of the corresponding argument is the type of the corresponding part of
the structure of the declared or inferred parameter type.
- If there is a return type annotation, it is a static error if the body can
- return a type of value that is not a subtype of the return type annotation.
+ If there is a return-type annotation, it is a static error if the body can
+ return a type of value that is not a subtype of the return-type annotation.
A return statement of the form `return;` implicitly returns a value of type
`[]`, as does every control flow path through a body that does not explicitly
end with a return statement.
- If there is no return type annotation, then a return type is inferred from the
+ If there is no return-type annotation, then a return type is inferred from the
body as the least upper bound of the types of the values that can be returned
from the body (explicitly or implicitly).
It is a static error if these types do not have a least upper bound.
@@ -2863,73 +2855,74 @@ value of a witness call is the value returned by the witness function.
### Map and fold expressions
Compact supports expressions that perform the higher-order operations _map_ and
-(left) _fold_ over vectors, tuples that have vector types (not arbitrary tuples),
+(left-to-right) _fold_ over vectors, tuples that have vector types (not arbitrary tuples),
and byte vectors.
-Map expressions have the form `map(f, e, e, ...)` where `map` is a keyword, `f`
-is a circuit or witness taking at least one argument, and each `e` is an expression.
-A circuit or witness taking _n_ arguments can be mapped over _n_ sequence values
-(vectors, tuples that have vector types, or byte-vectors) by providing _n_
+Map expressions have the form `map(`*fun*, *e*, ⋯¹, *e*`)` where `map` is a
+keyword, *fun* is a circuit or witness taking at least one argument, and each *e*
+is an expression.
+A circuit or witness taking *n* arguments can be mapped over *n* sequence values
+(vectors, tuples that have vector types, or byte-vectors) by providing *n*
sequence-value subexpressions to the `map`.
-Fold expressions have the form `fold(f, init, e, e, ...)` where `fold` is a
-keyword, `f` is a circuit or witness taking at least two arguments, `init`
-is an expression, and each `e` is an expression.
-A circuit or witness taking _n_+1 arguments can be folded over an initial value
-`init` and _n_ sequence values by providing _n_ sequence-value subexpressions to
+Fold expressions have the form `fold(`*fun*, *init*, *e*, ⋯¹, *e*`)` where
+`fold` is a keyword, *fun* is a circuit or witness taking at least two arguments,
+*init* is an expression, and each *e* is an expression.
+A circuit or witness taking *n*+1 arguments can be folded over an initial value
+*init* and *n* sequence values by providing *n* sequence-value subexpressions to
the `fold`.
-A detailed description of the circuit or witness `f` is given in
+A detailed description of the circuit or witness *fun* is given in
[Circuit and witness calls](#circuit-and-witness-calls) above.
A map expression is type-checked by checking the type of the witness or circuit
-`f` to find its declared or inferred parameter types and its declared or
-inferred return type `R`.
-`f` must have at least one parameter, and the map expression must have the same
-number of sequence-value subexpressions as the number of parameters of `f`.
+*fun* to find its declared or inferred parameter types and its declared or
+inferred return type *R*.
+*fun* must have at least one parameter, and the map expression must have the same
+number of sequence-value subexpressions as the number of parameters of *fun*.
Each of the sequence-value subexpressions must have a vector or byte-vector type,
-and all these types must have the same length `n`.
-If the type of the *i*th parameter to `f` is `T`, then the *i*th sequence-value
-subexpression must have the vector type `Vector` where `S` is a subtype of
-`T`, or it must be the byte-vector type `Bytes` and `Uint<8>` must be a subtype
-of `T`.
-The type of `map` expression is `Vector`, regardless of whether the input
-sequence-value subexpressions are vectors, tuples, or byte-vectors.
+and all these types must have the same length *n*.
+If the type of the *ith* parameter to *fun* is *T*, then the *ith* sequence-value
+subexpression must have the vector type `Vector<`*n*, *S*`>` where *S* is a subtype of
+*T*, or it must be the byte-vector type `Bytes<`*n*`>` and `Uint<8>` must be a subtype
+of *T*.
+The type of the `map` expression is `Vector<`*n*, *R*`>`; `map` produces a vector
+regardless of whether the input sequence-value subexpressions are vectors, tuples,
+byte-vectors, or some combination.
A fold expression is type-checked by checking the type of the witness or circuit
-`f` to find its parameter types and its return type `R`.
-`f` must have at least two parameters, and the type of the first parameter must
-be the same type as the return type `R`.
-The `fold` expression must have one fewer sequence-value subexpression than the
-number of parameters of `f`.
-The first subexpression `init` gives the initial value for the fold.
-It must have a type which is a subtype `R`.
-Each of the sequence-value subexpressions must have a vector or byte-vector type
-and all these types must have the same length `n`.
-If the type of the *i*+1th parameter of `f` is `T`, then the type of the *i*th
-sequence-value subexpression must have the vector type `Vector` where `S`
-is a subtype of `T`, or it must be the byte-vector type `Bytes` and `Uint<8>`
-must be a subtype of `T`.
-The type of the entire expression is `R`.
+*fun* to find its parameter types and its return type *R*.
+*fun* must have at least two parameters, and the type of the first parameter must
+be the same type as the return type *R*.
+The fold expression must have one fewer sequence-value subexpression than the
+number of parameters of *fun*.
+The first subexpression *init* gives the initial value for the fold.
+It must have a type which is a subtype *R*.
+Each of the sequence-value subexpressions must have a vector or byte-vector type,
+and all these types must have the same length *n*.
+If the type of parameter *i*+1 of *fun* is *T*, then the type of the *ith*
+sequence-value subexpression must have the vector type `Vector<`*n*, *S*`>` where *S*
+is a subtype of *T*, or it must be the byte-vector type `Bytes<`*n*`>` and `Uint<8>`
+must be a subtype of *T*.
+The type of the entire expression is *R*.
Map expressions are evaluated by evaluating the sequence-value subexpressions
-from left to right.
-These values are the input sequence values.
-The witness or circuit `f` is then applied in turn, from index 0 up to index
-`n`-1, to arguments taken from the input sequence values.
-The result is a vector of length `n` where each *i*th element is the result of
-applying `f` to the *i*th elements of the corresponding input sequence values.
-
-Fold expressions are evaluated by evaluating the initial value expression `init` and
+from left to right to produce the input sequence values.
+The witness or circuit *fun* is then applied in turn, from index 0 up to index
+*n*-1, to arguments taken from the input sequence values.
+The result is a vector of length *n* where each *ith* element is the result of
+applying *fun* to the *ith* elements of the corresponding input sequence values.
+
+Fold expressions are evaluated by evaluating the initial value expression *init* and
then evaluating the sequence-value subexpressions from left to right.
The values of the sequence-value expressions are the input sequence values.
-The witness or circuit `f` is then applied in turn, from index 0 up to index `n`-1,
+The witness or circuit *fun* is then applied in turn, from index 0 up to index *n*-1,
to an accumulator value argument and arguments taken from the input sequence values.
-The 0th (initial) accumulator value is the value of the expression `init`, and
-each subsequent *i*+1th accumulator value is the result of applying `f` to the
-*i*th accumulator value and to the *i*th elements of the corresponding input
+The 0th (initial) accumulator value is the value of the expression *init*, and
+each subsequent *i+1*th accumulator value is the result of applying *fun* to the
+*ith* accumulator value and to the *ith* elements of the corresponding input
sequence values.
-The result is the `n`th (final) accumulator value where `n` is the length of the
+The result is the *nth* (final) accumulator value where *n* is the length of the
input vectors.
### Type cast expressions
From 99e326839ac7e2e7421e18b0e74e03e787ba1e6f Mon Sep 17 00:00:00 2001
From: Kent Dybvig <18339284+dybvig@users.noreply.github.com>
Date: Mon, 16 Mar 2026 10:28:22 +0100
Subject: [PATCH 22/41] latest lang-ref.mdx
---
docs/compact/reference/lang-ref.mdx | 216 ++++++++++++++--------------
1 file changed, 108 insertions(+), 108 deletions(-)
diff --git a/docs/compact/reference/lang-ref.mdx b/docs/compact/reference/lang-ref.mdx
index c2141372..da3f32fe 100644
--- a/docs/compact/reference/lang-ref.mdx
+++ b/docs/compact/reference/lang-ref.mdx
@@ -694,7 +694,7 @@ that expects a value of type `Vector<3, Uint<16>>` without an explicit cast.
When one operand of an arithmetic operation (e.g., `+`) receives a value of some
nominal type alias *type-name*, the other operand must also be of type *type-name*,
and the result of performing the operation is cast to type *type-name*.
-This might cause a run-time error if the result cannot be represented by type
+This might cause a dynamic error if the result cannot be represented by type
*type-name*.
Values of any nominal type alias *type-name* cannot be compared directly using,
@@ -1378,9 +1378,9 @@ The following *ledger-state types* are supported.
- `Map`, for any Compact types `K` and `T`
- `Map`, for any Compact type `K` and ledger-state type `V` (see the following section)
- `List`, for any Compact type `T`
-- `MerkleTree`, for a compile time integer `1 < n <= 32`, and any Compact
+- `MerkleTree`, for a compile time integer 1 \< *n* ≤ 32, and any Compact
type `T`
-- `HistoricMerkleTree`, for a compile time integer `1 < n <= 32`, and any
+- `HistoricMerkleTree`, for a compile time integer 1 \< *n* ≤ 32, and any
Compact type `T`
Each ledger type supports a set of operations, which can be invoked with
@@ -2451,7 +2451,7 @@ On the other hand, if the type of either subexpression is a nominal type alias
*T* for a `Field` or a `Uint`, the type of the other subexpression must also have
type *T*, and the type of the result also has type *T*.
Evaluation proceeds as if the two operands had the underlying `Field` or `Uint`
-type with the value cast back to *T*, which can result in a run-time error if *T*
+type with the value cast back to *T*, which can result in a dynamic error if *T*
is a nominal alias for a type `Uint<0..`*n*`>` and the value is not less than *n*.
For example:
@@ -2919,7 +2919,7 @@ The values of the sequence-value expressions are the input sequence values.
The witness or circuit *fun* is then applied in turn, from index 0 up to index *n*-1,
to an accumulator value argument and arguments taken from the input sequence values.
The 0th (initial) accumulator value is the value of the expression *init*, and
-each subsequent *i+1*th accumulator value is the result of applying *fun* to the
+each subsequent *i+1th* accumulator value is the result of applying *fun* to the
*ith* accumulator value and to the *ith* elements of the corresponding input
sequence values.
The result is the *nth* (final) accumulator value where *n* is the length of the
@@ -2928,117 +2928,118 @@ input vectors.
### Type cast expressions
Values of one type can be cast to another, when allowed, via a *cast*, which
-takes the following form:
-
-```compact
-e as T
-```
-
-where `e` is an expression and `T` is a type.
-The effects of casting an expression `e` of type `T` to another type `U` depend
+takes the form *e* `as` *T* where *e* is an expression and *T* is a type.
+The effects of casting an expression *e* of type *T* to another type *U* depend
on the specific types involved.
-For some types `T` and `U`, the cast is not allowed, which is a static error.
-Even if the cast is allowed, some values of type `T` might not be representable
-as values of type `U`.
-In such cases, a run-time check of the value of `e` is required and can result
-in a run-time error.
-In cases where the run-time representation of `T` is different from the run-time
-representation of `U`, the value of `e` must be converted at run time from the
+For some types *T* and *U*, the cast is not allowed, which is a static error.
+Even if the cast is allowed, some values of type *T* might not be representable
+as values of type *U*.
+In such cases, a run-time check of the value of *e* is required and can result
+in a dynamic error.
+In cases where the run-time representation of *T* is different from the run-time
+representation of *U*, the value of *e* must be converted at run time from the
one representation to the other.
-The type of any (allowed) cast `e as T` is, naturally, `T`.
+The type of any (allowed) cast *e* `as` *T* is, naturally, *T*.
Evaluation of a cast proceeds by evaluation of its subexpression, followed by
any checks and conversions required by the cast.
-If a check fails, a run-time error is reported.
+If a check fails, a dynamic error is reported.
-TypeScript casts of the form `e` are not supported in Compact.
+TypeScript casts of the form `<`*T*`>`*e* are not supported in Compact.
-The following rules govern when casts are allowed, when casts might cause run-time
+The following rules govern when casts are allowed, when casts might cause dynamic
errors, and casts might require run-time conversions.
Any cast not covered by one of the rules is not allowed.
#### Upcasts
- Upcasts, i.e., casts from a type to a [supertype](#subtyping-and-least-upper-bounds)
- (e.g., from `Vector<3, Uint<8>>` to `Vector<3, Uint<16>>`), are always allowed
- (but never required), never result in run-time errors, and, except in the case
- where the type and the supertype are the same, might require run-time conversions.
-
-This rule has three implications:
-
-- Tuple-to-vector upcasts: if a tuple type `[T, ...]` has a vector type `Vector