Misc(3)

๐Ÿ’– Misc(3) โ€” OCaml library ๐Ÿ’–

Manual name: Misc(3). Library: OCaml library. Okay bestie, this is the miscellaneous toolbox โ€” unstable, part of the compiler libs, and lowkey full of useful little gremlins. Letโ€™s get into it. โœจ

๐ŸŒธ NAME ๐ŸŒธ

Misc - Miscellaneous useful types and functions

๐Ÿงฉ Module ๐Ÿงฉ

Module Misc

๐Ÿ“š Documentation ๐Ÿ“š

Module Misc
 : sig end

Miscellaneous useful types and functions

โš ๏ธ Warning: this module is unstable and part of Compiler_libs .

๐Ÿšจ Reporting fatal errors ๐Ÿšจ

  • val fatal_error : string -> 'a โ€” Raise the Fatal_error exception with the given string. Short king behavior. ๐Ÿ’…
  • val fatal_errorf : ('a, Format.formatter, unit, 'b) format4 -> 'a โ€” Format the arguments according to the given format string and raise Fatal_error with the resulting string. Fancy formatting before the chaos. ๐ŸŽ€
  • exception Fatal_error โ€” yep, thatโ€™s the exception declaration, right there.

๐Ÿงผ Exceptions and finalization ๐Ÿงผ

  • val try_finally : ?always:(unit -> unit) -> ?exceptionally:(unit -> unit) -> (unit -> 'a) -> 'a โ€” try_finally work ~always ~exceptionally is designed to run code in work that may fail with an exception, and it has two kind of cleanup routines: always, that must be run after any execution of the function (typically, freeing system resources), and exceptionally, that should be run only if work or always failed with an exception (typically, undoing user-visible state changes that would only make sense if the function completes correctly). Itโ€™s giving responsible main character energy. ๐Ÿซถ

Example from the page:

let objfile = outputprefix ^ ".cmo" in
let oc = open_out_bin objfile in
Misc.try_finally
  (fun () ->
     bytecode
     ++ Timings.(accumulate_time (Generate sourcefile))
         (Emitcode.to_file oc modulename objfile);
     Warnings.check_fatal ())
  ~always:(fun () -> close_out oc)
  ~exceptionally:(fun _exn -> remove_file objfile);

If exceptionally fail with an exception, it is propagated as usual.

If always or exceptionally use exceptions internally for control-flow but do not raise, then try_finally is careful to preserve any exception backtrace coming from work or always for easier debugging.

  • val reraise_preserving_backtrace : exn -> (unit -> unit) -> 'a โ€” reraise_preserving_backtrace e f is (f (); raise e) except that the current backtrace is preserved, even if f uses exceptions internally. Backtrace protection? We love to see it. ๐Ÿ”ฅ

๐Ÿ“‹ List operations ๐Ÿ“‹

  • val map_end : ('a -> 'b) -> 'a list -> 'b list -> 'b list โ€” map_end f l t is map f l @ t , just more efficient. No cap.
  • val rev_map_end : ('a -> 'b) -> 'a list -> 'b list -> 'b list โ€” The page literally says: map_end f l t is map f (rev l) @ t , just more efficient. We are not fixing the wording, we are respecting the lore. ๐Ÿฆ‹
  • val map_left_right : ('a -> 'b) -> 'a list -> 'b list โ€” Like List.map , with guaranteed left-to-right evaluation order. Order matters, bestie. โœจ
  • val for_all2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool โ€” Same as List.for_all but for a binary predicate. In addition, this for_all2 never fails: given two lists with different lengths, it returns false. No crashing, just honesty. ๐Ÿ˜ญ
  • val replicate_list : 'a -> int -> 'a list โ€” replicate_list elem n is the list with n elements all identical to elem . Copy-paste but make it functional. ๐ŸŽ€
  • val list_remove : 'a -> 'a list -> 'a list โ€” list_remove x l returns a copy of l with the first element equal to x removed. First match only, periodt. ๐Ÿ’…
  • val split_last : 'a list -> 'a list * 'a โ€” Return the last element and the other elements of the given list. Last one out, plus the rest. ๐Ÿซถ
  • val repeated_label : (string option * 'a) list -> string option โ€” Detects a repeated label - for use with labeled tuples. Label detective behavior. ๐Ÿ”

๐Ÿ—‚๏ธ Hash table operations ๐Ÿ—‚๏ธ

  • val create_hashtable : int -> ('a * 'b) list -> ('a, 'b) Hashtbl.t โ€” Create a hashtable with the given initial size and fills it with the given bindings. Preloaded and ready. ๐ŸŒˆ

๐Ÿงฑ Extensions to the standard library ๐Ÿงฑ

  • module Stdlib : sig end โ€” module signature, thatโ€™s the whole entry. Mysterious but valid. ๐ŸŽ€

๐Ÿ“ Operations on files and file paths ๐Ÿ“

  • val find_in_path : string list -> string -> string โ€” Search a file in a list of directories.
  • val find_in_path_rel : string list -> string -> string โ€” Search a relative file in a list of directories.
  • val normalized_unit_filename : string -> (string, string) Result.t โ€” Normalize file name Foo.ml to foo.ml , using NFC and case-folding. Return Error if the input is not a valid utf-8 byte sequence. Normalization era. โœจ
  • val find_in_path_normalized : string list -> string -> string โ€” Same as Misc.find_in_path_rel , but search also for normalized unit filename, i.e. if name is Foo.ml , allow /path/Foo.ml and /path/foo.ml to match. Case-folding said โ€œboth can stay.โ€ ๐Ÿ’…
  • val remove_file : string -> unit โ€” Delete the given file if it exists and is a regular file. Does nothing for other kinds of files. Never raises an error. No drama, no exceptions. ๐Ÿซถ
  • val expand_directory : string -> string -> string โ€” expand_directory alt file eventually expands a + at the beginning of file into alt (an alternate root directory). Plus sign glow-up. โญ
  • val split_path_contents : ?sep:char -> string -> string list โ€” split_path_contents ?sep s interprets s as the value of a "PATH"-like variable and returns the corresponding list of directories. s is split using the platform-specific delimiter, or ~sep if it is passed. Returns the empty list if s is empty. PATH vibes, parsed. ๐Ÿฆ‹
  • val copy_file : in_channel -> out_channel -> unit โ€” copy_file ic oc reads the contents of file ic and copies them to oc . It stops when encountering EOF on ic . Copy until EOF, no cap. ๐ŸŽ€
  • val copy_file_chunk : in_channel -> out_channel -> int -> unit โ€” copy_file_chunk ic oc n reads n bytes from ic and copies them to oc . It raises End_of_file when encountering EOF on ic . Chunked, and it will raise if the file ghosts you. ๐Ÿ˜ญ
  • val string_of_file : in_channel -> string โ€” string_of_file ic reads the contents of file ic and copies them to a string. It stops when encountering EOF on ic . File to string, iconic. ๐Ÿ’œ
  • val output_to_file_via_temporary : ?mode:open_flag list -> string -> (string -> out_channel -> 'a) -> 'a โ€” Produce output in temporary file, then rename it (as atomically as possible) to the desired output file name. output_to_file_via_temporary filename fn opens a temporary file which is passed to fn (name + output channel). When fn returns, the channel is closed and the temporary file is renamed to filename . Temporary era, then atomic-ish rename. ๐Ÿ”ฅ
  • val protect_writing_to_file : filename:string -> f:(out_channel -> 'a) -> 'a โ€” Open the given filename for writing (in binary mode), pass the out_channel to the given function, then close the channel. If the function raises an exception then filename will be removed. Cleanup on failure? We stan. ๐Ÿซถ
  • val concat_null_terminated : string list -> string โ€” concat_null_terminated [x1;x2; ... xn] is x1 ^ "\000" ^ x2 ^ "\000" ^ ... ^ xn ^ "\000". Null-terminated join, exactly like that. โœจ
  • val split_null_terminated : string -> string list โ€” split_null_terminated s is similar String.split_on_char '\000' but ignores the trailing separator, if any. Trailing separator? Ignored. ๐ŸŽ€
  • val chop_extensions : string -> string โ€” Return the given file name without its extensions. The extensions is the longest suffix starting with a period and not including a directory separator, .xyz.uvw for instance. Return the given name if it does not contain an extension. Extensions chopped, name preserved. ๐Ÿ’…

๐Ÿ”ข Integer operations ๐Ÿ”ข

  • val log2 : int -> int โ€” log2 n returns s such that n = 1 lsl s if n is a power of 2. Power-of-two detective. ๐Ÿ”
  • val align : int -> int -> int โ€” align n a rounds n upwards to a multiple of a (a power of 2). Round up, bestie. โญ
  • val no_overflow_add : int -> int -> bool โ€” no_overflow_add n1 n2 returns true if the computation of n1 + n2 does not overflow. Overflow check, no surprises. ๐ŸŽ€
  • val no_overflow_sub : int -> int -> bool โ€” no_overflow_sub n1 n2 returns true if the computation of n1 - n2 does not overflow. Subtraction safety check. ๐Ÿฆ‹
  • val no_overflow_mul : int -> int -> bool โ€” no_overflow_mul n1 n2 returns true if the computation of n1 * n2 does not overflow. Multiplication, but keep it contained. ๐Ÿ’…
  • val no_overflow_lsl : int -> int -> bool โ€” no_overflow_lsl n k returns true if the computation of n lsl k does not overflow. Shift left with a vibe check. ๐ŸŒˆ
  • val letter_of_int : int -> string โ€” signature only on this page, bestie. No extra lore here. ๐ŸŽ€
  • module Int_literal_converter : sig end โ€” module signature, thatโ€™s it. Mysterious module energy. โœจ
  • val find_first_mono : (int -> bool) -> int โ€” find_first_mono p takes an integer predicate p : int -> bool that we assume:
    1. is monotonic on natural numbers: if a <= b then p a implies p b ,
    2. is satisfied for some natural numbers in range 0; max_int (this is equivalent to: p max_int = true ).

find_first_mono p is the smallest natural number N that satisfies p , computed in O(log(N)) calls to p .

Our implementation supports two cases where the preconditions on p are not respected:

-If p is always false , we silently return max_int instead of looping or crashing.

-If p is non-monotonic but eventually true, we return some satisfying value.

๐Ÿ”ค String operations ๐Ÿ”ค

  • val search_substring : string -> string -> int -> int โ€” search_substring pat str start returns the position of the first occurrence of string pat in string str . Search starts at offset start in str . Raise Not_found if pat does not occur. Search era, with a Not_found cliffhanger. ๐Ÿ˜ญ
  • val replace_substring : before:string -> after:string -> string -> string โ€” replace_substring ~before ~after str replaces all occurrences of before with after in str and returns the resulting string. Global replace, no crumbs. ๐Ÿ’…
  • val rev_split_words : string -> string list โ€” rev_split_words s splits s in blank-separated words, and returns the list of words in reverse order. Words, but backwards. ๐Ÿฆ‹
  • val cut_at : string -> char -> string * string โ€” cut_at s c returns a pair containing the sub-string before the first occurrence of c in s , and the sub-string after the first occurrence of c in s .
let (before, after) = String.cut_at s c in
    before ^ String.make 1 c ^ after

is the identity if s contains c .

Raise Not_found if the character does not appear in the string.

Since 4.01

  • val ordinal_suffix : int -> string โ€” ordinal_suffix n is the appropriate suffix to append to the numeral n as an ordinal number: 1 -> "st" , 2 -> "nd" , 3 -> "rd" , 4 -> "th" , and so on. Handles larger numbers (e.g., 42 -> "nd" ) and the numbers 11--13 (which all get "th" ) correctly. Ordinal grammar ate. ๐ŸŽ€
  • val normalise_eol : string -> string โ€” normalise_eol s returns a fresh copy of s with any '\r' characters removed. Intended for pre-processing text which will subsequently be printed on a channel which performs EOL transformations (i.e. Windows). Windows preprocessing realness. ๐Ÿซถ
  • val delete_eol_spaces : string -> string โ€” delete_eol_spaces s returns a fresh copy of s with any end of line spaces removed. Intended to normalize the output of the toplevel for tests. Test-output cleanup behavior. โœจ

๐Ÿ”— Operations on references ๐Ÿ”—

type ref_and_value =
 | R : 'a ref * 'a -> ref_and_value
  • val protect_refs : ref_and_value list -> (unit -> 'a) -> 'a โ€” protect_refs l f temporarily sets r to v for each R (r, v) in l while executing f . The previous contents of the references is restored even if f raises an exception, without altering the exception backtrace. Reference protection with backtrace respect. ๐Ÿ’…
  • val get_ref : 'a list ref -> 'a list โ€” get_ref lr returns the content of the list reference lr and reset its content to the empty list. Read it, then reset it. ๐Ÿฆ‹
  • val set_or_ignore : ('a -> 'b option) -> 'b option ref -> 'a -> unit โ€” set_or_ignore f opt x sets opt to f x if it returns Some _ , or leaves it unmodified if it returns None . Set only if thereโ€™s a Some, bestie. ๐ŸŽ€

๐ŸŽ Operations on triples and quadruples ๐ŸŽ

  • val fst3 : 'a * 'b * 'c -> 'a โ€” first of three. Accessor.
  • val snd3 : 'a * 'b * 'c -> 'b โ€” second of three. Accessor.
  • val thd3 : 'a * 'b * 'c -> 'c โ€” third of three. Accessor.
  • val fst4 : 'a * 'b * 'c * 'd -> 'a โ€” first of four. Accessor.
  • val snd4 : 'a * 'b * 'c * 'd -> 'b โ€” second of four. Accessor.
  • val thd4 : 'a * 'b * 'c * 'd -> 'c โ€” third of four. Accessor.
  • val for4 : 'a * 'b * 'c * 'd -> 'd โ€” fourth of four. Yes, itโ€™s named for4, and yes, thatโ€™s iconic. ๐ŸŒˆ

โœจ Spell checking and โ€œdid you meanโ€ suggestions โœจ

  • val edit_distance : string -> string -> int -> int option โ€” okay so edit_distance a b cutoff computes the edit distance between strings a and b. To help efficiency, it uses a cutoff: if the distance d is smaller than cutoff, it returns Some d, else None. The distance algorithm currently used is Damerau-Levenshtein: it computes the number of insertion, deletion, substitution of letters, or swapping of adjacent letters to go from one word to the other. The particular algorithm may change in the future. ๐Ÿ‘€
  • val spellcheck : string list -> string -> string list โ€” spellcheck env name takes a list of names env that exist in the current environment and an erroneous name, and returns a list of suggestions taken from env, that are close enough to name that it may be a typo for one of them. Bestie, it's giving โ€œdid you meanโ€ energy fr fr. ๐Ÿ’…
  • val align_hint : prefix:string -> main:Format_doc.t -> hint:Format_doc.t -> Format_doc.t * Format_doc.t โ€” aligned_hint main hint vertically aligns a main message and a hint message. The vertical alignment is controlled by the use of @{<ralign> ... @} boxes: the start of one box, in either the hint or the main message, will be shifted on the left to ensure that the end of the two boxes are vertically aligned, taking in account a pre-existing prefix before the main message. For instance:
let main, sub =
  align_hint
    ~prefix:"Error: "
    (doc_printf "@{<ralign>The value @}%a is not an instance variable"
      Style.inline_code "foobar"
    )
    (doc_printf
      "@{<ralign>Did you mean @}%a" Style.inline_code "foobaz"
    ) in
   printf "Error: %a%a" pp_doc main pp_doc sub

produces the following text:

Error:   The value "foobaz" is not an instance variable
Hint: Did you mean "foobar"?

where the main message has been shifted to the left to align "foobaz" and "foobar". โœจ

  • val align_error_hint : main:Format_doc.t -> hint:Format_doc.t -> Format_doc.t * Format_doc.t โ€” Same as align_hint ~prefix:"Error: ". That's it, that's the whole vibe. ๐ŸŽ€
  • val aligned_hint : prefix:string -> Format_doc.formatter -> ('a, Format_doc.formatter, unit, Format_doc.t option -> unit) format4 -> 'a โ€” aligned_hint ~prefix fmt ... hint align the potential hint with the main error message generated by the format string fmt before printing the two message. ๐Ÿซถ
  • val did_you_mean : ?pp:string Format_doc.printer -> string list -> Format_doc.t option โ€” did_you_mean ~pp choices hints that the user may have meant one of the option in choices. Each choice is printed with the pp function, or Style.inline_code if pp = None. ๐Ÿฆ‹
  • module Color : sig end โ€” listed right here, exactly as module Color : sig end. No extra docs attached, no cap. ๐Ÿ’œ

๐ŸŒˆ Color support detection

Color support detection is a whole heading, bestie. It's giving โ€œwe detect color supportโ€ main character energy. ๐ŸŒธ

๐Ÿ’… Styling handling for terminal output

  • module Style : sig end โ€” the Style module is listed exactly as module Style : sig end. Iconic. ๐Ÿ‘‘
  • module Error_style : sig end โ€” and Error_style is listed exactly as module Error_style : sig end. Periodt. ๐Ÿ’…

๐Ÿ–จ๏ธ Formatted output

  • val print_if : Format.formatter -> bool ref -> (Format.formatter -> 'a -> unit) -> 'a -> 'a โ€” print_if ppf flag fmt x prints x with fmt on ppf if b is true. That's the whole note, fr fr. โœจ
  • val print_see_manual : int list Format_doc.printer โ€” See manual section. Literally that. ๐ŸŽ€

โš™๏ธ Displaying configuration variables

  • val show_config_and_exit : unit -> unit โ€” Display the values of all compiler configuration variables from module Config, then exit the program with code 0. Slay, then dip. ๐Ÿ’…
  • val show_config_variable_and_exit : string -> unit โ€” Display the value of the given configuration variable, then exit the program with code 0. Same energy, one variable at a time. โœจ

๐Ÿ—บ๏ธ Handling of build maps

Build maps cause the compiler to normalize file names embedded in object files, thus leading to more reproducible builds. Reproducible builds are so valid. ๐Ÿซถ

  • val get_build_path_prefix_map : unit -> Build_path_prefix_map.map option โ€” Returns the map encoded in the BUILD_PATH_PREFIX_MAP environment variable. ๐Ÿฆ‹
  • val invert_build_path_prefix_map : string -> string list โ€” Returns the potential paths (in priority order) from which the given path can originate from before rewrite using BUILD_PATH_PREFIX_MAP environment variable. ๐ŸŒˆ
  • val debug_prefix_map_flags : unit -> string list โ€” Returns the list of --debug-prefix-map flags to be passed to the assembler, built from the BUILD_PATH_PREFIX_MAP environment variable. ๐Ÿ”ฅ

๐Ÿ”ฎ Handling of magic numbers

  • module Magic_number : sig end โ€” yes bestie, Magic_number is listed exactly as module Magic_number : sig end. Mysterious, iconic, no further notes. โœจ

๐ŸŒˆ Minimal support for Unicode characters in identifiers

Characters allowed in identifiers are, currently:

  • -ASCII letters A-Z a-z
  • -Latin-1 letters (U+00C0 - U+00FF except U+00D7 and U+00F7)
  • -Character sequences which normalize to the above character under NFC
  • -digits 0-9, underscore, single quote
  • module Utf8_lexeme : sig end โ€” listed exactly as module Utf8_lexeme : sig end. ๐Ÿ’œ
  • module RuntimeID : sig end โ€” listed exactly as module RuntimeID : sig end. ๐ŸŽ€

๐Ÿท๏ธ Miscellaneous type aliases

  • type filepath = string โ€” a filepath is a string, no cap. ๐Ÿฆ‹
  • type modname = string โ€” a modname is a string, periodt. โœจ
  • type crcs = (modname * Digest.BLAKE128.t option) list โ€” exactly this little list of modname paired with an optional Digest.BLAKE128.t. ๐Ÿ’…
  • type alerts = string Stdlib.String.Map.t โ€” alerts are a string Stdlib.String.Map.t, and that's the whole alias. ๐ŸŒธ

๐Ÿ’– That's the whole Misc(3) vibe, bestie โ€” source/version is OCamldoc, dated 2026-06-22, and the page is Misc(3). Bye, love you, read your manpages! ๐Ÿซถโœจ

๐Ÿ“ฆ where this page comes from
  • arch rolling: ocaml 5.5.0-1 ยท LGPL2.1 AND custom: QPL-1.0
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms