Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OCaml: Throw away return value in imperative code

How do I successfully throw away the return value of a function and treat it as if it's returning unit (for side-effects, obviously). The obvious approach is to do this:

let foo = begin
  some_ignored_thing ();
  actual_return
end

However, the compiler complains (with a warning) that the return type of some_ignored_thing isn't unit.

I could invent my own method, such as:

let ignore a = ()

Which seems at least concise and flags that something's going on, but is there anything in the language/stdlib that achieves the same thing? I'd have thought it would be a relatively common use case.

like image 526
Impredicative Avatar asked Mar 06 '13 10:03

Impredicative


1 Answers

Indeed, there is an ignore : 'a -> unit function that does exactly this.

The compiler actually knows about ignore and hard-code a specific behavior that is generally very useful, but can occasionally be inconvenient: by default, ignoring a function (anything with a type of the form foo -> bar) will raise a warning.

The reason for this is that forgetting to add the last argument of a function is a relatively common mistake. You may write for example

ignore (List.map (fun x -> foo bar))

while you meant to write

ignore (List.map (fun x -> foo bar) li)

and the effects you expect to see applied are not.

So ignore will raise a warning in this case, which your hand-coded let ignore x = () does not do. People also sometimes write

let _ = foo in ...

to ignore foo, but this suffer from the same downside (it's easy to be wrong about what the type actually is). Kakadu recommends to use a type annotation there, and that's a reasonable advice.

(Some people also use let _ = ... for the "main" expression of their program. I recommend to rather use let () = ... for this same reason that it forces more type precision.)

Finally, some people prefer to use the let _ = ... form because they are in situations where using ; would force them to add parentheses or begin..end. I recommend that you always add parentheses or begin..end in these cases, because it's easy to shoot yourself in the foot with that -- obscure precedence rules for if..then..else.. for example.

like image 54
gasche Avatar answered Sep 28 '22 07:09

gasche