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 theFatal_errorexception 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 raiseFatal_errorwith 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 ~exceptionallyis designed to run code inworkthat 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), andexceptionally, that should be run only ifworkoralwaysfailed 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 fis(f (); raise e)except that the current backtrace is preserved, even iffuses 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 tismap 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โ LikeList.map, with guaranteed left-to-right evaluation order. Order matters, bestie. โจval for_all2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> boolโ Same asList.for_allbut for a binary predicate. In addition, thisfor_all2never fails: given two lists with different lengths, it returnsfalse. No crashing, just honesty. ๐ญval replicate_list : 'a -> int -> 'a listโreplicate_list elem nis the list withnelements all identical toelem. Copy-paste but make it functional. ๐val list_remove : 'a -> 'a list -> 'a listโlist_remove x lreturns a copy oflwith the first element equal toxremoved. 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 nameFoo.mltofoo.ml, using NFC and case-folding. ReturnErrorif the input is not a valid utf-8 byte sequence. Normalization era. โจval find_in_path_normalized : string list -> string -> stringโ Same asMisc.find_in_path_rel, but search also for normalized unit filename, i.e. ifnameisFoo.ml, allow/path/Foo.mland/path/foo.mlto 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 fileeventually expands a+at the beginning offileintoalt(an alternate root directory). Plus sign glow-up. โญval split_path_contents : ?sep:char -> string -> string listโsplit_path_contents ?sep sinterpretssas the value of a"PATH"-like variable and returns the corresponding list of directories.sis split using the platform-specific delimiter, or~sepif it is passed. Returns the empty list ifsis empty. PATH vibes, parsed. ๐ฆval copy_file : in_channel -> out_channel -> unitโcopy_file ic ocreads the contents of fileicand copies them tooc. It stops when encounteringEOFonic. Copy until EOF, no cap. ๐val copy_file_chunk : in_channel -> out_channel -> int -> unitโcopy_file_chunk ic oc nreadsnbytes fromicand copies them tooc. It raisesEnd_of_filewhen encounteringEOFonic. Chunked, and it will raise if the file ghosts you. ๐ญval string_of_file : in_channel -> stringโstring_of_file icreads the contents of fileicand copies them to a string. It stops when encounteringEOFonic. 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 fnopens a temporary file which is passed tofn(name + output channel). Whenfnreturns, the channel is closed and the temporary file is renamed tofilename. Temporary era, then atomic-ish rename. ๐ฅval protect_writing_to_file : filename:string -> f:(out_channel -> 'a) -> 'aโ Open the givenfilenamefor writing (in binary mode), pass theout_channelto the given function, then close the channel. If the function raises an exception thenfilenamewill be removed. Cleanup on failure? We stan. ๐ซถval concat_null_terminated : string list -> stringโconcat_null_terminated [x1;x2; ... xn]isx1 ^ "\000" ^ x2 ^ "\000" ^ ... ^ xn ^ "\000". Null-terminated join, exactly like that. โจval split_null_terminated : string -> string listโsplit_null_terminated sis similarString.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.uvwfor instance. Return the given name if it does not contain an extension. Extensions chopped, name preserved. ๐
๐ข Integer operations ๐ข
val log2 : int -> intโlog2 nreturnsssuch thatn = 1 lsl sifnis a power of 2. Power-of-two detective. ๐val align : int -> int -> intโalign n aroundsnupwards to a multiple ofa(apower of 2). Round up, bestie. โญval no_overflow_add : int -> int -> boolโno_overflow_add n1 n2returnstrueif the computation ofn1 + n2does not overflow. Overflow check, no surprises. ๐val no_overflow_sub : int -> int -> boolโno_overflow_sub n1 n2returnstrueif the computation ofn1 - n2does not overflow. Subtraction safety check. ๐ฆval no_overflow_mul : int -> int -> boolโno_overflow_mul n1 n2returnstrueif the computation ofn1 * n2does not overflow. Multiplication, but keep it contained. ๐val no_overflow_lsl : int -> int -> boolโno_overflow_lsl n kreturnstrueif the computation ofn lsl kdoes 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 ptakes an integer predicatep : int -> boolthat we assume:- is monotonic on natural numbers: if
a <= bthenp aimpliesp b, - is satisfied for some natural numbers in range
0; max_int(this is equivalent to:p max_int = true).
- is monotonic on natural numbers: if
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 startreturns the position of the first occurrence of stringpatin stringstr. Search starts at offsetstartinstr. RaiseNot_foundifpatdoes not occur. Search era, with aNot_foundcliffhanger. ๐ญval replace_substring : before:string -> after:string -> string -> stringโreplace_substring ~before ~after strreplaces all occurrences ofbeforewithafterinstrand returns the resulting string. Global replace, no crumbs. ๐val rev_split_words : string -> string listโrev_split_words ssplitssin 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 creturns a pair containing the sub-string before the first occurrence ofcins, and the sub-string after the first occurrence ofcins.
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 nis the appropriate suffix to append to the numeralnas an ordinal number:1 -> "st",2 -> "nd",3 -> "rd",4 -> "th", and so on. Handles larger numbers (e.g.,42 -> "nd") and the numbers11--13(which all get"th") correctly. Ordinal grammar ate. ๐val normalise_eol : string -> stringโnormalise_eol sreturns a fresh copy ofswith 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 sreturns a fresh copy ofswith 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 ftemporarily setsrtovfor eachR (r, v)inlwhile executingf. The previous contents of the references is restored even iffraises an exception, without altering the exception backtrace. Reference protection with backtrace respect. ๐val get_ref : 'a list ref -> 'a listโget_ref lrreturns the content of the list referencelrand 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 xsetsopttof xif it returnsSome _, or leaves it unmodified if it returnsNone. Set only if thereโs aSome, 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 namedfor4, and yes, thatโs iconic. ๐
โจ Spell checking and โdid you meanโ suggestions โจ
val edit_distance : string -> string -> int -> int optionโ okay soedit_distance a b cutoffcomputes the edit distance between stringsaandb. To help efficiency, it uses a cutoff: if the distancedis smaller thancutoff, it returnsSome d, elseNone. 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 nametakes a list of namesenvthat exist in the current environment and an erroneousname, and returns a list of suggestions taken fromenv, that are close enough tonamethat 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 hintvertically 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 asalign_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 ... hintalign the potential hint with the main error message generated by the format stringfmtbefore printing the two message. ๐ซถval did_you_mean : ?pp:string Format_doc.printer -> string list -> Format_doc.t optionโdid_you_mean ~pp choiceshints that the user may have meant one of the option inchoices. Each choice is printed with theppfunction, orStyle.inline_codeifpp = None. ๐ฆmodule Color : sig endโ listed right here, exactly asmodule 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โ theStylemodule is listed exactly asmodule Style : sig end. Iconic. ๐module Error_style : sig endโ andError_styleis listed exactly asmodule 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 xprintsxwithfmtonppfifbis 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 moduleConfig, then exit the program with code0. Slay, then dip. ๐val show_config_variable_and_exit : string -> unitโ Display the value of the given configuration variable, then exit the program with code0. 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 theBUILD_PATH_PREFIX_MAPenvironment 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 usingBUILD_PATH_PREFIX_MAPenvironment variable. ๐val debug_prefix_map_flags : unit -> string listโ Returns the list of--debug-prefix-mapflags to be passed to the assembler, built from theBUILD_PATH_PREFIX_MAPenvironment variable. ๐ฅ
๐ฎ Handling of magic numbers
module Magic_number : sig endโ yes bestie,Magic_numberis listed exactly asmodule 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 asmodule Utf8_lexeme : sig end. ๐module RuntimeID : sig endโ listed exactly asmodule RuntimeID : sig end. ๐
๐ท๏ธ Miscellaneous type aliases
type filepath = stringโ afilepathis astring, no cap. ๐ฆtype modname = stringโ amodnameis astring, periodt. โจtype crcs = (modname * Digest.BLAKE128.t option) listโ exactly this little list ofmodnamepaired with an optionalDigest.BLAKE128.t. ๐type alerts = string Stdlib.String.Map.tโ alerts are astring 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