···11+I have a checkout of OCaml in ocaml/ and a forked version with lots of
22+extensions in oxcaml/.
33+44+I want you to look carefully through the various documentations in oxcaml,
55+particularly the extensions in oxcaml/jane/doc/extensions.
66+77+Spawn subagents to understand each extension, distilling down each one to a set
88+of guidelines you can use when porting OCaml code to use the OxCaml extensions.
99+Then write a llms.txt that captures all this knowledge for future code models
1010+to refer to as part of their context when writing oxcaml code.
+319
llms.txt
···11+# OxCaml Language Model Context
22+33+OxCaml is Jane Street's enhanced version of OCaml that adds numerous performance and safety features while maintaining OCaml compatibility. This document provides comprehensive guidance for code generation and porting OCaml code to OxCaml.
44+55+## Core OxCaml Philosophy
66+77+OxCaml extends OCaml with:
88+- **Zero-allocation programming**: Stack allocation, unboxed types, comprehensive optimization
99+- **Parallelism with safety**: Data-race-free parallel programming through modes
1010+- **Fine-grained control**: Modes, kinds, uniqueness for memory and performance optimization
1111+- **Enhanced expressiveness**: Comprehensions, SIMD, templates for better abstractions
1212+1313+## Quick Reference: Key Extensions
1414+1515+### Stack Allocation (`local` mode)
1616+- Use `@ local` for values that don't escape scope
1717+- Enables stack allocation, reducing GC pressure
1818+- Use `exclave_` to return local values from functions
1919+- `stack_` forces stack allocation (fails if impossible)
2020+2121+### Unboxed Types (layouts)
2222+- `float#`, `int32#`, `int64#` for unboxed numeric types
2323+- Literals: `#3.14` (float#), `#123l` (int32#), `#456L` (int64#)
2424+- Unboxed records: `#{ field = value }`
2525+- Unboxed tuples: `#(a, b, c)`
2626+2727+### Parallelism
2828+- Use `Parallel.fork_join2` for parallel computation
2929+- Mark data `@ portable` for cross-domain sharing
3030+- Use `@ contended` for thread-safe mutable data
3131+- Capsules for complex shared mutable state
3232+3333+### Comprehensions
3434+- List: `[ expr for pat in seq when cond ]`
3535+- Array: `[| expr for pat in seq when cond |]`
3636+- Range iteration: `for i = 1 to n`
3737+- Parallel iteration: `for x in xs and y in ys`
3838+3939+### SIMD
4040+- Vector types: `float32x4#`, `int32x4#`, etc.
4141+- Load from memory: `Float32x4.String.get`
4242+- Operations: `Float32x4.add`, `Float32x4.mul`
4343+- Use `[@unboxed]` for C interop
4444+4545+## Mode System Reference
4646+4747+### Locality Axis (scope)
4848+- `global` (default): May escape scope
4949+- `local`: Cannot escape scope, enables stack allocation
5050+5151+### Contention Axis (thread safety)
5252+- `uncontended` (default): Single thread access
5353+- `shared`: Multiple threads read-only
5454+- `contended`: Multiple threads with writes
5555+5656+### Portability Axis (thread movement)
5757+- `nonportable` (default): Cannot move between threads
5858+- `portable`: May move across thread boundaries
5959+6060+### Uniqueness Axis (aliasing)
6161+- `aliased` (default): Multiple references
6262+- `unique`: Single reference only
6363+6464+### Other Axes
6565+- Linearity: `many` (default) vs `once` (single use)
6666+- Yielding: `unyielding` (default) vs `yielding` (effects)
6767+- Visibility: `read_write` (default) vs `read` vs `immutable`
6868+- Statefulness: `stateful` (default) vs `observing` vs `stateless`
6969+7070+## Kind System Reference
7171+7272+### Layouts
7373+- `value`: Standard OCaml values
7474+- `immediate`: Int-like types
7575+- `float64`, `float32`: Unboxed floats
7676+- `bits64`, `bits32`: Unboxed integers
7777+- `word`: Machine word
7878+- `vec128`, `vec256`: SIMD vectors
7979+- `any`: Maximum layout
8080+8181+### Kind Abbreviations
8282+- `immediate`: Values like `int`, `bool`
8383+- `immutable_data`: Plain immutable data
8484+- `mutable_data`: Plain mutable data
8585+- `any_non_null`: Any layout excluding NULL
8686+8787+## Migration Guidelines: OCaml to OxCaml
8888+8989+### 1. Performance Optimization
9090+9191+**Stack Allocation:**
9292+```ocaml
9393+(* Before *)
9494+let process data =
9595+ let temp = expensive_computation data in
9696+ extract_result temp
9797+9898+(* After *)
9999+let process data =
100100+ let temp @ local = expensive_computation data in
101101+ extract_result temp
102102+```
103103+104104+**Unboxed Numeric Code:**
105105+```ocaml
106106+(* Before *)
107107+let distance x1 y1 x2 y2 =
108108+ sqrt ((x2 -. x1) ** 2.0 +. (y2 -. y1) ** 2.0)
109109+110110+(* After *)
111111+let distance x1 y1 x2 y2 =
112112+ Float_u.sqrt (Float_u.add
113113+ (Float_u.pow (Float_u.sub x2 x1) #2.0)
114114+ (Float_u.pow (Float_u.sub y2 y1) #2.0))
115115+```
116116+117117+**Array Processing with SIMD:**
118118+```ocaml
119119+(* Before *)
120120+let add_arrays a b = Array.map2 (+.) a b
121121+122122+(* After *)
123123+module F32x4 = Ocaml_simd_sse.Float32x4
124124+let add_vectors v1 v2 = F32x4.add v1 v2
125125+```
126126+127127+### 2. Parallel Programming
128128+129129+**Basic Parallelism:**
130130+```ocaml
131131+(* Before *)
132132+let map_reduce f reduce_f init list =
133133+ List.fold_left (fun acc x -> reduce_f acc (f x)) init list
134134+135135+(* After *)
136136+let parallel_map_reduce par f reduce_f init list =
137137+ let process chunk =
138138+ List.fold_left (fun acc x -> reduce_f acc (f x)) init chunk
139139+ in
140140+ match list with
141141+ | [] -> init
142142+ | _ ->
143143+ let mid = List.length list / 2 in
144144+ let left, right = List.split_at mid list in
145145+ let left_result, right_result =
146146+ Parallel.fork_join2 par
147147+ (fun _ -> process left)
148148+ (fun _ -> process right)
149149+ in
150150+ reduce_f left_result right_result
151151+```
152152+153153+**Shared Mutable State:**
154154+```ocaml
155155+(* Before *)
156156+let shared_counter = ref 0
157157+let increment () = incr shared_counter
158158+159159+(* After *)
160160+let shared_counter = Atomic.make 0
161161+let increment () = Atomic.incr shared_counter
162162+```
163163+164164+### 3. Loop Transformation
165165+166166+**Comprehensions:**
167167+```ocaml
168168+(* Before *)
169169+let result = ref [] in
170170+for i = 1 to n do
171171+ for j = 1 to m do
172172+ if condition i j then
173173+ result := (f i j) :: !result
174174+ done
175175+done;
176176+List.rev !result
177177+178178+(* After *)
179179+[ f i j for i = 1 to n for j = 1 to m when condition i j ]
180180+```
181181+182182+**Filter + Map:**
183183+```ocaml
184184+(* Before *)
185185+list |> List.filter predicate |> List.map transform
186186+187187+(* After *)
188188+[ transform x for x in list when predicate x ]
189189+```
190190+191191+### 4. Memory Management
192192+193193+**Unique Resources:**
194194+```ocaml
195195+(* Define safe resource management *)
196196+type buffer : value
197197+198198+val create : size:int -> buffer @ unique
199199+val free : buffer @ unique -> unit
200200+val write : buffer @ unique -> string -> buffer @ unique
201201+202202+(* Use with functional threading *)
203203+let process_data size data =
204204+ create ~size
205205+ |> write data
206206+ |> write " processed"
207207+ |> fun buf -> let result = extract buf in free buf; result
208208+```
209209+210210+**Immutable Arrays:**
211211+```ocaml
212212+(* Before *)
213213+let readonly_data = [| 1; 2; 3; 4 |]
214214+215215+(* After *)
216216+let readonly_data = [: 1; 2; 3; 4 :]
217217+```
218218+219219+## Syntax Patterns
220220+221221+### Mode Annotations
222222+```ocaml
223223+let func (param @ local) : result @ local = ...
224224+let value : type @ modes = ...
225225+let (pattern @ modes) = expression
226226+function_name @ modes arg1 arg2
227227+```
228228+229229+### Kind Annotations
230230+```ocaml
231231+type ('a : float64) vector
232232+val process : ('a : immediate) -> unit
233233+let func (type (a : value) (b : bits32)) (x : a) (y : b) = ...
234234+```
235235+236236+### Templates (for mode/kind polymorphism)
237237+```ocaml
238238+let%template[@mode m = (global, local)] identity
239239+ : 'a. 'a @ m -> 'a @ m = fun x -> x
240240+241241+module%template[@kind k = (value, float64)] Math = struct
242242+ let add x y = (Float.add [@kind k]) x y
243243+end
244244+```
245245+246246+### Unboxed Type Usage
247247+```ocaml
248248+(* Literals *)
249249+let pi = #3.14159 (* float# *)
250250+let count = #42l (* int32# *)
251251+252252+(* Records *)
253253+type point = #{ x : float#; y : float# }
254254+let origin = #{ x = #0.0; y = #0.0 }
255255+256256+(* Tuples *)
257257+let coords = #(#1.0, #2.0, #3.0)
258258+```
259259+260260+## Error Handling Patterns
261261+262262+### Zero Allocation Checking
263263+```ocaml
264264+let[@zero_alloc] fast_math x y = x + y * 2
265265+let[@zero_alloc assume] external_func x = C.some_func x
266266+```
267267+268268+### Custom Error Messages
269269+```ocaml
270270+let process (x : (_ : immediate)[@error_message "requires immediate type"]) = x
271271+```
272272+273273+## Performance Considerations
274274+275275+1. **Stack vs Heap**: Use `@ local` for temporary values
276276+2. **Unboxed vs Boxed**: Use unboxed types (`#` suffix) for numeric code
277277+3. **Parallel vs Sequential**: Use `Parallel.fork_join2` for independent tasks
278278+4. **SIMD**: Use vector types for data-parallel numeric operations
279279+5. **Zero Allocation**: Mark performance-critical code with `[@zero_alloc]`
280280+6. **Immutable Arrays**: Use `[: ... :]` for read-only data
281281+282282+## Common Pitfalls
283283+284284+### Stack Allocation
285285+- Don't use `@ local` values in tail calls (use `[@nontail]`)
286286+- Avoid partial application with local parameters
287287+- Thread unique values through function calls, don't store in loops
288288+289289+### Parallelism
290290+- Mark shared data as `@ portable contended`
291291+- Use capsules for complex mutable state
292292+- Ensure functions are `@ portable` for parallel use
293293+294294+### Unboxed Types
295295+- Can't be used in tuples or variant constructors (current limitation)
296296+- Limited container type support
297297+- No polymorphic operations (comparison, marshaling)
298298+299299+### Templates
300300+- Use locally abstract types for multiple kinds
301301+- Prefer mono-attributes for instantiation
302302+- Test all generated template instances
303303+304304+## Library Usage
305305+306306+### Key Libraries
307307+- `Parallel`: Parallel computation primitives
308308+- `Atomic`: Thread-safe atomic operations
309309+- `Float_u`, `Int32_u`, etc.: Unboxed numeric operations
310310+- `ocaml_simd`: SIMD vector operations
311311+- `Capsule`: Safe sharing of mutable state
312312+313313+### Common Imports
314314+```ocaml
315315+open Parallel.Std
316316+module F32x4 = Ocaml_simd_sse.Float32x4
317317+```
318318+319319+This reference enables effective OxCaml code generation that leverages the language's advanced features while maintaining safety and performance.