816 search results for ""
-
Operators
Allowed Operators
OCaml has a subtle syntax; not everything is allowed as an operator symbol. An operator symbol is an identifier with a special syntax, so it must have the following structure:
Advanced Topics -
Operators
Prefix Operator
First character, either: ? ~ ! Following characters, at least one if the first character is ? or ~ , optional otherwise: $ & * + - / = > @ ^ | % <
Advanced Topics -
Operators
Binary Operator
Don't define wide scope operators. Restrict their scope to module or function. Don't use many of them. Before defining a custom binary operator, check that the symbol is not already used. This can be
Advanced Topics -
Operators
Operator Associativity and Precedence
The complete list of precedence is longer because it includes the predefined operators that are not allowed to be used as custom operators. The OCaml Manual has a table that sums up the operator as
Advanced Topics -
Operators
Binding Operators
<!-- TODO: move this into the list tutorial In the following example, we use that mechanism to write a function which produces the list of Friday 13th dates between two years. ```ocaml # let ( let
Advanced Topics -
Functors
Functors
Introduction
Note : The files illustrating this tutorial are available as a Git repo . As suggested by the name, a functor is almost like a function. However, while the inputs and outputs of functions are val
Module SystemFunctors
Project Setup
Check that this works using the opam exec -- dune exec funkt command. It shouldn't do anything (the empty file is valid OCaml syntax), but it shouldn't fail either. The stanza libraries str makes
Module SystemFunctors
Using an Existing Functor: Set.Make
There are no duplicates in a Set . Therefore, the string "funkt" is only displayed once, although it appears twice in the dune file. The functions StringSet.of_list and StringSet.iter are
Module SystemFunctors
Extending a Module with a Standard Library Functor
This allows the user to seemingly extend the module String with a submodule Set . Check the behaviour using opam exec -- dune exec funkt < dune . funkt.ml Using the include statement, here i
Module SystemFunctors
Parametrising Modules with Functors
Module SystemFunctors
Functors From the Standard Library
Set.S Map.S Hashtbl.S The functors Set.Make , Map.Make , and Hashtbl.Make return modules satisfying the interfaces Set.S , Map.S , and Hashtbl.S (respectively), which all contain an abstract
Module SystemFunctors
Writing Your Own Functors
Here is the skeleton of a possible implementation: Heap implementations can be represented as functors from OrderedType into HeapType . Each kind of heap would be a different functor. Using su
Module SystemFunctors
heap.ml
<!-- TODO: Create this section When several implementations of the same interface are needed at runtime, functors allow sharing of their common parts. ## Multiple Implementation of the Same Signat
Module SystemFunctors
Injecting Dependencies Using Functors
Module SystemFunctors
Dependencies Between Modules
Check the program's behaviour using opam exec -- dune exec funkt < dune . Module List through List.iter and f 's type Module Out_channel through Out_channel.output_string It embeds an addit
Module SystemFunctors
Dependency Injection
The dependency List is injected when compiling the module Funkt . Observe that the code using IterPrint is unchanged. Check the program's behaviour using opam exec -- dune exec funkt < dune .
Module SystemFunctors
Replacing a Dependency
Note : Modules received and returned by IterPrint.Make both have a type t . The with type ... := ... constraint exposes that the two types t are the same. This makes functions from the injecte
Module SystemFunctors
Naming and Scoping
Warning : Don't shadow names too often because it makes the code harder to understand. In the example above, t from with type takes precedence over the local t , which only has a local scope.
Module SystemFunctors
Write a Functor to Extend Modules
Modules Array and List appear augmented with Array.scan_left and List.scan_left . For brevity, the output of the first two toplevel commands is not shown here. Run the dune utop command. O
Module SystemFunctors
Initialisation of Stateful Modules
Calling R1.bits a third time returns the same result as the first call, which demonstrates the state has indeed been reset. Calling R2.bits a second time shows the modules aren't sharing states.
Module SystemFunctors
Conclusion
Functor application essentially works the same way as function application: passing parameters and getting results. The difference is that we are passing modules instead of values. Beyond comfort, it
Module SystemUnderstanding the Garbage Collector
Understanding the Garbage Collector
Mark and Sweep Garbage Collection
All blocks reachable from the roots by following edges in the graph must be retained, and unreachable blocks can be reused by the application. The algorithm used by OCaml to perform this heap tra
Runtime & CompilerUnderstanding the Garbage Collector
Generational Garbage Collection
<div class="note"> OCaml uses different memory layouts and garbage-collection algorithms for the major and minor heaps to account for this generational difference. We'll explain how they differ
Runtime & CompilerUnderstanding the Garbage Collector
The Gc Module and OCAMLRUNPARAM
</div> You can also control the behavior of OCaml programs by setting the OCAMLRUNPARAM environment variable before launching your application. This lets you set GC parameters without recompili
Runtime & CompilerUnderstanding the Garbage Collector
The Fast Minor Heap
To garbage-collect the minor heap, OCaml uses copying collection to move all live blocks in the minor heap to the major heap. This takes work proportional to the number of live blocks in the mi
Runtime & CompilerUnderstanding the Garbage Collector
Allocating on the Minor Heap
Allocating a block in the minor heap just requires ptr to be decremented by the size of the block (including the header) and a check that it's not less than limit . If there isn't enough space
Runtime & CompilerUnderstanding the Garbage Collector
Understanding Allocation
<div class="note"> These poll points check ptr against limit and developers should expect them to be placed at the start of every function and the back edge of loops. The compiler includes
Runtime & CompilerUnderstanding the Garbage Collector
Setting the Size of the Minor Heap
</div> Changing the GC size dynamically will trigger an immediate minor heap collection. Note that Core increases the default minor heap size from the standard OCaml installation quite significa
Runtime & CompilerUnderstanding the Garbage Collector
The Long-Lived Major Heap
A major garbage collection must also stop the world to ensure that blocks can be moved around without this being observed by the live application. The mark-and-sweep phases run incrementally over
Runtime & CompilerUnderstanding the Garbage Collector
Allocating on the Major Heap
Each chunk's data area starts on a page boundary, and its size is a multiple of the page size (4 KB). It contains a contiguous sequence of heap blocks that can be as small as one or two 4 KB page
Runtime & CompilerUnderstanding the Garbage Collector
Controlling the Major Heap Increment
You can use Gc.tune to set that value, but the values are a little counter-intuitive, for backwards-compatibility reasons. Values under 1000 are interpreted as percentages, and the default is
Runtime & CompilerUnderstanding the Garbage Collector
Memory Allocation Strategies
The free list of blocks is always checked first when allocating a new block in the major heap. The default free list search is called best-fit allocation , with alternatives next-fit and first
Runtime & CompilerUnderstanding the Garbage Collector
Best-Fit Allocation
Best-fit allocation is the default allocation mechanism. It represents a good trade-off between the allocation cost (in terms of CPU work) and heap fragmentation. Small allocations, when there a
Runtime & CompilerUnderstanding the Garbage Collector
Next-Fit Allocation
Next-fit allocation is quite a cheap allocation mechanism, since the same heap chunk can be reused across allocation requests until it runs out. This in turn means that there is good memory loc
Runtime & CompilerUnderstanding the Garbage Collector
First-Fit Allocation
For some workloads that need more real-time behavior under load, the reduction in the frequency of heap compaction will outweigh the extra allocation cost. First-fit allocation focuses on reduci
Runtime & CompilerUnderstanding the Garbage Collector
Controlling the Heap Allocation Policy
The same behavior can be controlled via an environment variable by setting OCAMLRUNPARAM to a=0 for next-fit, a=1 for first-fit, or a=2 for best-fit. You can set the heap allocation pol
Runtime & CompilerUnderstanding the Garbage Collector
Marking and Scanning the Heap
Later in the marking process when the mark stack is empty it is replenished by redarkening the heap. This starts at the first heap chunk (by address) that has blocks needing redarkening (i.e wer
Runtime & CompilerUnderstanding the Garbage Collector
Controlling Major Heap Collections
The space_overhead setting controls how aggressive the GC is about setting the slice size to a large size. This represents the proportion of memory used for live data that will be "wasted" beca
Runtime & CompilerUnderstanding the Garbage Collector
Heap Compaction
<div class="note"> The heap compaction cycle avoids this by relocating all the values in the major heap into a fresh heap that places them all contiguously in memory again. A naive implementati
Runtime & CompilerUnderstanding the Garbage Collector
Controlling Frequency of Compactions
</div> A value of 0 triggers a compaction after every major garbage collection cycle, whereas the maximum value of 1000000 disables heap compaction completely. The default settings should
Runtime & CompilerUnderstanding the Garbage Collector
Intergenerational Pointers
OCaml maintains a set of such intergenerational pointers to avoid this dependency between a major and minor heap collection. The compiler introduces a write barrier to update this so-called re
Runtime & CompilerUnderstanding the Garbage Collector
The Mutable Write Barrier
The only way to know for sure is to benchmark your program under real-world scenarios using Core_bench and experiment with the trade-offs. The command-line benchmark binaries have a number of
Runtime & CompilerUnderstanding the Garbage Collector
Attaching Finalizer Functions to Values
<div class="note"> OCaml's automatic memory management guarantees that a value will eventually be freed when it's no longer in use, either via the GC sweeping it or the program terminating. It'
Runtime & CompilerUnderstanding the Garbage Collector
What Values Can Be Finalized?
The finalizer can use all features of OCaml, including assignments that make the value reachable again and thus prevent it from being garbage-collected. It can also loop forever, which will cause
Runtime & CompilerLabelled and Optional Arguments
Labelled and Optional Arguments
Passing Labelled Arguments
Note : Passing labelled arguments through the pipe operator ( |> ) throws a syntax error: Labelled arguments are passed using a tilde ~ and can be placed at any position and in any order. T
IntroductionLabelled and Optional Arguments
Labelling Parameters
At parameter definition ~first is the same as ~first:first . Passing argument ~last is the same as ~last:last . It is possible to use a shorter syntax when using the same name as label and p
IntroductionLabelled and Optional Arguments
Passing Optional Arguments
It is also possible to pass optional arguments as values of type option . This is done using a question mark when passing the argument. Optional arguments can be omitted. When passed, a tilde
Introduction