Domain.DLS(3)

πŸ’… Domain.DLS β€” bestie's guide to domain-local storage πŸ’…

okay so this one lives in the OCaml library manual, and ngl the original NAME section literally just says "no description" 😭 β€” so consider this whole page the description, bestie. welcome to Domain.DLS, aka domain-local storage, and it's giving main character energy for concurrent programs. ✨


πŸŽ€ Module πŸŽ€

Module Domain.DLS

and then the docs are literally:

Module DLS
 : sig end

yep that's the whole signature listing. iconic minimalism. πŸ‘‘


🌸 Documentation 🌸

πŸ¦‹ Domain-local Storage πŸ¦‹

type 'a key

so 'a key is the type of a DLS key. that's it, that's the type. it's the little handle you use to reach into a domain's very own private stash of values. πŸ—οΈ


🌟 val new_key 🌟

val new_key : ?split_from_parent:('a -> 'a) -> (unit -> 'a) -> 'a key

new_key f hands you a brand-new key that's bound to the initialiser f, and you use that key to get at domain-local variables. πŸ’œ

if you don't pass split_from_parent: the value for a new domain gets computed on-demand by that new domain β€” meaning the very first get call is what runs the initialiser f and stores the result. lazy girlie behaviour, we respect it. πŸ›‹οΈ

⚠️ Warning, and this one's real: f may get called several times if another call to get happens during initialization on the same domain. only the 'first' value computed will actually be used β€” all the other now-useless values just get yeeted into the void πŸ—‘οΈ. so your initialization function should either support this situation or contain logic to detect this case and fail. no cap, don't skip this part.

if you do pass split_from_parent: spawning a domain will derive the child value (for this key) from the parent value. and here's the thing β€” this computation happens in the parent domain and it always happens, regardless of whether the child domain will ever use it. 😬 so if the splitting function is expensive, or it needs child-side computation, maybe consider using an 'a Lazy.t key instead:

let init () = ...

let split_from_parent parent_value =
  ... parent-side computation ...;
  lazy (
    ... child-side computation ...
  )

let key = Domain.DLS.new_key ~split_from_parent init

let get () = Lazy.force (Domain.DLS.get key)

in this setup, part of the computation happens on the child domain; and specifically, it can access parent_value concurrently with the parent domain β€” which may require explicit synchronization to avoid data races. πŸƒβ€β™€οΈπŸ’¨ so like, be careful, bestie, fr fr.


πŸ’– val get πŸ’–

val get : 'a key -> 'a

get k returns v if there's a value v associated with the key k on the calling domain's domain-local state. otherwise it sets k's value with its initialiser and returns that. simple as. 🫢


πŸ”₯ val set πŸ”₯

val set : 'a key -> 'a -> unit

set k v updates the calling domain's domain-local state so that the key k is associated with the value v. but heads up β€” it overwrites any previous value associated with k, and that previous value cannot be restored later. so like, no undo button, no take-backs, it's gone gone. πŸ’€


anyway that's the whole page, you ate that πŸ“πŸ’…

OCamldoc made this one, dated 2026-06-22, and it's page Domain.DLS(3) of the manual β€” mwah, go forth and store things domain-locally πŸ‘‘βœ¨

πŸ“¦ where this page comes from