Is an OCaml function of signature:
'a -> 'b
possible?
I think it might be possible, however, I would not know the underlying logic behind the answer, so having it explained would be great :)
EDIT: It cannot recursively loop forever
Is an OCaml function of signature:
'a -> 'b
possible?
I think it might be possible, however, I would not know the underlying logic behind the answer, so having it explained would be great :)
EDIT: It cannot recursively loop forever
There are several "legitimate" answers. One is to loop forever, which you ruled out:
let rec f x = f x
Another is to diverge by raising an exception or terminating the program:
let f x = exit 0
let f x = assert false
let f x = failwith "die"
It is possible using this:
let rec x = fun y -> x y;;
I'm not sure how it exactly works. I know x would have type:
`a -> `b
and y would have type:
`a
so x:`a->`b y:`a would have type:
`b
The problem is that it seems to go into an infinite loop.
There is Obj
module, with Obj.magic
function. And you can introduce function like magic
, using external %identity
primitive, like:
external magic : 'a -> 'b = "%identity"
But you must understand, that all this bypasses type system, and should be used at all. Without breaking type system, all functions of type 'a -> 'b
share the same property - the do not return: so they should either raise an exception (or use other non-local exit) or do not return at all.
Yes! There are various "trivial" ways to do it (by terminating the program, throwing an exception, or looping forever), but here is a very non-trivial method right from the standard library:
external magic: 'a -> 'b = "%identity"
Here, external
is used to call C functions that use OCaml's C API. Normally, the string would be the name of the C function to call, but"%identity"
is a compiler intrinsic that generates no code, but simply returns its argument. This takes advantage of the fact that OCaml simply trusts the type signatures given for external functions, as it cannot verify them.
It is part of the Obj
module, where such low-level operations live, and is usually known by its fully qualified name, Obj.magic
. It is an unsafe identity cast, as shown by the following:
OCaml version 4.03.0+dev5-2014-10-15
# external magic: 'a -> 'b = "%identity";;
external magic : 'a -> 'b = "%identity"
# Printf.printf "%d\n" (magic 1);;
1
- : unit = ()
# (* Crash *) print_string (magic 1);;
[1] 4010 segmentation fault (core dumped) ocaml
The segfault is because OCaml does not maintain type information at runtime. This cast is unchecked - the compiler/interpreter simply takes your word for it. The last example tries to dereference the internal representation of 1 (which is 0x3, due to the tag bit) as a pointer to a string, and that segfaults.
There are legitimate uses for this function, but they are rare. One set was in the Printf
and Scanf
sources, until a GADT-based solution was adopted. Other uses are in programs generated by Coq (which has a more powerful type system, and so can prove that casts are safe, even though OCaml can't). Other functions in the Obj
module are sometimes used for hacks like mutating cons cells for tail-recursive list operations, and for avoiding indirections in extremely performance-critical code.
As a VERY good rule: If you are not absolutely sure that you should use the functions in the Obj
module, or are not absolutely sure that such use is safe, don't. Using them is a good way to lead to heap corruption, which is both hard to debug and a security vulnerability that can lead to arbitrary code execution, judging by similar problems in C and C++ being exploitable.