|
| 1 | +# Supplemental |
| 2 | +This folder contains supplemental knowledge about Ocaml you should have. |
| 3 | + |
| 4 | +## Compiling and Running OCaml |
| 5 | +This exercise introduces you to use of the OCaml compiler `ocamlc`. Calling the OCaml compiler directly is often tedious, but we present it here once so you can see what's going on under the hood. In the rest of this course, all projects will be built with Dune. Dune is a build system that automates calling the OCaml compiler for you, and generally you should prefer it to calling the compiler directly. Setting up a minimal Dune project takes very little effort, and thus we recommend using it whenever you want to compile OCaml! |
| 6 | + |
| 7 | +### ocamlc |
| 8 | +`ocamlc` is the basic OCaml compiler. |
| 9 | +Run it as `ocamlc <file-0> ... <file-n>` with all the files that belong to a program to compile it into an executable named a.out. |
| 10 | + |
| 11 | +For example create a file `helloworld.ml` with the content: |
| 12 | + |
| 13 | +```ocaml |
| 14 | +let _ = print_endline "Hello World!" |
| 15 | +``` |
| 16 | + |
| 17 | +Then compile and run it: |
| 18 | + |
| 19 | +```bash |
| 20 | +ocamlc helloworld.ml |
| 21 | +./a.out |
| 22 | +``` |
| 23 | + |
| 24 | +This process also creates `.cmi` and `.cmo` files for each `.ml` file. They are binary representations of the public interface and implementation of a source file. They can be used instead of the source code when including libraries. |
| 25 | + |
| 26 | +Check the [documentation](https://ocaml.org/manual/comp.html) for a list of all command line options and more advanced build steps. |
| 27 | + |
| 28 | +### dune |
| 29 | +Since listing every file required for compiling the program every time will get tedious fast, `dune` is able to find all files involved in a program by following some conventions. |
| 30 | + |
| 31 | +To use dune, first you need to create a file named `dune-project` to tell dune about your project. Although this file can contain many options, all we need is to give it the contents: |
| 32 | + |
| 33 | +```bash |
| 34 | +(lang dune 2.0) |
| 35 | +``` |
| 36 | +Next, a file named `dune` tells dune where it should start searching for program parts and also configures various options. Give it the content |
| 37 | + |
| 38 | +```bash |
| 39 | +(executable |
| 40 | + (name helloworld)) |
| 41 | +``` |
| 42 | + |
| 43 | +to tell dune to create a stand-alone program and to start looking in `helloworld.ml`. |
| 44 | + |
| 45 | +You can tell dune to build you program by running `dune build .` (`.` is the path to the folder of the `dune` file to build). |
| 46 | +You will note that dune only created a file `dune-project` that can be used to organize projects with multiple `dune` files and a directory `_build` that contains all the templorary files from building, but no actual executable to run your program. |
| 47 | + |
| 48 | +How do you run your program with dune? Add the flag `(promote)` to your `dune` file to copy the finished executable to the source directory. |
| 49 | + |
| 50 | +```bash |
| 51 | +(executable |
| 52 | + (name helloworld) |
| 53 | + (promote)) |
| 54 | +``` |
| 55 | + |
| 56 | +and then build again. You will now find a file helloworld.exe that you can use to run your program (dune gives the program the file extension .exe even on platforms other than Windows). |
| 57 | + |
| 58 | +Check the [documentation](https://dune.readthedocs.io/en/stable/dune-files.html#dune) for a list of all options you can use in a `dune` file. |
| 59 | + |
| 60 | +### utop |
| 61 | +Note that since your tutorial and homework assignments are libraries instead of executables they cannot be run directly and instead they just provide a list of functions that can be used by other programs. |
| 62 | +One such program is `utop`: an REPL (Read Eval Print Loop) that can interactivly compile and run any OCaml code. |
| 63 | + |
| 64 | +Go to a new empty directory and create a file `greeter.ml` with content |
| 65 | + |
| 66 | +```ocaml |
| 67 | +let greet name = "Hello " ^ name ^ "!" |
| 68 | +``` |
| 69 | + |
| 70 | +and a file `dune` with content |
| 71 | + |
| 72 | +```bash |
| 73 | +(library |
| 74 | + (name greeter)) |
| 75 | +``` |
| 76 | + |
| 77 | +then run `dune utop .` to start a new utop session with your code loaded. |
| 78 | + |
| 79 | +Here you can then enter any code and for example call your library with |
| 80 | + |
| 81 | +```ocaml |
| 82 | +Greeter.greet "Alice";; |
| 83 | +``` |
| 84 | + |
| 85 | +If you change the source of your library you need to reload it by exiting utop by pressing `Ctrl+D` and restarting utop. |
| 86 | + |
| 87 | +### Example Solution |
| 88 | +```bash |
| 89 | +# ocamlc |
| 90 | + |
| 91 | +mkdir -p /tmp/dunetest && cd /tmp/dunetest |
| 92 | +echo 'let _ = print_endline "Hello World!"' > helloworld.ml |
| 93 | +ocamlc helloworld.ml |
| 94 | +ls |
| 95 | +./a.out |
| 96 | +rm *.cmi *.cmo a.out |
| 97 | + |
| 98 | +# dune |
| 99 | + |
| 100 | +echo '(lang dune 2.0)' > dune-project |
| 101 | +echo '(executable (name helloworld))' > dune |
| 102 | +dune build . |
| 103 | +ls |
| 104 | +echo '(executable (name helloworld) (promote))' > dune |
| 105 | +dune build . |
| 106 | +ls |
| 107 | +./helloworld.exe |
| 108 | + |
| 109 | + |
| 110 | +# utop |
| 111 | + |
| 112 | +rm -rf ./* |
| 113 | +echo 'let greet name = "Hello " ^ name ^ "!"' > greeter.ml |
| 114 | +echo '(library (name greeter))' > dune |
| 115 | +dune utop . |
| 116 | +# Greeter.greet "Alice";; |
| 117 | +``` |
0 commit comments