# Module `Base.With_return`

`with_return f`

allows for something like the return statement in C within `f`

.

There are three ways `f`

can terminate:

- If
`f`

calls`r.return x`

, then`x`

is returned by`with_return`

. - If
`f`

evaluates to a value`x`

, then`x`

is returned by`with_return`

. - If
`f`

raises an exception, it escapes`with_return`

.

Here is a typical example:

```
let find l ~f =
with_return (fun r ->
List.iter l ~f:(fun x -> if f x then r.return (Some x));
None
)
```

It is only because of a deficiency of ML types that `with_return`

doesn't have type:

`val with_return : 'a. (('a -> ('b. 'b)) -> 'a) -> 'a `

but we can slightly increase the scope of `'b`

without changing the meaning of the type, and then we get:

```
type 'a return = { return : 'b . 'a -> 'b }
val with_return : ('a return -> 'a) -> 'a
```

But the actual reason we chose to use a record type with polymorphic field is that otherwise we would have to clobber the namespace of functions with `return`

and that is undesirable because `return`

would get hidden as soon as we open any monad. We considered names different than `return`

but everything seemed worse than just having `return`

as a record field. We are clobbering the namespace of record fields but that is much more acceptable.

`val with_return : ('a return -> 'a) -> 'a`

`val with_return_option : ('a return -> unit) -> 'a option`

Note that

`with_return_option`

allocates ~5 words more than the equivalent`with_return`

call.

`val prepend : 'a return -> f:('b -> 'a) -> 'b return`

`prepend a ~f`

returns a value`x`

such that each call to`x.return`

first applies`f`

before applying`a.return`

. The call to`f`

is "prepended" to the call to the original`a.return`

. A possible use case is to hand`x`

over to another function which returns`'b`

, a subtype of`'a`

, or to capture a common transformation`f`

applied to returned values at several call sites.