Skip to content

Commit d2a3f01

Browse files
committed
docs fix
1 parent d0db6fa commit d2a3f01

File tree

2 files changed

+115
-40
lines changed

2 files changed

+115
-40
lines changed

ownership.md

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,40 @@ This warning relies on flow analysis, which ensures that the potential nullabili
9696
#### Non nullable members
9797

9898
The concept of nullable types is present in some language like C# and Typescript.
99-
Both languages have the concept of `constructor` for objects. So, for objects members, the compiler checks if after the constructor the non-nullable members have being assigned to a non null value.
99+
Both languages have the concept of object constructor. For object members, the compiler checks if
100+
after the constructor the non-nullable members have being assigned to a non null value.
100101

101-
The other way to see this, is that during construction the non nullable pointer member can be null, before they receive a value.
102+
For instance, in Typescript
102103

103-
In C, we don t have the concept of constructor, so the same approach cannot be applied directly.
104+
```ts
105+
class Y {
106+
public i = 0;
107+
}
108+
109+
class X
110+
{
111+
public readonly i : number;
112+
public pY : Y;
113+
constructor(){
114+
//Property 'pY' has no initializer and is not definitely assigned
115+
//in the constructor.(2564)
116+
//this.pY = new Y;
117+
//this.i = 1;
118+
}
119+
}
120+
121+
```
122+
123+
https://www.typescriptlang.org/play/?#code/MYGwhgzhAECa0G9oChrQA4FcBGICWw0e0AvNAAwDcKAvssqJDABopKoY76EBOApmAAmAewB2IAJ5FoALmijMAW2x8e1DllwEM8ObGoo0wMRAAuPTMFPCeACgCUCDmgD0LgAo9h6VaakBydFh-aAALSHlhIlE8UzwwfAAvVWgwUUEiGFFhU2hBPgAzPBjTPklUqDwAc1E+DOdoN2LoU1C+aGNRMwsrGwA6WwAmAFYANgAWezQ0BrdWvAg+oNJ5PgB3OEpZl3nF4jIARi20OjogA
124+
125+
126+
The other way to see this, is that during construction the invariant of the object is not complete yet.
127+
128+
In C, we don t have the concept of constructor, so the same approach cannot be applied directly.
104129

105130
Cake, have a mechanism using the qualifier `_Opt` before struct types to make all non-nullable members as nullable for a particular instance.
131+
This allow us the have a object where the invariant is not completed.
132+
106133

107134
```c
108135
struct X {
@@ -124,11 +151,16 @@ struct X * _Opt makeX(const char* name)
124151
}
125152
```
126153
127-
<button onclick="Try(this)">try</button>
154+
<button onclick="Try(this)">try</button>
155+
156+
The particular instance of p, that has being qualified with \_Opt, is allowed to have no-nullable members with a null values.
128157
129-
Just like in C# or Typescript, we cannot leave this function with a nullable member being null. But the particular instance of p is allowed to have nullable members.
158+
However, we cannot leave this function with a non-nullable member being null because the result of
159+
the function is not \_Opt qualified.
160+
This approach makes it possible to have an alternative design for constructors.
130161
131-
This is also useful to accept for some functions like destructor, partially constructed object.
162+
This state is also useful for some functions like destructor, to be able to destroy partially constructed objects.
163+
For instance:
132164
133165
```c
134166
void x_destroy(_Opt struct X * p)
@@ -137,9 +169,16 @@ void x_destroy(_Opt struct X * p)
137169
}
138170
```
139171

172+
>Note : This design may change and be replaced by mutable.
173+
174+
#### mutable
175+
140176
Note that this concept also could be applied for const members.
141177

