369 search results for "function"
-
The Compiler Backend: Bytecode and Native code
Benchmarking Polymorphic Comparison
ee that this polymorphic comparison is much heavier than the simple monomorphic integer comparison from earlier. Let's confirm this hypothesis again by writing a quick Core_bench test with both functions:
Runtime & Compiler -
The Compiler Backend: Bytecode and Native code
Debugging Native Code Binaries
assembly when the library is compiled in debug mode. These include the CFI stubs you will have noticed in the profiling output earlier ( .cfi_start_proc and .cfi_end_proc to delimit an OCaml function call, for example). The native code compiler builds executables that can be debugged using conventional system debuggers such as GNU gdb . You need to compile your libraries with the -g optio
Runtime & Compiler -
The Compiler Backend: Bytecode and Native code
Interactive Breakpoints with the GNU Debugger
e first call to take : Now we can run this interactively within gdb : Compile and run this with debugging symbols. You should see the following output: Let's write a mutually recursive function that selects alternating values from a list. This isn't tail-recursive, so our stack size will grow as we single-step through the execution: Let's see name mangling in action with some interacti
Runtime & Compiler -
The Compiler Backend: Bytecode and Native code
Gprof
gmon.out when the program is executed. This profile information can then be examined using gprof . gprof produces an execution profile of an OCaml program by recording a call graph of which functions call one another, and recording the time these calls take during the program execution.
Runtime & Compiler -
The Compiler Backend: Bytecode and Native code
Perf
home page . This trace broadly reflects the results of the benchmark itself. The mutable benchmark consists of the combination of the call to test_mutable and the caml_modify write barrier function in the runtime. This adds up to slightly over half the execution time of the application. When this completes, you can interactively explore the results: Run Perf on a compiled binary to reco
Runtime & Compiler -
Memory Representation of Values
Distinguishing Integers and Pointers at Runtime
. This representation means that integers are unboxed runtime values in OCaml so that they can be stored directly without having to allocate a wrapper block. They can be passed directly to other function calls in registers and are generally the cheapest and fastest values to use in OCaml. OCaml values don't all have to be boxed at runtime. Instead, values use a single tag bit per word to disting
Runtime & Compiler -
Memory Representation of Values
Integers, Characters, and Other Basic Types
it are very efficient to use, since integers are never allocated on the heap. They can be passed directly in registers and not appear on the stack if you don't have too many parameters to your functions. Modern architectures such as x86_64 have a lot of spare registers to further improve the efficiency of using unboxed integers. Many basic types are efficiently stored as unboxed integers at
Runtime & Compiler -
Memory Representation of Values
Tuples, Records, and Arrays
The Obj.repr function retrieves the runtime representation of any OCaml value. Obj.is_block checks the bottom bit to determine if the value is a block header or an unboxed integer. You can check the difference be
Runtime & Compiler -
Memory Representation of Values
Floating-Point Numbers and Arrays
hich are not optimized in the same way and have the normal tuple tag value (0). This tells us that float arrays have a tag value of 254. Now let's test some sample values using the Obj.tag function to check that the allocated block has the expected runtime tag, and also use Obj.double_field to retrieve a float from within the block: First, let's check that float arrays do in fact have
Runtime & Compiler -
Memory Representation of Values
Custom Heap Blocks
ted. This finalizer has nothing to do with ordinary OCaml finalizers (as created by Gc.finalize and explained in Understanding The Garbage Collector ). They are instead used to call C cleanup functions such as free . The first word of the data within the custom block is a C pointer to a struct of custom operations. The custom block cannot have pointers to OCaml blocks and is opaque to the
Runtime & Compiler -
A Tour of OCaml
Type Conversion and Type-Inference
ison to other languages. Arguably, this saves more time than we lose by being more explicit. In OCaml you need to explicitly convert the integer to a floating point number using the float_of_int function: In the first example, + is intended to be used with integers, so it can't be used with the 2.5 float. In the second example, +. is intended to be used with floats, so it can't be used with th
First Steps -
A Tour of OCaml
Pattern Matching, Cont'd
mes, just as let does. In the third pattern, x designates the data inside the double-wrapped option. Pattern matching isn't limited to lists. Any kind of data can be inspected using it, except functions. Patterns are expressions that are compared to an inspected value. It could be performed using if … then … else … , but pattern matching is more convenient. Here is an example using the opti
First Steps -
A Tour of OCaml
Records
Here, the pattern { age = x; _ } is typed with the most recently declared record type that has an age field of type int . The type int is inferred from the expression 13 <= x && x <= 19 . The function is_teenager will only work with the found record type, here person . When defining gerard , no type needs to be declared. The type checker will search for a record which has exactly three fiel
First Steps -
Configuring Your Editor
1) Hovering for Type Information
This is a great feature that lets you see type information of any OCaml variable or function. All you have to do is place your cursor over the code and it will be displayed in the tooltip. VSCode Hovering
Tooling -
Configuring Your Editor
Choosing a major mode
nd actively maintained mode with comprehensive OCaml support. Recommended if you're using an older version of Emacs (before the introduction of tree-sitter support) or you need some of the advanced functionality that Tuareg provides. Caml : an older, lighter mode that is softly deprecated at this point. Neocaml : a newer mode based on tree-sitter , requiring Emacs 30+. There are several major modes de
Tooling -
Configuring Your Editor
Finer configuration
OCaml-eglot can be finely configured, the project README gives several configuration paths to adapt perfectly to your workflow. You will also find there an exhaustive presentation of the different functions offered by the mode.
Tooling -
Configuring Your Editor
Getting Type Information
OCaml-eglot README provides a comprehensive overview of all the functions available in this mode! Emacs Type information Opening an OCaml file should launch an ocaml-lsp server, and you can convince yourself that it's working by using, for example, the ocaml-eglot-ty
Tooling -
Your First OCaml Program
Installing and Using Modules From a Package
Refer to the Sexplib documentation for more information. Next, define a string containing a valid S-expression in bin/main.ml . Parse it into an S-expression with the Sexplib.Sexp.of_string function, and then convert it back into a string with Sexplib.Sexp.to_string and print it. To illustrate this, let's update our hello project to parse a string containing an S-expression and print
First Steps -
Your First OCaml Program
Using the Preprocessor to Generate Code
le, and edit it to look like this: Let's assume we'd like hello to display its output as if it was a list of strings in UTop: ["hello"; "using"; "an"; "opam"; "library"] . To do that, we need a function turning a string list into a string , adding brackets, spaces, and commas. Instead of defining it ourselves, let's generate it automatically with a package. We'll use ppx_deriving . Here is how t
First Steps