Skip to content

Commit

Permalink
Merge pull request #1765 from Octachron/manual_ellipsis_in_examples
Browse files Browse the repository at this point in the history
manual: ellipses in examples
(cherry picked from commit 7398fd2)
  • Loading branch information
gasche committed May 7, 2018
1 parent d040ad6 commit f59941a
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 70 deletions.
3 changes: 3 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ OCaml 4.07
- GPR#1741: manual, improve typesetting and legibility in HTML output
(steinuil, review by Gabriel Scherer)

- GPR#1765: manual, ellipsis in code examples
(Florian Angeletti, review and suggestion by Gabriel Scherer)

### Compiler distribution build system

- MPR#5219, GPR#1680: use 'install' instead of 'cp' in install scripts
Expand Down
28 changes: 25 additions & 3 deletions manual/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,31 @@ let f None = None [@@expect warning 8];;
\end{caml_example}
```

The `caml_eval` environment is a companion environment to `caml_example`
and can be used to evaluate OCaml expressions in the toplevel without
printing anything:
It is also possible to elide a code fragment by annotating it with
an `[@ellipsis]` attribute

```latex
\begin{caml_example}{toplevel}
let f: type a. a list -> int = List.length[@ellipsis] ;;
\end{caml_example}
```
For module components, it might be easier to hide them by using
`[@@@ellipsis.start]` and `[@@@ellipsis.stop]`:
```latex
\begin{caml_example*}{verbatim}
module M = struct
[@@@ellipsis.start]
type t = T
let x = 0
[@@@ellipsis.stop]
end
\end{caml_example*}
```

Another possibility to avoid displaying distracting code is to use
the `caml_eval` environment. This environment is a companion environment
to `caml_example` and can be used to evaluate OCaml expressions in the
toplevel without printing anything:
```latex
\begin{caml_eval}
let pi = 4. *. atan 1.;;
Expand Down
42 changes: 21 additions & 21 deletions manual/manual/refman/exten.etex
Original file line number Diff line number Diff line change
Expand Up @@ -460,22 +460,22 @@ suspend the evaluation of @expr@ as a regular abstraction would. The
syntax has been chosen to fit nicely in the context of function
declarations, where it is generally used. It is possible to freely mix
regular function parameters with pseudo type parameters, as in:
\begin{verbatim}
let f = fun (type t) (foo : t list) -> ...
\end{verbatim}
\begin{caml_example*}{verbatim}
let f = fun (type t) (foo : t list) -> assert false[@ellipsis]
\end{caml_example*}
and even use the alternative syntax for declaring functions:
\begin{verbatim}
let f (type t) (foo : t list) = ...
\end{verbatim}
\begin{caml_example*}{verbatim}
let f (type t) (foo : t list) = assert false[@ellipsis]
\end{caml_example*}
If several locally abstract types need to be introduced, it is possible to use
the syntax
@"fun" '(' "type" typeconstr-name_1 \ldots typeconstr-name_n ')' "->" expr@
as syntactic sugar for @"fun" '(' "type" typeconstr-name_1 ')' "->" \ldots "->"
"fun" '(' "type" typeconstr-name_n ')' "->" expr@. For instance,
\begin{verbatim}
let f = fun (type t u v) -> fun (foo : (t * u * v) list) -> ...
let f' (type t u v) (foo : (t * u * v) list) = ...
\end{verbatim}
\begin{caml_example*}{verbatim}
let f = fun (type t u v) -> fun (foo : (t * u * v) list) -> assert false[@ellipsis]
let f' (type t u v) (foo : (t * u * v) list) = assert false[@ellipsis]
\end{caml_example}

This construction is useful because the type constructors it introduces
can be used in places where a type variable is not allowed. For
Expand Down Expand Up @@ -518,15 +518,15 @@ The @"(type" typeconstr-name")"@ syntax construction by itself does not make
polymorphic the type variable it introduces, but it can be combined
with explicit polymorphic annotations where needed.
The above rule is provided as syntactic sugar to make this easier:
\begin{verbatim}
let rec f : type t1 t2. t1 * t2 list -> t1 = ...
\end{verbatim}
\begin{caml_example*}{verbatim}
let rec f : type t1 t2. t1 * t2 list -> t1 = assert false[@ellipsis]
\end{caml_example*}
\noindent
is automatically expanded into
\begin{verbatim}
\begin{caml_example*}{verbatim}
let rec f : 't1 't2. 't1 * 't2 list -> 't1 =
fun (type t1) (type t2) -> (... : t1 * t2 list -> t1)
\end{verbatim}
fun (type t1) (type t2) -> ( assert false[@ellipsis] : t1 * t2 list -> t1)
\end{caml_example*}
This syntax can be very useful when defining recursive functions involving
GADTs, see the section~\ref{s:gadts} for a more detailed explanation.

Expand Down Expand Up @@ -620,16 +620,16 @@ select at run-time among several implementations of a signature.
Each implementation is a structure that we can encapsulate as a
first-class module, then store in a data structure such as a hash
table:
\begin{verbatim}
module type DEVICE = sig ... end
\begin{caml_example*}{verbatim}
module type DEVICE = sig [@@@ellipsis] end
let devices : (string, (module DEVICE)) Hashtbl.t = Hashtbl.create 17

module SVG = struct ... end
module SVG = struct [@@@ellipsis] end
let _ = Hashtbl.add devices "SVG" (module SVG : DEVICE)

module PDF = struct ... end
module PDF = struct [@@@ellipsis] end
let _ = Hashtbl.add devices "PDF" (module PDF: DEVICE)
\end{verbatim}
\end{caml_example*}
We can then select one implementation based on command-line
arguments, for instance:
\begin{verbatim}
Expand Down
5 changes: 3 additions & 2 deletions manual/tools/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ htmlgen: latexmacros.cmo latexscan.cmo latexmain.cmo
latexscan.ml: latexscan.mll
ocamllex latexscan.mll

caml-tex2: caml_tex2.cmo
$(OCAMLC) -o caml-tex2 str.cma unix.cma caml_tex2.cmo
caml-tex2: caml_tex2.ml
$(OCAMLC) $(TOPDIR)/compilerlibs/ocamlcommon.cma -I $(TOPDIR)/parsing \
-o caml-tex2 str.cma unix.cma caml_tex2.ml

.SUFFIXES:
.SUFFIXES: .ml .cmo .mli .cmi .c
Expand Down
Loading

0 comments on commit f59941a

Please sign in to comment.