TL;DR
@@ may be used to group expressions if you’re allergic to parentheses. Example:
List.rev @@ List.sort (-) [4;2;5;2;7;5;4;1;3;9;0]
is equivalent to
List.rev (List.sort (-) [4;2;5;2;7;5;4;1;3;9;0])You can think of @@ as being defined as let (@@) f x = f x, and you’re right, f @@ x isn’t a whole lot different from f x. One use case for @@ is when you’re trying to cut down on parenthesis. For example, consider a pop function that extracts a value from an option:
let pop = function Some x -> x | None -> failwith "nothing here"
If you wanted to call it on Some 5, it would be a bit of pain.
pop Some 5
would lead to this error
Error: The constructor Some expects 1 argument(s),
but is applied here to 0 argument(s)
You can fix this by either wrapping the option in parenthesis or by using the @@ operator:
pop (Some 5)
pop @@ Some 5
Both compile as you’d expect.
Edit: I thought I’d mention that this trick works because @@ has lower precedence than other operations (like applying a function or passing an argument into a constructor).
https://www.reddit.com/r/ocaml/comments/3qmapa/comment/cwgfb1b/