142-
The introduction of a **mutable** qualifier allows certain exceptions to the usual contract of immutability and non-nullability during transitional phases, such as in constructors and destructors. This means that objects marked as **mutable** can temporarily violate their normal constraints, such as modifying `const` members or assigning null to non-nullable pointers during these phases.
178+
The introduction of a **mutable** qualifier allows certain exceptions to the usual contract
179+
of immutability and non-nullability during transitional phases, such as in constructors and destructors.
180+
This means that objects marked as **mutable** can temporarily violate their normal constraints,
181+
such as modifying `const` members or assigning null to non-nullable pointers during these phases.
143182

144183
Consider the following code example:
145184

@@ -163,9 +202,17 @@ struct X * _Opt makeX(const char* name)
163202
}
164203
```
165204
166-
In this example, `struct X` has a `const` member `name`, which is non-nullable. Under normal conditions, modifying a `const` member after initialization would be disallowed. However, the **mutable** qualifier temporarily relaxes this rule during the object’s creation process, allowing modifications even to `const` members, and allowing a non-nullable pointer to be null before the object’s initialization completes.
205+
In this example, `struct X` has a `const` member `name`, which is non-nullable.
206+
Under normal conditions, modifying a `const` member after initialization would be disallowed.
207+
208+
However, the **mutable** qualifier temporarily relaxes this rule during the object’s creation process,
209+
allowing modifications even to `const` members, and allowing a non-nullable pointer to be null
210+
before the object’s initialization completes.
167211
168-
We also have an implicit contract for struct members. Generally, we assume that members are initialized, but we lack a qualifier to explicitly indicate "initialized member." For instance, when using malloc, members are initially uninitialized, but they should receive a value before being used.
212+
We also have an implicit contract for struct members.
213+
Generally, we assume that members are initialized, but we lack a qualifier to explicitly
214+
indicate "initialized member."
215+
For instance, when using malloc, members are initially uninitialized, but they should receive a value before being used.
169216
170217
```c
171218
struct X * _Opt makeX(const char* name)
@@ -184,17 +231,7 @@ struct X * _Opt makeX(const char* name)
184231
}
185232
```
186233

187-
188-
##### Transitional State:
189-
During the object creation (or destruction), the instance is considered to be in a transitional state, where the usual constraints—such as non-nullable pointers and immutability—are lifted. For example, in the `makeX` function, `p->name` can be set to `temp`, even though `name` is `const`. This allows flexibility during initialization, after which the object is returned to its normal state with the contract fully enforced.
190-
191-
##### Effect on the Final Object:
192-
Once the transitional phase is over and the object is returned, the contract that governs the object (such as immutability of `name` and non-nullability of pointers) is fully reinstated. The **mutable** qualifier only applies within the scope of the constructor or destructor, ensuring that once the object is fully constructed, its state is valid and consistent with the type system’s rules.
193-
194-
This approach allows for more flexibility during object creation while maintaining strong contracts once the object is finalized, enhancing both safety and expressiveness in the code.
195-
196-
197-
OBS: mutable qualifier is not yet implemented in Cake. However, _Opt for structs is implemented.
234+
>OBS: mutable qualifier is not yet implemented in Cake. However, _Opt for structs is implemented and may be replaced in the future
198235
199236

200237
### Object lifetime checks

src/web/ownership.html

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,37 @@ <h4>Example 3: Diagnostic for Nullable to Non-Nullable Conversion</h4>
147147
<h4>Non nullable members</h4>
148148

149149
<p>The concept of nullable types is present in some language like C# and Typescript.
150-
Both languages have the concept of <code>constructor</code> for objects. So, for objects members, the compiler checks if after the constructor the non-nullable members have being assigned to a non null value.</p>
150+
Both languages have the concept of object constructor. For object members, the compiler checks if
151+
after the constructor the non-nullable members have being assigned to a non null value.</p>
151152

152-
<p>The other way to see this, is that during construction the non nullable pointer member can be null, before they receive a value.</p>
153+
<p>For instance, in Typescript</p>
153154

154-
<p>In C, we don t have the concept of constructor, so the same approach cannot be applied directly.</p>
155+
<pre><code class="language-ts">class Y {
156+
public i = 0;
157+
}
158+
159+
class X
160+
{
161+
public readonly i : number;
162+
public pY : Y;
163+
constructor(){
164+
//Property &#39;pY&#39; has no initializer and is not definitely assigned
165+
//in the constructor.(2564)
166+
//this.pY = new Y;
167+
//this.i = 1;
168+
}
169+
}
170+
171+
</code></pre>
155172

156-
<p>Cake, have a mechanism using the qualifier <code>_Opt</code> before struct types to make all non-nullable members as nullable for a particular instance.</p>
173+
<p><a href="https://www.typescriptlang.org/play/?#code/MYGwhgzhAECa0G9oChrQA4FcBGICWw0e0AvNAAwDcKAvssqJDABopKoY76EBOApmAAmAewB2IAJ5FoALmijMAW2x8e1DllwEM8ObGoo0wMRAAuPTMFPCeACgCUCDmgD0LgAo9h6VaakBydFh-aAALSHlhIlE8UzwwfAAvVWgwUUEiGFFhU2hBPgAzPBjTPklUqDwAc1E+DOdoN2LoU1C+aGNRMwsrGwA6WwAmAFYANgAWezQ0BrdWvAg+oNJ5PgB3OEpZl3nF4jIARi20OjogA">https://www.typescriptlang.org/play/?#code/MYGwhgzhAECa0G9oChrQA4FcBGICWw0e0AvNAAwDcKAvssqJDABopKoY76EBOApmAAmAewB2IAJ5FoALmijMAW2x8e1DllwEM8ObGoo0wMRAAuPTMFPCeACgCUCDmgD0LgAo9h6VaakBydFh-aAALSHlhIlE8UzwwfAAvVWgwUUEiGFFhU2hBPgAzPBjTPklUqDwAc1E+DOdoN2LoU1C+aGNRMwsrGwA6WwAmAFYANgAWezQ0BrdWvAg+oNJ5PgB3OEpZl3nF4jIARi20OjogA</a></p>
174+
175+
<p>The other way to see this, is that during construction the invariant of the object is not complete yet.</p>
176+
177+
<p>In C, we don t have the concept of constructor, so the same approach cannot be applied directly.</p>
178+
179+
<p>Cake, have a mechanism using the qualifier <code>_Opt</code> before struct types to make all non-nullable members as nullable for a particular instance.
180+
This allow us the have a object where the invariant is not completed.</p>
157181

158182
<pre><code class="language-c">struct X {
159183
char * name; //non nullable
@@ -176,19 +200,33 @@ <h4>Non nullable members</h4>
176200

177201
<p><button onclick="Try(this)">try</button></p>
178202

179-
<p>Just like in C# or Typescript, we cannot leave this function with a nullable member being null. But the particular instance of p is allowed to have nullable members.</p>
203+
<p>The particular instance of p, that has being qualified with _Opt, is allowed to have no-nullable members with a null values.</p>
180204

181-
<p>This is also useful to accept for some functions like destructor, partially constructed object.</p>
205+
<p>However, we cannot leave this function with a non-nullable member being null because the result of
206+
the function is not _Opt qualified.
207+
This approach makes it possible to have an alternative design for constructors.</p>
208+
209+
<p>This state is also useful for some functions like destructor, to be able to destroy partially constructed objects.
210+
For instance:</p>
182211

183212
<pre><code class="language-c">void x_destroy(_Opt struct X * p)
184213
{
185214
free(p-&gt;name); //ok
186215
}
187216
</code></pre>
188217

218+
<blockquote>
219+
<p>Note : This design may change and be replaced by mutable.</p>
220+
</blockquote>
221+
222+
<h4>mutable</h4>
223+
189224
<p>Note that this concept also could be applied for const members. </p>
190225

191-
<p>The introduction of a <strong>mutable</strong> qualifier allows certain exceptions to the usual contract of immutability and non-nullability during transitional phases, such as in constructors and destructors. This means that objects marked as <strong>mutable</strong> can temporarily violate their normal constraints, such as modifying <code>const</code> members or assigning null to non-nullable pointers during these phases.</p>
226+
<p>The introduction of a <strong>mutable</strong> qualifier allows certain exceptions to the usual contract
227+
of immutability and non-nullability during transitional phases, such as in constructors and destructors.
228+
This means that objects marked as <strong>mutable</strong> can temporarily violate their normal constraints,
229+
such as modifying <code>const</code> members or assigning null to non-nullable pointers during these phases.</p>
192230

193231
<p>Consider the following code example:</p>
194232

@@ -211,9 +249,17 @@ <h4>Non nullable members</h4>
211249
}
212250
</code></pre>
213251

214-
<p>In this example, <code>struct X</code> has a <code>const</code> member <code>name</code>, which is non-nullable. Under normal conditions, modifying a <code>const</code> member after initialization would be disallowed. However, the <strong>mutable</strong> qualifier temporarily relaxes this rule during the object’s creation process, allowing modifications even to <code>const</code> members, and allowing a non-nullable pointer to be null before the object’s initialization completes.</p>
252+
<p>In this example, <code>struct X</code> has a <code>const</code> member <code>name</code>, which is non-nullable.
253+
Under normal conditions, modifying a <code>const</code> member after initialization would be disallowed. </p>
215254

216-
<p>We also have an implicit contract for struct members. Generally, we assume that members are initialized, but we lack a qualifier to explicitly indicate &quot;initialized member.&quot; For instance, when using malloc, members are initially uninitialized, but they should receive a value before being used.</p>
255+
<p>However, the <strong>mutable</strong> qualifier temporarily relaxes this rule during the object’s creation process,
256+
allowing modifications even to <code>const</code> members, and allowing a non-nullable pointer to be null
257+
before the object’s initialization completes.</p>
258+
259+
<p>We also have an implicit contract for struct members.
260+
Generally, we assume that members are initialized, but we lack a qualifier to explicitly
261+
indicate &quot;initialized member.&quot;
262+
For instance, when using malloc, members are initially uninitialized, but they should receive a value before being used.</p>
217263

218264
<pre><code class="language-c">struct X * _Opt makeX(const char* name)
219265
{
@@ -231,17 +277,9 @@ <h4>Non nullable members</h4>
231277
}
232278
</code></pre>
233279

234-
<h5>Transitional State:</h5>
235-
236-
<p>During the object creation (or destruction), the instance is considered to be in a transitional state, where the usual constraints—such as non-nullable pointers and immutability—are lifted. For example, in the <code>makeX</code> function, <code>p-&gt;name</code> can be set to <code>temp</code>, even though <code>name</code> is <code>const</code>. This allows flexibility during initialization, after which the object is returned to its normal state with the contract fully enforced.</p>
237-
238-
<h5>Effect on the Final Object:</h5>
239-
240-
<p>Once the transitional phase is over and the object is returned, the contract that governs the object (such as immutability of <code>name</code> and non-nullability of pointers) is fully reinstated. The <strong>mutable</strong> qualifier only applies within the scope of the constructor or destructor, ensuring that once the object is fully constructed, its state is valid and consistent with the type system’s rules.</p>
241-
242-
<p>This approach allows for more flexibility during object creation while maintaining strong contracts once the object is finalized, enhancing both safety and expressiveness in the code.</p>
243-
244-
<p>OBS: mutable qualifier is not yet implemented in Cake. However, _Opt for structs is implemented.</p>
280+
<blockquote>
281+
<p>OBS: mutable qualifier is not yet implemented in Cake. However, _Opt for structs is implemented and may be replaced in the future</p>
282+
</blockquote>
245283

246284
<h3 id="toc_3">Object lifetime checks</h3>
247285

0 commit comments

Comments
 (0)