I acknowledge that the notion of arity as the number recorded in a closure’s info field is unusual. Usually, the arity of a function means the number of parameters it can take, which is, implicitly, the maximum number of parameters. However, in the context of an OCaml closure’s info field, the term arity adopts a different meaning. This is best illustrated by the example below.
Let’s first define:
let sum_six = fun a b c d e f -> a + b + c + d + e + f
(* partial sums *)
let psum1 a = sum_six a
let psum2 a b = sum_six a b
let psum3 a b c = sum_six a b c
let psum4 a b c d = sum_six a b c d
let psum5 a b c d e = sum_six a b c d e
Then we ask: what is the arity of psum1
, …, psum5
, respectively? Intuitively, we would say their arities are all the same : 6 ! However, if we use a runtime value explorer (I use OInspect) to peek into the blocks of these closures, I get arities 1,…, 5 for them respectively. For instance, psum1
has runtime repr.
OCaml Value : 0X0000555CE6851C90
Header : 0X0000000000000BF7
wo-size : 2
color : 3
closure tag : 247
Field 0 : 0X0000555CE681C170 ... code partial appl.
Field 1 : 0X0100000000000005 ... info
Arity : 1
Env. : 2
... no env.
psum2
has runtime repr.
OCaml Value : 0X0000555CE6851CA8
Header : 0X0000000000000FF7
wo-size : 3
color : 3
closure tag : 247
Field 0 : 0X0000555CE681BF80 ... code partial appl.
Field 1 : 0X0200000000000007 ... info
Arity : 2
Env. : 3
Field 2 : 0X0000555CE681C1F0 ... code total appl.
... no env.
and psum3
has runtime repr.
OCaml Value : 0X0000555CE6851CC8
Header : 0X0000000000000FF7
wo-size : 3
color : 3
closure tag : 247
Field 0 : 0X0000555CE681BE90 ... code partial appl.
Field 1 : 0X0300000000000007 ... info
Arity : 3
Env. : 3
Field 2 : 0X0000555CE681C280 ... code total appl.
... no env.
Using the manual’s terminology, it all seems that for an identifier <value-name>
(e.g., psum1
) defined by
let <value-name> = fun <parameter>+ -> <expr>
where <expr>
does not have the form fun <param>+ -> ...
, the arity (as in the closure’s info field) of <value-name>
is the number of formal parameters <parameter>+
; moreover, when <expr>
itself is a partial application, the number of missing parameters do not count towards the arity of <value-name>
.
An abstraction (e.g. fun a -> sum_six a
) is like an “arity curtain” that prevents the compiler from seeing that actually psum1
can take 6 arguments. I guess this may have something to do with the evaluation model of OCaml, where an abstraction body is not evaluated at definition time.
The runtime representation of sum_six 1 2 3 4 5
is quite different from that of psum1 1 2 3 4 5
as well. For sum_six 1 2 3 4 5
, the block has quite a neat structure: header, code pointer, info, and env that consists of the original function sum_six
and its five arguments, as follows:
OCaml Value : 0X00007F77B626EE78
Header : 0X00000000000020F7
wo-size : 8
color : 0
closure tag : 247
Field 0 : 0X0000561F3D79E240 ... code partial appl.
Field 1 : 0X0100000000000005 ... info
Arity : 1
Env. : 2
env starts ...
Field 2 :
....OCaml Value : 0X0000000000000003
.... Is integer : 1 (in decimal)
Field 3 :
....OCaml Value : 0X0000000000000005
.... Is integer : 2 (in decimal)
Field 4 :
....OCaml Value : 0X0000000000000007
.... Is integer : 3 (in decimal)
Field 5 :
....OCaml Value : 0X0000000000000009
.... Is integer : 4 (in decimal)
Field 6 :
....OCaml Value : 0X000000000000000B
.... Is integer : 5 (in decimal)
Field 7 :
....OCaml Value : 0X0000561F3D7D3C68
.... Header : 0X0000000000000FF7
.... wo-size : 3
.... color : 3
.... closure tag : 247
.... Field 0 : 0X0000561F3D79D800 ... code partial appl.
.... Field 1 : 0X0600000000000007 ... info
.... Arity : 6
.... Env. : 3
.... Field 2 : 0X0000561F3D79E110 ... code total appl.
.... ... no env.
However, the runtime repr. of psum1 1 2 3 4 5
is much more involved; it is a cascade of partial applications which basically says psum1 1 2 3 4 5
is a partial application to 5, of psum1 1 2 3 4
, which is a partial application to 4, of psum1 1 2 3
, which is , …, which is a partial application to 1, of sum_six
:
OCaml Value : 0X00007F77B626ED90
Header : 0X00000000000010F7
wo-size : 4
color : 0
closure tag : 247
Field 0 : 0X0000561F3D79DCD0 ... code partial appl.
Field 1 : 0X0100000000000005 ... info
Arity : 1
Env. : 2
env starts ...
Field 2 :
....OCaml Value : 0X000000000000000B
.... Is integer : 5 (in decimal)
Field 3 :
....OCaml Value : 0X00007F77B626EDB8
.... Header : 0X00000000000014F7
.... wo-size : 5
.... color : 0
.... closure tag : 247
.... Field 0 : 0X0000561F3D79DC80 ... code partial appl.
.... Field 1 : 0X0200000000000007 ... info
.... Arity : 2
.... Env. : 3
.... Field 2 : 0X0000561F3D79DC50 ... code total appl.
.... env starts ...
.... Field 3 :
........OCaml Value : 0X0000000000000009
........ Is integer : 4 (in decimal)
.... Field 4 :
........OCaml Value : 0X00007F77B626EDE8
........ Header : 0X00000000000014F7
........ wo-size : 5
........ color : 0
........ closure tag : 247
........ Field 0 : 0X0000561F3D79DBF0 ... code partial appl.
........ Field 1 : 0X0300000000000007 ... info
........ Arity : 3
........ Env. : 3
........ Field 2 : 0X0000561F3D79DBC0 ... code total appl.
........ env starts ...
........ Field 3 :
............OCaml Value : 0X0000000000000007
............ Is integer : 3 (in decimal)
........ Field 4 :
............OCaml Value : 0X00007F77B626EE18
............ Header : 0X00000000000014F7
............ wo-size : 5
............ color : 0
............ closure tag : 247
............ Field 0 : 0X0000561F3D79DB60 ... code partial appl.
............ Field 1 : 0X0400000000000007 ... info
............ Arity : 4
............ Env. : 3
............ Field 2 : 0X0000561F3D79DB30 ... code total appl.
............ env starts ...
............ Field 3 :
................OCaml Value : 0X0000000000000005
................ Is integer : 2 (in decimal)
............ Field 4 :
................OCaml Value : 0X00007F77B626EE48
................ Header : 0X00000000000014F7
................ wo-size : 5
................ color : 0
................ closure tag : 247
................ Field 0 : 0X0000561F3D79DAD0 ... code partial appl.
................ Field 1 : 0X0500000000000007 ... info
................ Arity : 5
................ Env. : 3
................ Field 2 : 0X0000561F3D79E190 ... code total appl.
................ env starts ...
................ Field 3 :
....................OCaml Value : 0X0000000000000003
.................... Is integer : 1 (in decimal)
................ Field 4 :
....................OCaml Value : 0X0000561F3D7D3C68
.................... Header : 0X0000000000000FF7
.................... wo-size : 3
.................... color : 3
.................... closure tag : 247
.................... Field 0 : 0X0000561F3D79D800 ... code partial appl.
.................... Field 1 : 0X0600000000000007 ... info
.................... Arity : 6
.................... Env. : 3
.................... Field 2 : 0X0000561F3D79E110 ... code total appl.
.................... ... no env.