-
Notifications
You must be signed in to change notification settings - Fork 1
[CHANGE] Spec Proposal 2026 #90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Sir-NoChill
wants to merge
27
commits into
cmput415:master
Choose a base branch
from
Sir-NoChill:upstreaming
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
c8a71a1
chore: remove vector type specification
Sir-NoChill d80f747
chore: remove struct type specification
Sir-NoChill 2b25062
chore: remove matrix type specification
Sir-NoChill a20d9d2
clean: remove deprecated keywords for removed features
Sir-NoChill c3f9751
clean: remove length built-in; update shape and reverse for N-D arrays
Sir-NoChill b4c8c28
impl: add constexpr specification
Sir-NoChill 4f5a077
impl: add value-categories hint document
Sir-NoChill 3cb11d3
clean: update globals initialization rule to reference constexpr
Sir-NoChill 2119881
clean: add range and stride operator definitions to expressions
Sir-NoChill e8e553e
clean: update generator examples for N-dimensional array syntax
Sir-NoChill abaa136
clean: replace array spec with unified N-dimensional model
Sir-NoChill 23b19e7
fix: uniform N-D array syntax throughout spec
Sir-NoChill cca38a1
impl: rewrite string type specification
Sir-NoChill 8b5f0aa
impl: add type lattice diagram and revise type_promotion.rst
Sir-NoChill 435f396
fix: update functions and procedures to reflect revised spec
Sir-NoChill 454dfe9
enh: add integer overflow specification
Sir-NoChill 06067d6
impl: rewrite tuple type specification with named-field support
Sir-NoChill ea0ac49
clar: clarify that * is not what makes an array dynamic
Sir-NoChill d8352c0
clar: add implementation hint for slice passing without eager deep copy
Sir-NoChill 8f44885
fix: move value_categories from standalone Hints section into Impleme…
Sir-NoChill 924cd1d
clar: Constexprs and scope constraints
Sir-NoChill 8e08976
fix: clarify the inner scope constexprs
Sir-NoChill 6495ac8
fix: kill the em-dash and fix hallucinations
Sir-NoChill abe0e48
clar: Remove jagged arrays
Sir-NoChill 3733d27
fix: r-dean comments
Sir-NoChill a26aee2
fix: grammar
Sir-NoChill d5fbc16
fix: function calls contradiction
Sir-NoChill File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| .. _sec:impl_slice_passing: | ||
|
|
||
| Slice Passing — Eager Copy vs. Copy-On-Write | ||
| ============================================ | ||
|
|
||
| The *Gazprea* specification defines slice expressions as rvalues that produce a | ||
| **deep copy** of the selected elements (see :ref:`sssec:array_ops`). This is a | ||
| *semantic* guarantee: from the programmer's perspective, a slice always behaves | ||
| as an independent value with no aliasing relationship to the source array. | ||
|
|
||
| However, the specification does **not** require an *eager* copy to be made at | ||
| the point of the slice expression. An implementation is free to use a lazy | ||
| strategy such as **Copy-On-Write (COW)**. | ||
|
|
||
| Copy-On-Write Strategy | ||
| ---------------------- | ||
|
|
||
| Under COW, passing a slice to a function or procedure does not immediately | ||
| duplicate the underlying storage. Instead, the implementation shares the same | ||
| backing memory and only performs the physical copy when — and if — either the | ||
| source array or the slice view is mutated. If no mutation occurs, the copy is | ||
| avoided entirely. | ||
|
|
||
| This is safe because: | ||
|
|
||
| 1. Slices can only be passed as ``const`` (by-value) parameters. A callee that | ||
| receives a slice argument cannot mutate it through that parameter. | ||
| 2. The source array variable is not accessible from inside the called | ||
| function/procedure (functions are pure; procedures have no aliasing with | ||
| ``const`` parameters). | ||
|
|
||
| Therefore, a COW implementation is observationally equivalent to an eager deep | ||
| copy for all legal *Gazprea* programs. | ||
|
|
||
| Example | ||
| ------- | ||
|
|
||
| :: | ||
|
|
||
| function sum(integer[*] v) returns integer { ... } | ||
|
|
||
| procedure main() returns integer { | ||
| var integer[10] a = 1..10; | ||
|
|
||
| // The slice a[2..6] is an rvalue. An eager-copy implementation | ||
| // allocates a new 4-element array here. A COW implementation may | ||
| // instead pass a lightweight view into a's storage, deferring the | ||
| // copy until (if ever) a mutation would make it necessary. | ||
| integer total = sum(a[2..6]); | ||
| return total; | ||
| } | ||
|
|
||
| Implementation Note | ||
| ------------------- | ||
|
|
||
| Choosing an eager-copy or COW strategy is an internal quality-of-implementation | ||
| decision and does not affect language semantics. Implementations that wish to | ||
| avoid the overhead of copying large slices are encouraged to consider COW or | ||
| similar lazy strategies. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| .. _sec:value_categories: | ||
|
|
||
| Value Categories | ||
| ================ | ||
|
|
||
| Every expression in *Gazprea* belongs to exactly one **value category**, | ||
| which determines how the expression may be used. In essence, value categories | ||
| describe whether an expression | ||
| can appear on the left-hand side of an assignment and whether it can be passed | ||
| as a mutable (``var``) argument to a procedure. | ||
|
|
||
| *Gazprea* recognises two value categories: **lvalue** and **rvalue**. This is | ||
| a deliberate simplification of the richer taxonomy found in modern C++ (which | ||
| adds *xvalue*, *prvalue*, and *glvalue*); those additional categories exist to | ||
| support move semantics and resource transfer, neither of which *Gazprea* | ||
| exposes. The two-category model is sufficient for *Gazprea*'s ownership rules, | ||
| which are entirely copy-based. | ||
|
|
||
| The full C++ taxonomy is described at | ||
| `cppreference: Value categories <https://en.cppreference.com/w/cpp/language/value_category.html>`_ | ||
| and is worth understanding as background, even if *Gazprea* does not expose all | ||
| of it. | ||
|
|
||
| .. _ssec:vc_background: | ||
|
|
||
| Background: The Full C++ Taxonomy | ||
| ---------------------------------- | ||
|
|
||
| C++ characterises expressions along two orthogonal axes: | ||
|
|
||
| - **Identity**: does the expression refer to a persistent object that has an | ||
| address and can be named again later? | ||
| - **Moveability**: can the object's resources be transferred (moved) rather | ||
| than copied? | ||
|
|
||
| This gives rise to five named categories, arranged in the following hierarchy: | ||
|
|
||
| .. code-block:: text | ||
|
|
||
| Expression | ||
| ├── glvalue (has identity) | ||
| │ ├── lvalue (identity, not moveable) | ||
| │ └── xvalue (identity, moveable — "expiring value") | ||
| └── rvalue (may be moved from) | ||
| ├── xvalue (shared with glvalue above) | ||
| └── prvalue (no identity — "pure rvalue") | ||
|
|
||
| **glvalue** ("generalised lvalue") | ||
| Any expression that determines the identity of an object or function. | ||
| Includes both lvalues and xvalues. A glvalue *may* be implicitly converted | ||
| to a prvalue. | ||
|
|
||
| **lvalue** | ||
| A glvalue that is not an xvalue. Refers to a persistent object with a | ||
| stable address — something you can take the address of and use again next | ||
| time the same expression is evaluated. Variable names, array element | ||
| accesses, and dereferenced pointers are classic lvalues. | ||
|
|
||
| **xvalue** ("expiring value") | ||
| A glvalue whose resources can be reused because the object is near the end | ||
| of its lifetime. Introduced in C++11 to support ``std::move`` and rvalue | ||
| references. *Gazprea* has no equivalent.* | ||
|
|
||
| **prvalue** ("pure rvalue") | ||
| An rvalue that is not an xvalue. Computes a value or initialises an object | ||
| but has no persistent identity of its own. Literals, arithmetic | ||
| sub-expressions, and function return values (when returned by value) are | ||
| prvalues. | ||
|
|
||
| **rvalue** | ||
| The union of xvalues and prvalues, anything that is not a glvalue. | ||
| rvalues can generally be moved from (in C++) and cannot be the target of an | ||
| ordinary assignment. | ||
|
|
||
| .. _ssec:vc_gazprea: | ||
|
|
||
| Value Categories in Gazprea | ||
| ----------------------------- | ||
|
|
||
| Because *Gazprea* has no move semantics or reference types, xvalues never | ||
| arise. The two remaining categories collapse cleanly: | ||
|
|
||
| **lvalue** | ||
| An expression that refers to a named, addressable storage location that | ||
| persists beyond the expression and can appear on the left-hand side of an | ||
| assignment. In *Gazprea*: | ||
|
|
||
| - Named variables (``x``, ``arr``, ``my_tuple``) | ||
| - Individual element accesses on mutable arrays (``arr[i]``, ``mat[i, j]``, | ||
| ``tup.1``, ``tup.name``) | ||
|
|
||
| **rvalue** | ||
| An expression that produces a value but has no persistent, named storage | ||
| location. In *Gazprea*, rvalues correspond to what C++ would call | ||
| *prvalues*: | ||
|
|
||
| - Literals (``42``, ``true``, ``'a'``, ``"hello"``) | ||
| - Arithmetic and logical sub-expressions (``x + 1``, ``a and b``) | ||
| - Array and tuple literals (``[1, 2, 3]``, ``(x: 1, y: 2)``) | ||
| - Range expressions (``1..10``) | ||
| - **Slice expressions** (``arr[2..5]``) — even though slices are derived | ||
| from a named array, the result is a fresh deep copy with no stable | ||
| address of its own | ||
| - Function call results | ||
|
|
||
| .. _ssec:vc_consequences: | ||
|
|
||
| Practical Consequences | ||
| ----------------------- | ||
|
|
||
| The value category of an expression determines what you can do with it: | ||
|
|
||
| +---------------------------------------------+----------+---------+ | ||
| | Operation | lvalue | rvalue | | ||
| +=============================================+==========+=========+ | ||
| | Appear on left-hand side of ``=`` | ✓ | ✗ | | ||
| +---------------------------------------------+----------+---------+ | ||
| | Pass as ``var`` (mutable) procedure argument| ✓ | ✗ | | ||
| +---------------------------------------------+----------+---------+ | ||
| | Pass as ``const`` procedure argument | ✓ | ✓ | | ||
| +---------------------------------------------+----------+---------+ | ||
| | Use in an expression | ✓ | ✓ | | ||
| +---------------------------------------------+----------+---------+ | ||
|
|
||
| In particular, because a slice is an rvalue, the following are both | ||
| compile-time errors: | ||
|
|
||
| :: | ||
|
|
||
| var integer[5] a = [10, 20, 30, 40, 50]; | ||
|
|
||
| a[1..3] = [99, 99]; // ERROR: slice is an r-value, not an l-value | ||
|
|
||
| procedure mutate(var integer[*] v) { ... } | ||
| call mutate(a[1..3]); // ERROR: cannot pass r-value as var argument | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.