author | wenzelm |
Mon, 09 Dec 2013 12:22:23 +0100 | |
changeset 54703 | 499f92dc6e45 |
parent 54387 | 890e983cb07b |
child 55112 | b1a5d603fd12 |
permissions | -rw-r--r-- |
29755 | 1 |
theory "ML" |
2 |
imports Base |
|
3 |
begin |
|
18538 | 4 |
|
39822 | 5 |
chapter {* Isabelle/ML *} |
20489 | 6 |
|
39823 | 7 |
text {* Isabelle/ML is best understood as a certain culture based on |
8 |
Standard ML. Thus it is not a new programming language, but a |
|
9 |
certain way to use SML at an advanced level within the Isabelle |
|
10 |
environment. This covers a variety of aspects that are geared |
|
11 |
towards an efficient and robust platform for applications of formal |
|
12 |
logic with fully foundational proof construction --- according to |
|
40126 | 13 |
the well-known \emph{LCF principle}. There is specific |
14 |
infrastructure with library modules to address the needs of this |
|
15 |
difficult task. For example, the raw parallel programming model of |
|
16 |
Poly/ML is presented as considerably more abstract concept of |
|
17 |
\emph{future values}, which is then used to augment the inference |
|
18 |
kernel, proof interpreter, and theory loader accordingly. |
|
39823 | 19 |
|
20 |
The main aspects of Isabelle/ML are introduced below. These |
|
21 |
first-hand explanations should help to understand how proper |
|
22 |
Isabelle/ML is to be read and written, and to get access to the |
|
23 |
wealth of experience that is expressed in the source text and its |
|
24 |
history of changes.\footnote{See |
|
54703 | 25 |
@{url "http://isabelle.in.tum.de/repos/isabelle"} for the full |
39823 | 26 |
Mercurial history. There are symbolic tags to refer to official |
27 |
Isabelle releases, as opposed to arbitrary \emph{tip} versions that |
|
28 |
merely reflect snapshots that are never really up-to-date.} *} |
|
29 |
||
30 |
||
39878 | 31 |
section {* Style and orthography *} |
32 |
||
39879 | 33 |
text {* The sources of Isabelle/Isar are optimized for |
34 |
\emph{readability} and \emph{maintainability}. The main purpose is |
|
35 |
to tell an informed reader what is really going on and how things |
|
36 |
really work. This is a non-trivial aim, but it is supported by a |
|
37 |
certain style of writing Isabelle/ML that has emerged from long |
|
38 |
years of system development.\footnote{See also the interesting style |
|
39 |
guide for OCaml |
|
54703 | 40 |
@{url "http://caml.inria.fr/resources/doc/guides/guidelines.en.html"} |
39878 | 41 |
which shares many of our means and ends.} |
42 |
||
43 |
The main principle behind any coding style is \emph{consistency}. |
|
39879 | 44 |
For a single author of a small program this merely means ``choose |
39878 | 45 |
your style and stick to it''. A complex project like Isabelle, with |
39879 | 46 |
long years of development and different contributors, requires more |
47 |
standardization. A coding style that is changed every few years or |
|
48 |
with every new contributor is no style at all, because consistency |
|
49 |
is quickly lost. Global consistency is hard to achieve, though. |
|
40126 | 50 |
Nonetheless, one should always strive at least for local consistency |
51 |
of modules and sub-systems, without deviating from some general |
|
52 |
principles how to write Isabelle/ML. |
|
39878 | 53 |
|
40126 | 54 |
In a sense, good coding style is like an \emph{orthography} for the |
55 |
sources: it helps to read quickly over the text and see through the |
|
56 |
main points, without getting distracted by accidental presentation |
|
57 |
of free-style code. |
|
39878 | 58 |
*} |
59 |
||
60 |
||
61 |
subsection {* Header and sectioning *} |
|
62 |
||
39879 | 63 |
text {* Isabelle source files have a certain standardized header |
64 |
format (with precise spacing) that follows ancient traditions |
|
65 |
reaching back to the earliest versions of the system by Larry |
|
40800
330eb65c9469
Parse.liberal_name for document antiquotations and attributes;
wenzelm
parents:
40508
diff
changeset
|
66 |
Paulson. See @{file "~~/src/Pure/thm.ML"}, for example. |
39878 | 67 |
|
68 |
The header includes at least @{verbatim Title} and @{verbatim |
|
69 |
Author} entries, followed by a prose description of the purpose of |
|
70 |
the module. The latter can range from a single line to several |
|
71 |
paragraphs of explanations. |
|
72 |
||
73 |
The rest of the file is divided into sections, subsections, |
|
40126 | 74 |
subsubsections, paragraphs etc.\ using a simple layout via ML |
75 |
comments as follows. |
|
39878 | 76 |
|
77 |
\begin{verbatim} |
|
78 |
(*** section ***) |
|
79 |
||
80 |
(** subsection **) |
|
81 |
||
82 |
(* subsubsection *) |
|
83 |
||
84 |
(*short paragraph*) |
|
85 |
||
86 |
(* |
|
40126 | 87 |
long paragraph, |
88 |
with more text |
|
39878 | 89 |
*) |
90 |
\end{verbatim} |
|
91 |
||
92 |
As in regular typography, there is some extra space \emph{before} |
|
93 |
section headings that are adjacent to plain text (not other headings |
|
94 |
as in the example above). |
|
95 |
||
96 |
\medskip The precise wording of the prose text given in these |
|
40126 | 97 |
headings is chosen carefully to introduce the main theme of the |
39879 | 98 |
subsequent formal ML text. |
99 |
*} |
|
100 |
||
101 |
||
39880 | 102 |
subsection {* Naming conventions *} |
39879 | 103 |
|
104 |
text {* Since ML is the primary medium to express the meaning of the |
|
105 |
source text, naming of ML entities requires special care. |
|
106 |
||
39881 | 107 |
\paragraph{Notation.} A name consists of 1--3 \emph{words} (rarely |
108 |
4, but not more) that are separated by underscore. There are three |
|
40126 | 109 |
variants concerning upper or lower case letters, which are used for |
39881 | 110 |
certain ML categories as follows: |
39880 | 111 |
|
112 |
\medskip |
|
113 |
\begin{tabular}{lll} |
|
114 |
variant & example & ML categories \\\hline |
|
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
115 |
lower-case & @{ML_text foo_bar} & values, types, record fields \\ |
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
116 |
capitalized & @{ML_text Foo_Bar} & datatype constructors, structures, functors \\ |
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
117 |
upper-case & @{ML_text FOO_BAR} & special values, exception constructors, signatures \\ |
39880 | 118 |
\end{tabular} |
119 |
\medskip |
|
120 |
||
121 |
For historical reasons, many capitalized names omit underscores, |
|
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
122 |
e.g.\ old-style @{ML_text FooBar} instead of @{ML_text Foo_Bar}. |
47180 | 123 |
Genuine mixed-case names are \emph{not} used, because clear division |
40126 | 124 |
of words is essential for readability.\footnote{Camel-case was |
125 |
invented to workaround the lack of underscore in some early |
|
126 |
non-ASCII character sets. Later it became habitual in some language |
|
127 |
communities that are now strong in numbers.} |
|
39880 | 128 |
|
39881 | 129 |
A single (capital) character does not count as ``word'' in this |
40126 | 130 |
respect: some Isabelle/ML names are suffixed by extra markers like |
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
131 |
this: @{ML_text foo_barT}. |
39881 | 132 |
|
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
133 |
Name variants are produced by adding 1--3 primes, e.g.\ @{ML_text |
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
134 |
foo'}, @{ML_text foo''}, or @{ML_text foo'''}, but not @{ML_text |
39881 | 135 |
foo''''} or more. Decimal digits scale better to larger numbers, |
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
136 |
e.g.\ @{ML_text foo0}, @{ML_text foo1}, @{ML_text foo42}. |
39880 | 137 |
|
138 |
\paragraph{Scopes.} Apart from very basic library modules, ML |
|
139 |
structures are not ``opened'', but names are referenced with |
|
39881 | 140 |
explicit qualification, as in @{ML Syntax.string_of_term} for |
39880 | 141 |
example. When devising names for structures and their components it |
142 |
is important aim at eye-catching compositions of both parts, because |
|
40126 | 143 |
this is how they are seen in the sources and documentation. For the |
144 |
same reasons, aliases of well-known library functions should be |
|
145 |
avoided. |
|
39880 | 146 |
|
40126 | 147 |
Local names of function abstraction or case/let bindings are |
39880 | 148 |
typically shorter, sometimes using only rudiments of ``words'', |
149 |
while still avoiding cryptic shorthands. An auxiliary function |
|
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
150 |
called @{ML_text helper}, @{ML_text aux}, or @{ML_text f} is |
39880 | 151 |
considered bad style. |
152 |
||
153 |
Example: |
|
154 |
||
155 |
\begin{verbatim} |
|
156 |
(* RIGHT *) |
|
157 |
||
158 |
fun print_foo ctxt foo = |
|
159 |
let |
|
39881 | 160 |
fun print t = ... Syntax.string_of_term ctxt t ... |
161 |
in ... end; |
|
162 |
||
163 |
||
164 |
(* RIGHT *) |
|
165 |
||
166 |
fun print_foo ctxt foo = |
|
167 |
let |
|
39880 | 168 |
val string_of_term = Syntax.string_of_term ctxt; |
169 |
fun print t = ... string_of_term t ... |
|
170 |
in ... end; |
|
171 |
||
172 |
||
173 |
(* WRONG *) |
|
174 |
||
175 |
val string_of_term = Syntax.string_of_term; |
|
176 |
||
177 |
fun print_foo ctxt foo = |
|
178 |
let |
|
179 |
fun aux t = ... string_of_term ctxt t ... |
|
180 |
in ... end; |
|
181 |
||
182 |
\end{verbatim} |
|
183 |
||
184 |
||
40126 | 185 |
\paragraph{Specific conventions.} Here are some specific name forms |
186 |
that occur frequently in the sources. |
|
39881 | 187 |
|
188 |
\begin{itemize} |
|
189 |
||
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
190 |
\item A function that maps @{ML_text foo} to @{ML_text bar} is |
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
191 |
called @{ML_text foo_to_bar} or @{ML_text bar_of_foo} (never |
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
192 |
@{ML_text foo2bar}, @{ML_text bar_from_foo}, @{ML_text |
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
193 |
bar_for_foo}, or @{ML_text bar4foo}). |
39881 | 194 |
|
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
195 |
\item The name component @{ML_text legacy} means that the operation |
39881 | 196 |
is about to be discontinued soon. |
197 |
||
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
198 |
\item The name component @{ML_text old} means that this is historic |
39881 | 199 |
material that might disappear at some later stage. |
200 |
||
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
201 |
\item The name component @{ML_text global} means that this works |
39881 | 202 |
with the background theory instead of the regular local context |
203 |
(\secref{sec:context}), sometimes for historical reasons, sometimes |
|
204 |
due a genuine lack of locality of the concept involved, sometimes as |
|
205 |
a fall-back for the lack of a proper context in the application |
|
206 |
code. Whenever there is a non-global variant available, the |
|
207 |
application should be migrated to use it with a proper local |
|
208 |
context. |
|
209 |
||
210 |
\item Variables of the main context types of the Isabelle/Isar |
|
211 |
framework (\secref{sec:context} and \chref{ch:local-theory}) have |
|
40126 | 212 |
firm naming conventions as follows: |
39881 | 213 |
|
214 |
\begin{itemize} |
|
215 |
||
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
216 |
\item theories are called @{ML_text thy}, rarely @{ML_text theory} |
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
217 |
(never @{ML_text thry}) |
39881 | 218 |
|
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
219 |
\item proof contexts are called @{ML_text ctxt}, rarely @{ML_text |
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
220 |
context} (never @{ML_text ctx}) |
39881 | 221 |
|
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
222 |
\item generic contexts are called @{ML_text context}, rarely |
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
223 |
@{ML_text ctxt} |
39881 | 224 |
|
40149
4c35be108990
proper markup of uninterpreted ML text as @{ML_text}, not @{verbatim};
wenzelm
parents:
40126
diff
changeset
|
225 |
\item local theories are called @{ML_text lthy}, except for local |
40126 | 226 |
theories that are treated as proof context (which is a semantic |