Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OCaml - What is an unsound type?

Tags:

ocaml

Recently I was given the code

List.fold_left (fun acc x -> raise x ; acc) 3

I'm completely fine with this partial application having a functional value of type exn list -> int, and the fact it yields a warning isn't surprising. I am, however, not certain what half of the warning means:

Warning 21: this statement never returns (or has an unsound type.)

I can't actually find any reference to this warning where it isn't the result of a non-returning statement. Even the man page for ocamlc only mentions non-returning statements for this warning, and warnings.ml refers to it merely as Nonreturning_statement.

I am familiar with the concept of soundness as it relates to type systems, but the idea of a type itself being inherently unsound seems odd to me.

So my questions are:

What exactly is an unsound type?

What's a situation in which an unsound type would arise when OCaml would only issue a warning rather than failing hard outright?

Someone has posted this question, and while I was writing an answer, it was deleted. I believe the question is very interesting and worth for reposting. Please consider you may have someone who is willing to help you :-(

like image 639
camlspotter Avatar asked Dec 23 '15 04:12

camlspotter


1 Answers

How Warning 21 is reported

First, let's think of functions which returns unrelated 'a: I do not mean function like let id x = x here since it has type 'a -> 'a and the return type 'a relates with the input. I mean functions like raise : exn -> 'a and exit : int -> 'a.

These functions return unrelated 'a are considered never returning. Since the type 'a (more precisely forall 'a. 'a) has no citizen. Only thing the functions can do are terminating the program (exit or raising an exception) or falling into an infinite loop: let rec loop () = loop ().

Warning 21 is mentioned when the type of a statement is 'a. (Actually there is another condition but I just skip for simplicity.) For example,

# loop (); print_string "end of the infinite loop";;
Warning 21: this statement never returns (or has an unsound type.)

This is the main purpose of warning 21. Then what is the latter half?

"Unsound type"

Warning 21 can be reported even if the statement returns something actually. In this case, as the warning message suggests the statement has a unsound type.

Why unsound? Since the expression does return a value of type forall 'a. 'a, which has no citizen. It breaks the basis of the type theory OCaml depends on.

In OCaml, there are several ways to write an expression with such an unsound type:

Use of Obj.magic. It screws type system therefore you can write an expression of type 'a which returns:

(Obj.magic 1); print_string "2"

Use of external. Same as Obj.magic you can give arbitrary type to any external values and functions:

external crazy : unit -> 'a = "%identity"
let f () = crazy ()  (* val f : unit -> 'a *)
let _ = f (); print_string "3"

For OCaml type system, it is impossible to distinguish non-returning expressions and expressions with unsound types. This is why it cannot rule out unsound things as errors. Tracking the definitions to tell a statement has an unsound type or not is generally impossible either and costs a lot even when possible.

like image 86
camlspotter Avatar answered Oct 19 '22 18:10

camlspotter