this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

experiment

+329
+10
CLAUDE.md
··· 1 + I have a checkout of OCaml in ocaml/ and a forked version with lots of 2 + extensions in oxcaml/. 3 + 4 + I want you to look carefully through the various documentations in oxcaml, 5 + particularly the extensions in oxcaml/jane/doc/extensions. 6 + 7 + Spawn subagents to understand each extension, distilling down each one to a set 8 + of guidelines you can use when porting OCaml code to use the OxCaml extensions. 9 + Then write a llms.txt that captures all this knowledge for future code models 10 + to refer to as part of their context when writing oxcaml code.
+319
llms.txt
··· 1 + # OxCaml Language Model Context 2 + 3 + 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. 4 + 5 + ## Core OxCaml Philosophy 6 + 7 + OxCaml 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 *) 94 + let process data = 95 + let temp = expensive_computation data in 96 + extract_result temp 97 + 98 + (* After *) 99 + let process data = 100 + let temp @ local = expensive_computation data in 101 + extract_result temp 102 + ``` 103 + 104 + **Unboxed Numeric Code:** 105 + ```ocaml 106 + (* Before *) 107 + let distance x1 y1 x2 y2 = 108 + sqrt ((x2 -. x1) ** 2.0 +. (y2 -. y1) ** 2.0) 109 + 110 + (* After *) 111 + let 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 *) 120 + let add_arrays a b = Array.map2 (+.) a b 121 + 122 + (* After *) 123 + module F32x4 = Ocaml_simd_sse.Float32x4 124 + let add_vectors v1 v2 = F32x4.add v1 v2 125 + ``` 126 + 127 + ### 2. Parallel Programming 128 + 129 + **Basic Parallelism:** 130 + ```ocaml 131 + (* Before *) 132 + let map_reduce f reduce_f init list = 133 + List.fold_left (fun acc x -> reduce_f acc (f x)) init list 134 + 135 + (* After *) 136 + let 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 *) 156 + let shared_counter = ref 0 157 + let increment () = incr shared_counter 158 + 159 + (* After *) 160 + let shared_counter = Atomic.make 0 161 + let increment () = Atomic.incr shared_counter 162 + ``` 163 + 164 + ### 3. Loop Transformation 165 + 166 + **Comprehensions:** 167 + ```ocaml 168 + (* Before *) 169 + let result = ref [] in 170 + for 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 175 + done; 176 + List.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 *) 185 + list |> 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 *) 196 + type buffer : value 197 + 198 + val create : size:int -> buffer @ unique 199 + val free : buffer @ unique -> unit 200 + val write : buffer @ unique -> string -> buffer @ unique 201 + 202 + (* Use with functional threading *) 203 + let 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 *) 213 + let readonly_data = [| 1; 2; 3; 4 |] 214 + 215 + (* After *) 216 + let readonly_data = [: 1; 2; 3; 4 :] 217 + ``` 218 + 219 + ## Syntax Patterns 220 + 221 + ### Mode Annotations 222 + ```ocaml 223 + let func (param @ local) : result @ local = ... 224 + let value : type @ modes = ... 225 + let (pattern @ modes) = expression 226 + function_name @ modes arg1 arg2 227 + ``` 228 + 229 + ### Kind Annotations 230 + ```ocaml 231 + type ('a : float64) vector 232 + val process : ('a : immediate) -> unit 233 + let func (type (a : value) (b : bits32)) (x : a) (y : b) = ... 234 + ``` 235 + 236 + ### Templates (for mode/kind polymorphism) 237 + ```ocaml 238 + let%template[@mode m = (global, local)] identity 239 + : 'a. 'a @ m -> 'a @ m = fun x -> x 240 + 241 + module%template[@kind k = (value, float64)] Math = struct 242 + let add x y = (Float.add [@kind k]) x y 243 + end 244 + ``` 245 + 246 + ### Unboxed Type Usage 247 + ```ocaml 248 + (* Literals *) 249 + let pi = #3.14159 (* float# *) 250 + let count = #42l (* int32# *) 251 + 252 + (* Records *) 253 + type point = #{ x : float#; y : float# } 254 + let origin = #{ x = #0.0; y = #0.0 } 255 + 256 + (* Tuples *) 257 + let coords = #(#1.0, #2.0, #3.0) 258 + ``` 259 + 260 + ## Error Handling Patterns 261 + 262 + ### Zero Allocation Checking 263 + ```ocaml 264 + let[@zero_alloc] fast_math x y = x + y * 2 265 + let[@zero_alloc assume] external_func x = C.some_func x 266 + ``` 267 + 268 + ### Custom Error Messages 269 + ```ocaml 270 + let process (x : (_ : immediate)[@error_message "requires immediate type"]) = x 271 + ``` 272 + 273 + ## Performance Considerations 274 + 275 + 1. **Stack vs Heap**: Use `@ local` for temporary values 276 + 2. **Unboxed vs Boxed**: Use unboxed types (`#` suffix) for numeric code 277 + 3. **Parallel vs Sequential**: Use `Parallel.fork_join2` for independent tasks 278 + 4. **SIMD**: Use vector types for data-parallel numeric operations 279 + 5. **Zero Allocation**: Mark performance-critical code with `[@zero_alloc]` 280 + 6. **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 315 + open Parallel.Std 316 + module F32x4 = Ocaml_simd_sse.Float32x4 317 + ``` 318 + 319 + This reference enables effective OxCaml code generation that leverages the language's advanced features while maintaining safety and performance.