Summary of OxCaml changes for llms.txt
at main 8.5 kB view raw
1# OxCaml Language Model Context 2 3OxCaml 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. 4 5## Core OxCaml Philosophy 6 7OxCaml extends OCaml with: 8- **Zero-allocation programming**: Stack allocation, unboxed types, comprehensive optimization 9- **Parallelism with safety**: Data-race-free parallel programming through modes 10- **Fine-grained control**: Modes, kinds, uniqueness for memory and performance optimization 11- **Enhanced expressiveness**: Comprehensions, SIMD, templates for better abstractions 12 13## Quick Reference: Key Extensions 14 15### Stack Allocation (`local` mode) 16- Use `@ local` for values that don't escape scope 17- Enables stack allocation, reducing GC pressure 18- Use `exclave_` to return local values from functions 19- `stack_` forces stack allocation (fails if impossible) 20 21### Unboxed Types (layouts) 22- `float#`, `int32#`, `int64#` for unboxed numeric types 23- Literals: `#3.14` (float#), `#123l` (int32#), `#456L` (int64#) 24- Unboxed records: `#{ field = value }` 25- Unboxed tuples: `#(a, b, c)` 26 27### Parallelism 28- Use `Parallel.fork_join2` for parallel computation 29- Mark data `@ portable` for cross-domain sharing 30- Use `@ contended` for thread-safe mutable data 31- Capsules for complex shared mutable state 32 33### Comprehensions 34- List: `[ expr for pat in seq when cond ]` 35- Array: `[| expr for pat in seq when cond |]` 36- Range iteration: `for i = 1 to n` 37- Parallel iteration: `for x in xs and y in ys` 38 39### SIMD 40- Vector types: `float32x4#`, `int32x4#`, etc. 41- Load from memory: `Float32x4.String.get` 42- Operations: `Float32x4.add`, `Float32x4.mul` 43- Use `[@unboxed]` for C interop 44 45## Mode System Reference 46 47### Locality Axis (scope) 48- `global` (default): May escape scope 49- `local`: Cannot escape scope, enables stack allocation 50 51### Contention Axis (thread safety) 52- `uncontended` (default): Single thread access 53- `shared`: Multiple threads read-only 54- `contended`: Multiple threads with writes 55 56### Portability Axis (thread movement) 57- `nonportable` (default): Cannot move between threads 58- `portable`: May move across thread boundaries 59 60### Uniqueness Axis (aliasing) 61- `aliased` (default): Multiple references 62- `unique`: Single reference only 63 64### Other Axes 65- Linearity: `many` (default) vs `once` (single use) 66- Yielding: `unyielding` (default) vs `yielding` (effects) 67- Visibility: `read_write` (default) vs `read` vs `immutable` 68- Statefulness: `stateful` (default) vs `observing` vs `stateless` 69 70## Kind System Reference 71 72### Layouts 73- `value`: Standard OCaml values 74- `immediate`: Int-like types 75- `float64`, `float32`: Unboxed floats 76- `bits64`, `bits32`: Unboxed integers 77- `word`: Machine word 78- `vec128`, `vec256`: SIMD vectors 79- `any`: Maximum layout 80 81### Kind Abbreviations 82- `immediate`: Values like `int`, `bool` 83- `immutable_data`: Plain immutable data 84- `mutable_data`: Plain mutable data 85- `any_non_null`: Any layout excluding NULL 86 87## Migration Guidelines: OCaml to OxCaml 88 89### 1. Performance Optimization 90 91**Stack Allocation:** 92```ocaml 93(* Before *) 94let process data = 95 let temp = expensive_computation data in 96 extract_result temp 97 98(* After *) 99let process data = 100 let temp @ local = expensive_computation data in 101 extract_result temp 102``` 103 104**Unboxed Numeric Code:** 105```ocaml 106(* Before *) 107let distance x1 y1 x2 y2 = 108 sqrt ((x2 -. x1) ** 2.0 +. (y2 -. y1) ** 2.0) 109 110(* After *) 111let distance x1 y1 x2 y2 = 112 Float_u.sqrt (Float_u.add 113 (Float_u.pow (Float_u.sub x2 x1) #2.0) 114 (Float_u.pow (Float_u.sub y2 y1) #2.0)) 115``` 116 117**Array Processing with SIMD:** 118```ocaml 119(* Before *) 120let add_arrays a b = Array.map2 (+.) a b 121 122(* After *) 123module F32x4 = Ocaml_simd_sse.Float32x4 124let add_vectors v1 v2 = F32x4.add v1 v2 125``` 126 127### 2. Parallel Programming 128 129**Basic Parallelism:** 130```ocaml 131(* Before *) 132let map_reduce f reduce_f init list = 133 List.fold_left (fun acc x -> reduce_f acc (f x)) init list 134 135(* After *) 136let parallel_map_reduce par f reduce_f init list = 137 let process chunk = 138 List.fold_left (fun acc x -> reduce_f acc (f x)) init chunk 139 in 140 match list with 141 | [] -> init 142 | _ -> 143 let mid = List.length list / 2 in 144 let left, right = List.split_at mid list in 145 let left_result, right_result = 146 Parallel.fork_join2 par 147 (fun _ -> process left) 148 (fun _ -> process right) 149 in 150 reduce_f left_result right_result 151``` 152 153**Shared Mutable State:** 154```ocaml 155(* Before *) 156let shared_counter = ref 0 157let increment () = incr shared_counter 158 159(* After *) 160let shared_counter = Atomic.make 0 161let increment () = Atomic.incr shared_counter 162``` 163 164### 3. Loop Transformation 165 166**Comprehensions:** 167```ocaml 168(* Before *) 169let result = ref [] in 170for i = 1 to n do 171 for j = 1 to m do 172 if condition i j then 173 result := (f i j) :: !result 174 done 175done; 176List.rev !result 177 178(* After *) 179[ f i j for i = 1 to n for j = 1 to m when condition i j ] 180``` 181 182**Filter + Map:** 183```ocaml 184(* Before *) 185list |> List.filter predicate |> List.map transform 186 187(* After *) 188[ transform x for x in list when predicate x ] 189``` 190 191### 4. Memory Management 192 193**Unique Resources:** 194```ocaml 195(* Define safe resource management *) 196type buffer : value 197 198val create : size:int -> buffer @ unique 199val free : buffer @ unique -> unit 200val write : buffer @ unique -> string -> buffer @ unique 201 202(* Use with functional threading *) 203let process_data size data = 204 create ~size 205 |> write data 206 |> write " processed" 207 |> fun buf -> let result = extract buf in free buf; result 208``` 209 210**Immutable Arrays:** 211```ocaml 212(* Before *) 213let readonly_data = [| 1; 2; 3; 4 |] 214 215(* After *) 216let readonly_data = [: 1; 2; 3; 4 :] 217``` 218 219## Syntax Patterns 220 221### Mode Annotations 222```ocaml 223let func (param @ local) : result @ local = ... 224let value : type @ modes = ... 225let (pattern @ modes) = expression 226function_name @ modes arg1 arg2 227``` 228 229### Kind Annotations 230```ocaml 231type ('a : float64) vector 232val process : ('a : immediate) -> unit 233let func (type (a : value) (b : bits32)) (x : a) (y : b) = ... 234``` 235 236### Templates (for mode/kind polymorphism) 237```ocaml 238let%template[@mode m = (global, local)] identity 239 : 'a. 'a @ m -> 'a @ m = fun x -> x 240 241module%template[@kind k = (value, float64)] Math = struct 242 let add x y = (Float.add [@kind k]) x y 243end 244``` 245 246### Unboxed Type Usage 247```ocaml 248(* Literals *) 249let pi = #3.14159 (* float# *) 250let count = #42l (* int32# *) 251 252(* Records *) 253type point = #{ x : float#; y : float# } 254let origin = #{ x = #0.0; y = #0.0 } 255 256(* Tuples *) 257let coords = #(#1.0, #2.0, #3.0) 258``` 259 260## Error Handling Patterns 261 262### Zero Allocation Checking 263```ocaml 264let[@zero_alloc] fast_math x y = x + y * 2 265let[@zero_alloc assume] external_func x = C.some_func x 266``` 267 268### Custom Error Messages 269```ocaml 270let process (x : (_ : immediate)[@error_message "requires immediate type"]) = x 271``` 272 273## Performance Considerations 274 2751. **Stack vs Heap**: Use `@ local` for temporary values 2762. **Unboxed vs Boxed**: Use unboxed types (`#` suffix) for numeric code 2773. **Parallel vs Sequential**: Use `Parallel.fork_join2` for independent tasks 2784. **SIMD**: Use vector types for data-parallel numeric operations 2795. **Zero Allocation**: Mark performance-critical code with `[@zero_alloc]` 2806. **Immutable Arrays**: Use `[: ... :]` for read-only data 281 282## Common Pitfalls 283 284### Stack Allocation 285- Don't use `@ local` values in tail calls (use `[@nontail]`) 286- Avoid partial application with local parameters 287- Thread unique values through function calls, don't store in loops 288 289### Parallelism 290- Mark shared data as `@ portable contended` 291- Use capsules for complex mutable state 292- Ensure functions are `@ portable` for parallel use 293 294### Unboxed Types 295- Can't be used in tuples or variant constructors (current limitation) 296- Limited container type support 297- No polymorphic operations (comparison, marshaling) 298 299### Templates 300- Use locally abstract types for multiple kinds 301- Prefer mono-attributes for instantiation 302- Test all generated template instances 303 304## Library Usage 305 306### Key Libraries 307- `Parallel`: Parallel computation primitives 308- `Atomic`: Thread-safe atomic operations 309- `Float_u`, `Int32_u`, etc.: Unboxed numeric operations 310- `ocaml_simd`: SIMD vector operations 311- `Capsule`: Safe sharing of mutable state 312 313### Common Imports 314```ocaml 315open Parallel.Std 316module F32x4 = Ocaml_simd_sse.Float32x4 317``` 318 319This reference enables effective OxCaml code generation that leverages the language's advanced features while maintaining safety and performance.