From c9ae643fb692d55e82a67469436f3dfd6e474996 Mon Sep 17 00:00:00 2001 From: nmatschke Date: Tue, 19 May 2026 18:07:51 -0400 Subject: [PATCH] Edit slides starting at the end --- misc/oxcaml/oxcaml-basics/slides/index.html | 66 +++++++++++---------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/misc/oxcaml/oxcaml-basics/slides/index.html b/misc/oxcaml/oxcaml-basics/slides/index.html index 2c867d6..2fd5e86 100644 --- a/misc/oxcaml/oxcaml-basics/slides/index.html +++ b/misc/oxcaml/oxcaml-basics/slides/index.html @@ -944,13 +944,13 @@

Value layouts and unboxing

-

Runtime invariant: one OCaml value word

+

Runtime invariant: every OCaml value is one word

Immediate value

63 bits of immediate data1
-

Small integers and constructors with no payload use this shape.

+

int, char, bool, unit, etc. use this shape.

Pointer value

@@ -965,7 +965,7 @@

Pointer value

payload Nvalue or raw data
-

The word points to a heap block with a header and payload words.

+

Records, tuples, arrays, etc. use this shape.

@@ -983,7 +983,7 @@

Heap block anatomy

payload Nvalue or raw data
-

The GC follows fields described as values. Raw data fields are not scanned as pointers.

+

The header describes which fields are values vs. raw data. The GC does not scan raw data.

@@ -991,24 +991,26 @@

Heap block anatomy

Uniform value representation is powerful

Source

let plain_value_integer = 5
+
 let plain_value_tuple = (1, 2, 3)
+
 type quote =
   { symbol : string
   ; price : int
   ; mutable size : int
   }
-

Runtime model

GC, polymorphism, tuples, records, variants, and libraries all agree on one value shape.

+

Runtime model

The runtime, GC, and libraries all agree on one value shape. Polymorphic functions are only compiled once.

-

Variants and recursive data are values too

+

Variants are values too

Constant constructors

Represented as immediates.

Payload constructors

Allocate heap blocks; the header tag identifies the constructor.

-

Recursive data is a graph of value words and heap blocks.

+

Recursive data is a graph of values: immediates or pointers to other heap blocks.

@@ -1016,7 +1018,7 @@

Variants and recursive data are values too

Sharing: the heap is a graph

let shared = "shared"
 let t = (shared, shared, "other")
-

Two fields can point at the same heap object. Visualizations must preserve sharing.

+

Two fields can point at the same heap object.

@@ -1024,18 +1026,18 @@

Sharing: the heap is a graph

Uniform model costs: boxes and pointers

boxed numeric values

let boxed_numeric_values =
-  (3.5, 456L)

tuple block, boxed float, boxed int64

+ (3.5, 456L)

tuple block, boxed float, boxed int64

ordinary option values

let ordinary_option_values =
-  (None, Some "found")

Some wrapper block

+ (None, Some "found")

Some constructor requires a block

-

Layouts remove specific boxes

+

Unboxed types remove specific boxes

ordinary tuple

(1, "one")

one heap block for grouping

-

unboxed product

#(1, "one")

tuple block removed; string heap object remains

+

unboxed tuple

#(1, "one")

tuple block removed; string heap object remains

@@ -1062,7 +1064,7 @@

Unboxed records inline nested fields

-

or_null removes option wrapper allocation

+

or_null removes option wrapper allocation

@@ -1096,10 +1098,11 @@

or_null removes option wrapper allocation

-

or_null answer

+

or_null answer

Null replaces None.

+

This x replaces Some x without adding a wrapper block around x.

@@ -1119,11 +1122,13 @@

or_null answer

-

The limit: or_null cannot be nested

+

The limit: or_null cannot be nested

Null is represented by the null machine word.

+

If string or_null or_null were allowed, the same null word would need two meanings: the outer missing value and the inner missing value.

+

The payload of or_null must be non-null. A value that is already or_null is maybe-null.

@@ -1141,6 +1146,7 @@

Kinds record allowed representations

If an error says a type parameter expects value, the API expects ordinary one-word OCaml values.

+

Edit the kind bound from value to float64.

@@ -1172,18 +1178,18 @@

Abstract types need public kinds

Polymorphic code still has a layout

-

ordinary map

let rec map_value
-  : ('a : value) ('b : value).
-    ('a -> 'b)
-    -> 'a list
-    -> 'b list
+

ordinary map

val map_value
+  :  ('a : value) ('b : value)
+  .  ('a -> 'b)
+  -> 'a list
+  -> 'b list

product layout map

type ('a : value & value) product_list = ...
 
-let rec map_product_list
-  : ('a : value & value) ('b : value & value).
-    ('a -> 'b)
-    -> 'a product_list
-    -> 'b product_list
+val map_product_list + : ('a : value & value) ('b : value & value) + . ('a -> 'b) + -> 'a product_list + -> 'b product_list
@@ -1193,16 +1199,16 @@

Templates reduce layout-specific repetition

let%template[@kind k = (value, value & value)] id
   : ('a : k). 'a -> 'a =
   fun x -> x
-

One source pattern can generate related checked definitions with different calling conventions.

+

One source pattern can generate multiple definitions with different calling conventions.

-

Choose the checked lever

+

Choose the correct lever

-

Race risk

Use contention and portability requirements.

-

Lifetime or heap allocation risk

Use local, stack_, and exclave_.

-

Box or pointer cost

Use layouts, unboxed values, or_null, kinds, and templates.

+

Data race safety

Use contention and portability requirements.

+

Lifetime correctness or heap allocation cost

Use local, stack_, and exclave_.

+

Box or pointer cost

Use layouts, unboxed types, and or_null.

All three make performance-sensitive intent explicit and checked.