Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the compiler stop complaining about `type unit` in this case?

Tags:

ocaml

If I do let f1 x = x; x+1, compiler will complain: Warning 10: this expression should have type unit.

If I do let f2 f = f(); 5, compiler will give val f2 : (unit -> 'a) -> int = <fun>.

Questions

  1. The type system infers that f is a function which take unit as parameter and returns 'a. But if it returns 'a, why the compiler does not give Warning 10?
  2. If compiler does not give Warning 10, it means it thinks f() returns unit, doesn't it? Then why it give 'a as the return type?
like image 373
Jackson Tale Avatar asked Apr 16 '14 22:04

Jackson Tale


People also ask

What is the difference between compiler and type checker?

The compiler contains modules, where the type checker is a module of a compiler and its task is type checking. Conversion from one type to another type is known as implicit if it is to be done automatically by the compiler. Implicit type conversions are also called Coercion and coercion is limited in many languages.

What should a compiler check before writing a program?

A compiler must check that the source program should follow the syntactic and semantic conventions of the source language and it should also check the type rules of the language. It allows the programmer to limit what types may be used in certain circumstances and assigns types to values.

What does it mean when a compiler error is ambiguous?

Whenever you see a compiler error that says something is ambiguous it normally means that you have opened some namespaces (ie using namespace std;) and other namespaces and cout is defined in both namespaces. This means it is ambiguous, the compiler does not know which definition you mean.

What is true and false in C++ with example?

In C (and in C++), any expression whether its type is numeric, pointer, etc. is considered true if the value of that expression is non-zero (i.e., has any bits turned on). Any expression with a value of zero (i.e., all bits turned off) is considered false.


2 Answers

If compiler does not give Warning 10, it means it thinks f() returns unit, doesn't it?

Obviously, if the compiler gives f2 the type (unit -> 'a) -> int, that means it thinks f returns 'a.

What would you do in the compiler's place?

  • Would you warn that f2 may be applied to some functions that return non-unit results, although it may never actually be applied thus?

  • Would you give f2 the type (unit -> unit) -> int and make it less useful, forcing it to be used only with functions that return ()?

  • Would you invent a complicated system of postponed warnings where f2 has type (unit -> 'a) -> int but produces an additional warning at compile-time if it is applied to a function that does not return ()? Would you make this system work across modules (the postponed warnings of a function would have to be part of the module signatures)?

Warnings are only helpful hints, not guarantees. When in doubt, not emitting the warning is the usual solution (and nearly all compilers adopt this solution, not just the OCaml compilers).

like image 167
Pascal Cuoq Avatar answered Sep 26 '22 14:09

Pascal Cuoq


I think this is legacy behaviour from the compiler. Use -strict-sequence to fix it:

$ ocaml
# let f2 f = f(); 5;;
val f2 : (unit -> 'a) -> int = <fun>

But:

$ ocaml -strict-sequence
# let f2 f = f(); 5;;
val f2 : (unit -> unit) -> int = <fun>

If you use ocamlbuild, you should put this in your _tags file:

true: strict_sequence
like image 27
Thomas Leonard Avatar answered Sep 25 '22 14:09

Thomas Leonard