Reputation: 2127
I'm reading OCaml source code and I'm getting confused about named arguments:
let verify_transport_checksum ~proto ~ipv4_header ~transport_packet =
(* note: it's not necessary to ensure padding to integral number of 16-bit fields here; ones_complement_list does this for us *)
let check ~proto ipv4_header len =
try
let ph = Marshal.pseudoheader ~src:ipv4_header.src ~dst:ipv4_header.dst ~proto len in
let calculated_checksum = Tcpip_checksum.ones_complement_list [ph ; transport_packet] in
0 = compare 0x0000 calculated_checksum
with
| Invalid_argument _ -> false
in
match proto with
| `TCP -> (* checksum isn't optional in tcp, but pkt must be long enough *)
check ipv4_header ~proto (Cstruct.len transport_packet)
| `UDP ->
match Udp_wire.get_udp_checksum transport_packet with
| n when (=) 0 @@ compare n 0x0000 -> true (* no checksum supplied, so the check trivially passes *)
| _ ->
check ipv4_header ~proto (Cstruct.len transport_packet)
I see that verify_transport_checksum
is a function that has these 3 names arguments: ~proto ~ipv4_header ~transport_packet
. Then, in the inside, it does let check ~proto ipv4_header len =
. This is a new ~proto
?
Then it does
let ph = Marshal.pseudoheader ~src:ipv4_header.src ~dst:ipv4_header.dst ~proto len in
what is this ~proto
? Is it a named argument of Marshal.pseudoheader
? If so, why it has no value?
Upvotes: 0
Views: 170
Reputation: 246
This is doing label-punning
: It takes some variable-binding from before, and passes it on to another function as a labeled argument of the same name and same value.
let someArg = "something";;
someFun ~someArg;;
(* is shorthand notation for *)
someFun ~someArg:someArg;;
verify_transport_checksum
has the labelled argument ~proto
.check
.~proto
in the check
-definition has the same name as before, so it can be passed through. However, it shadowes the previous binding of ~proto
. If one called it (in the pattern matching below) like check ~proto:"something else here"
, it would have a different value. In your case, because it gets punned, it has the very same value as before.Marshal.pseudoheader
-call, the ~proto
from check
gets passed through.Upvotes: 3