14:50 < cbosdonnat> pino|work, do you know how I could get ?tar passed from one
function to the other in the checksum code?
14:51 < pino|work> cbosdonnat: pass it as it is, ie ?foo
14:52 < cbosdonnat> pino|work, indeed, works better... I didn't know I could use
the ? in the calling function and I used the ~ instead
14:53 < pino|work> ? is handled like an option type
This is a bit complicated, but I think it may be more obvious if
you know there are two distinct issues:
Issue 1: When calling a function, ?foo is short for ?foo:foo and
~bar is short for ~bar:bar
If you're calling a function that takes a labelled parameter ~bar
and you want to pass (eg) a string you can do:
func ~bar:"hello"
If you want to pass a variable [really: a binding] to the function, then:
let v = "hello" in
func ~bar:v
But as a special case, if the variable is called bar already, then
this works:
let bar = "hello" in
func ~bar
because ~bar is short for ~bar:bar (and the same for optional
parameters like ?foo).
This leads naturally to code that looks like:
let other_func ~foo ~bar ?baz =
func ~foo ~bar ?baz
Issue 2: Optional arguments are implemented as option types (eg. None,
Some foo), except when defaults are used
If a function is defined as:
let func ?foo ~bar () =
...
then bar is passed as an ordinary parameter, it's just that at compile
time it is given a label (the labels disappear completely at runtime).
So there is no overhead or difference for the ~bar parameter.
However ?foo is implemented as an option. If the function is called
this way:
func ~bar ()
then what actually happens is the first parameter is passed as None,
and foo is assigned to None inside the function. If it is called this
way:
func ~foo:"hello" ~bar ()
then Some "hello" is passed to the function and assigned to foo inside
the function. [And as you can see, the syntax is confusingly
inconsistent as well, welcome to OCaml.]
This works slightly differently if the optional parameter has a
default, eg:
let func ?(foo = "hello") ~bar () =
...
In this case, the implementation still passes an option (None or Some ..)
to the function (because the function still needs to have a way to
know if it was called with or without the ?foo parameter), but the
implementation also implicitly adds the following code to the
beginning of the function:
let func ?(foo = "hello") ~bar () =
let foo = match [real ?foo param] with None -> "hello" | Some x -> x
in
...
so foo inside the function is not an option type in this case.
HTH,
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top