Stdlib.Obj(3)

πŸ’– Stdlib.Obj(3) β€” the "yes bestie we're doing unsafe stuff" module πŸ’–

ok so real talk: this page lives in the OCaml library manual, and it's the one your CS prof warns you about at 2am. It's Stdlib.Obj, module Obj, which the docs literally declare as (module Stdlib__Obj). no description was given in the original, so like… the vibe is the description, iykyk 🫢


✨ NAME ✨

Stdlib.Obj β€” no description. that's it. that's the name. she's mysterious, she's powerful, she's giving main character energy with zero explanation πŸ’…


πŸ¦‹ Module πŸ¦‹

Module Stdlib.Obj


🌸 Documentation 🌸

girl. okay. here's the whole thing, item by item, no cap:

Module Obj
 : (module Stdlib__Obj)

πŸŽ€ the types

  • type t β€” the abstract opaque blob type. the raw "thing" that everything secretly is.
  • type raw_data = nativeint β€” yup, raw data is just a nativeint. that's the whole definition. slay.

πŸ”₯ the core functions

  • val repr : 'a -> t β€” takes literally anything and hands you back its t representation. peek behind the curtain.
  • val obj : t -> 'a β€” the reverse glow-up: turn a t back into "some 'a". trust the process (and the type system, which is being very brave right now).
  • val magic : 'a -> 'b β€” the iconique one. any type to any other type. it's giving chaos, it's giving power, it's giving please know what you're doing 😭
  • val is_block : t -> bool β€” true if it's a block, false otherwise. vibe check for blocks.
  • val is_int : t -> bool β€” true if it's an integer. vibe check for ints.
  • val tag : t -> int β€” grab the tag of the thing.
  • val size : t -> int β€” grab the size of the thing.
  • val reachable_words : t -> int β€” this one's a whole paragraph, buckle up: it computes the total size (in words, including the headers) of all heap blocks accessible from the argument. and yes, statically allocated blocks are included. she's thorough. ✨
Since 4.04 β€” reachable_words has been here since 4.04, periodt.

πŸ’œ the field accessors

  • val field : t -> int -> t β€” read the field at that index.
  • val set_field : t -> int -> t -> unit β€” write a field at that index.
⚠️ BIG WARNING BESTIE, READ THIS ONE ⚠️ when using flambda: set_field MUST NOT be called on immutable blocks. (blocks allocated in C stubs, or with new_block below, are always considered mutable. that's the safe zone.) the exact same rule goes for set_double_field. 🧠 for experts only: set_field et al can be made safe by first wrapping the block in Sys.opaque_identity, so any information about its contents will not be propagated. that's the trick. literally the trick.
  • val double_field : t -> int -> float β€” read a double field.
  • val set_double_field : t -> int -> float -> unit β€” write a double field. (see the flambda warning above, it applies here too, don't act surprised πŸ™ˆ)
  • val raw_field : t -> int -> raw_data β€” read a raw field.
  • val set_raw_field : t -> int -> raw_data -> unit β€” write a raw field.

🧚 block construction & friends

  • val new_block : int -> int -> t β€” make a fresh new block. yes, blocks made this way count as mutable. πŸ’–
  • val dup : t -> t β€” duplicate it.
  • val add_offset : t -> Int32.t -> t β€” shift it by an Int32.t offset.
  • val with_tag : int -> t -> t β€” same block, different tag.

πŸ‘‘ the legendary tag constants

these are the crown jewels, list them all, don't skip a single one:

  • val first_non_constant_constructor_tag : int
  • val last_non_constant_constructor_tag : int
  • val forcing_tag : int
  • val cont_tag : int
  • val lazy_tag : int
  • val closure_tag : int
  • val object_tag : int
  • val infix_tag : int
  • val forward_tag : int
  • val no_scan_tag : int
  • val abstract_tag : int
  • val string_tag : int
  • val double_tag : int
  • val double_array_tag : int
  • val custom_tag : int
  • val int_tag : int
  • val out_of_heap_tag : int
  • val unaligned_tag : int

🌈 submodules

  • module Extension_constructor : sig end β€” yeah, the signature's empty from out here. it's a whole thing. πŸ€·β€β™€οΈ
  • module Ephemeron : sig end β€” same deal, empty sig end in this view.

🌟 quick reminder: this whole module is the "for experts, for real, we mean it" part of the stdlib. the fact that it's documented doesn't make it a cuddle puddle. respect the blocks. πŸ’€

that's the whole page, bestie, every single val, every tag, every warning, nothing skipped πŸ«ΆπŸ’–βœ¨

made with love by OCamldoc, dated 2026-06-22, for Stdlib.Obj(3) β€” go forth and be responsible with that magic πŸ’…πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from