How does one print a function value?

For example wanted to print the following:

let add_three x y z = z + y + z;;
let h = add_three 5 4;;

how do I print h?

can one use Printf?

Functional values are not data, therefore there is no reason or way to print them.

In general, in OCaml there is no canonical value representation or printing, like in Python, for example. For each type one can write a function that will print some representation of values of this type. It is totally arbitrary and up to a developer discretion.

Another thing to understand about OCaml, is that programs written in OCaml are compiled to machine code, and there are no types or any other runtime supporting information, available during program execution. Functions are just pointers to the code section of the program and closures are just pointers to the heap allocated values. Therefore there is no value in printing those addresses.

but I can print it in the interactive version. Why not in my script too?

val f' : int -> int = <fun>
# f';;
- : int -> int = <fun>

Im not compiling I am just running

ocaml my_script.ml

You’re not printing it in the interactive version, it is the OCaml toplevel system that prints it. Since in the interactive toplevel is not executing a compiled program, but rather compiles and interprets it, it has a full access to the typing environment, therefore it is able to give you some representation. However, the printed value is just val h, i.e., it is only the name of the variable. (Or just <fun> in case if it is an anonymous function).

If you want to print the type of the function, it is also not possible. Again, OCaml doesn’t have any reflection - i.e., an ability to query program structure from the program itself.

so I can’t do it even if I am just doing ocaml my_script.ml?

It is probably would be better if you will tell us what problem you’re hoping to solve by printing the function, and what output you’re expecting, then it would be possible to give you a more direct solution.

I’ve stated exactly what I want. To print a function just like in the toplevel but when I use ocaml command (which afaik doesn’t compile…)

Thats all.

Im trying to use toplevel without having to re open it every time so Im just using a script.

Btw, thnx for the help! :slight_smile:

Im just learning for the moment. No real code.

No, you can’t do this, unless you’re going to bring in the compiler internals and use the compiler libs.

Im trying to use toplevel without having to re open it every time so Im just using a script.

Yep, so that’ts the crux of the problem. Indeed, reopening it every time you make a change is indeed painful and definitely not the way it was designed. Have you read this topic?

2 Likes

I will check it out.

Thanks! :slight_smile:

Maybe it’ll help to explain a little more. Ocaml, like all ML-family languages, has what’s called “type eraseure semantics”. This means that executing a fully-typed program to a value, and then erasing all the type information, gives the same result as erasing all the type information from the program, and then executing that to a value. This means that a compiler can compile a program to code that lacks any runtime type information, and that’s what ML compilers typically do.

Now, the toplevel uses the normal Ocaml compiler (sure, bytecode version, but still a normal compiler), so the actual code that it runs, doesn’t have any type information. But remember that the toplevel started with your source code, parsed it, typechecked, compiled, and only then ran the compiled code. So it knows the type of the value produced by your code’s execution, and so, when it gets that (remember, untyped) value (which is just a pointer or primitive value), it can use the type information to interpret that value and print something out.

The “compiler libs” that are referred-to by other comments, are some of the code that knows how to interpret “in parallel” the type information and the untyped value… [full disclosure: maybe not exactly right; but the topplevel does use code that knows, for any particular type-constructor, the layout of corresponding values, and by induction on the type of a value, that means that it can traverse that untyped value.]

So really what’s happening, is that the toplevel has a special “escape clause”. That isn’t available to normal ML code, and by design.

You can start the toplevel ocaml and then inside the toploop you can type:

#use "my_script.ml"

Then you will get the signatures of the contents of your script.
You can also use the following command:

ocamlc -i my_script.ml

this will also print the signature of the contents of your script, which can also be used as an .mli file if it was a usable module.