| author | wenzelm |
| Sat, 24 Jul 2021 11:56:34 +0200 | |
| changeset 74053 | 54a11c37d5bc |
| parent 74041 | 6bf9f94198a7 |
| child 74057 | 22ad3ac2152c |
| permissions | -rw-r--r-- |
| 61656 | 1 |
(*:maxLineLen=78:*) |
| 61575 | 2 |
|
| 47825 | 3 |
theory Scala |
4 |
imports Base |
|
5 |
begin |
|
6 |
||
| 72252 | 7 |
chapter \<open>Isabelle/Scala systems programming \label{sec:scala}\<close>
|
| 47825 | 8 |
|
| 61575 | 9 |
text \<open> |
| 71907 | 10 |
Isabelle/ML and Isabelle/Scala are the two main implementation languages of |
11 |
the Isabelle environment: |
|
12 |
||
13 |
\<^item> Isabelle/ML is for \<^emph>\<open>mathematics\<close>, to develop tools within the context |
|
14 |
of symbolic logic, e.g.\ for constructing proofs or defining |
|
15 |
domain-specific formal languages. See the \<^emph>\<open>Isabelle/Isar implementation |
|
16 |
manual\<close> @{cite "isabelle-implementation"} for more details.
|
|
17 |
||
18 |
\<^item> Isabelle/Scala is for \<^emph>\<open>physics\<close>, to connect with the world of systems |
|
19 |
and services, including editors and IDE frameworks. |
|
20 |
||
21 |
There are various ways to access Isabelle/Scala modules and operations: |
|
22 |
||
23 |
\<^item> Isabelle command-line tools (\secref{sec:scala-tools}) run in a separate
|
|
24 |
Java process. |
|
25 |
||
26 |
\<^item> Isabelle/ML antiquotations access Isabelle/Scala functions |
|
27 |
(\secref{sec:scala-functions}) via the PIDE protocol: execution happens
|
|
28 |
within the running Java process underlying Isabelle/Scala. |
|
29 |
||
30 |
\<^item> The \<^verbatim>\<open>Console/Scala\<close> plugin of Isabelle/jEdit @{cite "isabelle-jedit"}
|
|
31 |
operates on the running Java application, using the Scala |
|
32 |
read-eval-print-loop (REPL). |
|
33 |
||
| 74041 | 34 |
The main Isabelle/Scala/jEdit functionality is provided by |
35 |
\<^file>\<open>$ISABELLE_HOME/lib/classes/isabelle.jar\<close>. Further underlying Scala and |
|
36 |
Java libraries are bundled with Isabelle, e.g.\ to access SQLite or |
|
37 |
PostgreSQL via JDBC. |
|
| 71907 | 38 |
|
| 74041 | 39 |
Add-on Isabelle components may augment the system environment by providing |
40 |
suitable configuration in \<^path>\<open>etc/settings\<close> (GNU bash script). The |
|
41 |
shell function \<^bash_function>\<open>classpath\<close> helps to write |
|
42 |
\<^path>\<open>etc/settings\<close> in a portable manner: it refers to library \<^verbatim>\<open>jar\<close> |
|
43 |
files in standard POSIX path notation. On Windows, this is converted to |
|
44 |
native platform format, before invoking Java (\secref{sec:scala-tools}).
|
|
| 71907 | 45 |
|
| 74041 | 46 |
\<^medskip> |
47 |
There is also an implicit build process for Isabelle/Scala/Java modules, |
|
48 |
based on \<^path>\<open>etc/build.props\<close> within the component directory (see also |
|
49 |
\secref{sec:scala-build}).
|
|
| 61575 | 50 |
\<close> |
| 47825 | 51 |
|
52 |
||
| 71907 | 53 |
section \<open>Command-line tools \label{sec:scala-tools}\<close>
|
54 |
||
55 |
subsection \<open>Java Runtime Environment \label{sec:tool-java}\<close>
|
|
| 47825 | 56 |
|
| 61575 | 57 |
text \<open> |
58 |
The @{tool_def java} tool is a direct wrapper for the Java Runtime
|
|
59 |
Environment, within the regular Isabelle settings environment |
|
| 71907 | 60 |
(\secref{sec:settings}) and Isabelle classpath. The command line arguments
|
61 |
are that of the bundled Java distribution: see option \<^verbatim>\<open>-help\<close> in |
|
62 |
particular. |
|
| 47825 | 63 |
|
| 71907 | 64 |
The \<^verbatim>\<open>java\<close> executable is taken from @{setting ISABELLE_JDK_HOME}, according
|
65 |
to the standard directory layout for regular distributions of OpenJDK. |
|
66 |
||
67 |
The shell function \<^bash_function>\<open>isabelle_jdk\<close> allows shell scripts to |
|
68 |
invoke other Java tools robustly (e.g.\ \<^verbatim>\<open>isabelle_jdk jar\<close>), without |
|
69 |
depending on accidental operating system installations. |
|
| 58618 | 70 |
\<close> |
| 47825 | 71 |
|
72 |
||
| 71907 | 73 |
subsection \<open>Scala toplevel \label{sec:tool-scala}\<close>
|
| 47825 | 74 |
|
| 61575 | 75 |
text \<open> |
| 71907 | 76 |
The @{tool_def scala} tool is a direct wrapper for the Scala toplevel,
|
77 |
similar to @{tool java} above. The command line arguments are that of the
|
|
78 |
bundled Scala distribution: see option \<^verbatim>\<open>-help\<close> in particular. This allows |
|
79 |
to interact with Isabelle/Scala interactively. |
|
| 71897 | 80 |
\<close> |
81 |
||
82 |
subsubsection \<open>Example\<close> |
|
| 47825 | 83 |
|
| 71897 | 84 |
text \<open> |
85 |
Explore the Isabelle system environment in Scala: |
|
| 71907 | 86 |
@{verbatim [display, indent = 2] \<open>$ isabelle scala\<close>}
|
87 |
@{scala [display, indent = 2]
|
|
| 71897 | 88 |
\<open>import isabelle._ |
89 |
||
90 |
val isabelle_home = Isabelle_System.getenv("ISABELLE_HOME")
|
|
91 |
||
92 |
val options = Options.init() |
|
93 |
options.bool("browser_info")
|
|
94 |
options.string("document")\<close>}
|
|
| 58618 | 95 |
\<close> |
| 47825 | 96 |
|
97 |
||
| 71907 | 98 |
subsection \<open>Scala script wrapper\<close> |
|
52116
abf9fcfa65cf
added isabelle_scala_script wrapper -- NB: portable hash-bang allows exactly one executable, without additional arguments;
wenzelm
parents:
48985
diff
changeset
|
99 |
|
| 61575 | 100 |
text \<open> |
101 |
The executable @{executable "$ISABELLE_HOME/bin/isabelle_scala_script"}
|
|
102 |
allows to run Isabelle/Scala source files stand-alone programs, by using a |
|
| 62415 | 103 |
suitable ``hash-bang'' line and executable file permissions. For example: |
| 71907 | 104 |
@{verbatim [display, indent = 2] \<open>#!/usr/bin/env isabelle_scala_script\<close>}
|
105 |
@{scala [display, indent = 2]
|
|
106 |
\<open>val options = isabelle.Options.init() |
|
|
52116
abf9fcfa65cf
added isabelle_scala_script wrapper -- NB: portable hash-bang allows exactly one executable, without additional arguments;
wenzelm
parents:
48985
diff
changeset
|
107 |
Console.println("browser_info = " + options.bool("browser_info"))
|
|
61407
7ba7b8103565
@{verbatim [display]} supersedes old alltt/ttbox;
wenzelm
parents:
58618
diff
changeset
|
108 |
Console.println("document = " + options.string("document"))\<close>}
|
|
52116
abf9fcfa65cf
added isabelle_scala_script wrapper -- NB: portable hash-bang allows exactly one executable, without additional arguments;
wenzelm
parents:
48985
diff
changeset
|
109 |
|
| 62415 | 110 |
This assumes that the executable may be found via the @{setting PATH} from
|
111 |
the process environment: this is the case when Isabelle settings are active, |
|
112 |
e.g.\ in the context of the main Isabelle tool wrapper |
|
| 63680 | 113 |
\secref{sec:isabelle-tool}. Alternatively, the full
|
114 |
\<^file>\<open>$ISABELLE_HOME/bin/isabelle_scala_script\<close> may be specified in expanded |
|
| 62415 | 115 |
form. |
| 61575 | 116 |
\<close> |
|
52116
abf9fcfa65cf
added isabelle_scala_script wrapper -- NB: portable hash-bang allows exactly one executable, without additional arguments;
wenzelm
parents:
48985
diff
changeset
|
117 |
|
|
71378
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
118 |
|
| 74041 | 119 |
subsection \<open>Scala compiler \label{sec:tool-scalac}\<close>
|
120 |
||
121 |
text \<open> |
|
122 |
The @{tool_def scalac} tool is a direct wrapper for the Scala compiler; see
|
|
123 |
also @{tool scala} above. The command line arguments are that of the
|
|
124 |
bundled Scala distribution. |
|
125 |
||
126 |
This provides a low-level mechanism to compile further Scala modules, |
|
127 |
depending on existing Isabelle/Scala functionality; the resulting \<^verbatim>\<open>class\<close> |
|
128 |
or \<^verbatim>\<open>jar\<close> files can be added to the Java classpath using the shell function |
|
129 |
\<^bash_function>\<open>classpath\<close>. |
|
130 |
||
131 |
A more convenient high-level approach works via \<^path>\<open>etc/build.props\<close> |
|
132 |
(see \secref{sec:scala-build}).
|
|
133 |
\<close> |
|
134 |
||
135 |
||
136 |
section \<open>Isabelle/Scala/Java modules \label{sec:scala-build}\<close>
|
|
137 |
||
138 |
subsection \<open>Component configuration via \<^path>\<open>etc/build.props\<close>\<close> |
|
|
71378
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
139 |
|
|
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
140 |
text \<open> |
| 74041 | 141 |
Isabelle components may augment the Isabelle/Scala/Java environment |
142 |
declaratively via properties given in \<^path>\<open>etc/build.props\<close> (within the |
|
143 |
component directory). This specifies an output \<^verbatim>\<open>jar\<close> \<^emph>\<open>module\<close>, based on |
|
144 |
Scala or Java \<^emph>\<open>sources\<close>, and arbitrary \<^emph>\<open>resources\<close>. Moreover, a module can |
|
145 |
specify \<^emph>\<open>services\<close> that are subclasses of |
|
146 |
\<^scala_type>\<open>isabelle.Isabelle_System.Service\<close>; these have a particular |
|
147 |
meaning to Isabelle/Scala tools. |
|
148 |
||
149 |
Before running a Scala or Java process, the Isabelle system implicitly |
|
150 |
ensures that all provided modules are compiled and packaged (as jars). It is |
|
151 |
also possible to invoke @{tool scala_build} explicitly, with extra options.
|
|
152 |
||
153 |
\<^medskip> |
|
154 |
The syntax of in \<^path>\<open>etc/build.props\<close> follows a regular Java properties |
|
155 |
file\<^footnote>\<open>\<^url>\<open>https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/Properties.html#load(java.io.Reader)\<close>\<close>, |
|
156 |
but the encoding is \<^verbatim>\<open>UTF-8\<close>, instead of historic \<^verbatim>\<open>ISO 8859-1\<close> from the API |
|
157 |
documentation. |
|
158 |
||
159 |
The subsequent properties are relevant for the Scala/Java build process. |
|
160 |
Most properties are optional: the default is an empty string (or list). File |
|
161 |
names are relative to the main component directory and may refer to Isabelle |
|
162 |
settings variables (e.g. \<^verbatim>\<open>$ISABELLE_HOME\<close>). |
|
163 |
||
164 |
\<^item> \<^verbatim>\<open>title\<close> (required) is a human-readable description of the module, used |
|
165 |
in printed messages. |
|
166 |
||
167 |
\<^item> \<^verbatim>\<open>module\<close> specifies a \<^verbatim>\<open>jar\<close> file name for the output module, as result |
|
168 |
of compiling the specified sources (and resources). If this is absent, |
|
169 |
there is no build process, but contributing sources may still be given, |
|
170 |
possibly together with \<^verbatim>\<open>no_module\<close> as described below. |
|
171 |
||
172 |
\<^item> \<^verbatim>\<open>no_module\<close> means that there is no build process, but the specified |
|
173 |
\<^verbatim>\<open>jar\<close> is provided by other means. This is relevant for @{tool
|
|
174 |
scala_project} (\secref{sec:tool-scala-project}), which includes all
|
|
175 |
Scala/Java sources of components, but suppresses \<^verbatim>\<open>jar\<close> modules to avoid |
|
176 |
duplication of content. |
|
177 |
||
178 |
\<^item> \<^verbatim>\<open>scalac_options\<close> and \<^verbatim>\<open>javac_options\<close> augment the default settings |
|
179 |
@{setting_ref ISABELLE_SCALAC_OPTIONS} and @{setting_ref
|
|
180 |
ISABELLE_JAVAC_OPTIONS} for this component; option syntax follows the |
|
181 |
regular command-line tools \<^verbatim>\<open>scalac\<close> and \<^verbatim>\<open>javac\<close>, respectively. |
|
182 |
||
183 |
\<^item> \<^verbatim>\<open>main\<close> specifies the main entry point for the \<^verbatim>\<open>jar\<close> module. This is |
|
184 |
only relevant for direct invocation like ``\<^verbatim>\<open>java -jar test.jar\<close>''. |
|
185 |
||
186 |
\<^item> \<^verbatim>\<open>requirements\<close> is a list of \<^verbatim>\<open>jar\<close> modules that are needed in the |
|
187 |
compilation process, but not provided by the regular classpath (notably |
|
188 |
@{setting ISABELLE_CLASSPATH}).
|
|
189 |
||
| 74053 | 190 |
A \<^emph>\<open>normal entry\<close> refers to a single \<^verbatim>\<open>jar\<close> file name, possibly with |
| 74041 | 191 |
settings variables as usual. E.g. \<^file>\<open>$ISABELLE_SCALA_JAR\<close> for the main |
192 |
\<^file>\<open>$ISABELLE_HOME/lib/classes/isabelle.jar\<close> (especially relevant for |
|
193 |
add-on modules). |
|
194 |
||
| 74053 | 195 |
A \<^emph>\<open>special entry\<close> is of of the form \<^verbatim>\<open>env:\<close>\<open>variable\<close> and refers to a |
| 74041 | 196 |
settings variable from the Isabelle environment: its value may consist of |
197 |
multiple \<^verbatim>\<open>jar\<close> entries (separated by colons). Environment variables are |
|
198 |
not expanded recursively. |
|
199 |
||
200 |
\<^item> \<^verbatim>\<open>resources\<close> is a list of files that should be included in the resulting |
|
201 |
\<^verbatim>\<open>jar\<close> file. Each item consists of a pair separated by colon: |
|
202 |
\<open>source\<close>\<^verbatim>\<open>:\<close>\<open>target\<close> means to copy an existing source file (relative to |
|
203 |
the component directory) to the given target file or directory (relative |
|
204 |
to the \<^verbatim>\<open>jar\<close> name space). A \<open>file\<close> specification without colon |
|
205 |
abbreviates \<open>file\<close>\<^verbatim>\<open>:\<close>\<open>file\<close>, i.e. the file is copied while retaining its |
|
206 |
relative path name. |
|
207 |
||
208 |
\<^item> \<^verbatim>\<open>sources\<close> is a list of \<^verbatim>\<open>.scala\<close> or \<^verbatim>\<open>.java\<close> files that contribute to |
|
209 |
the specified module. It is possible to use both languages simultaneously: |
|
210 |
the Scala and Java compiler will be invoked consecutively to make this |
|
211 |
work. |
|
212 |
||
213 |
\<^item> \<^verbatim>\<open>services\<close> is a list of class names to be registered as Isabelle |
|
214 |
service providers (subclasses of |
|
215 |
\<^scala_type>\<open>isabelle.Isabelle_System.Service\<close>). Internal class names of |
|
216 |
the underlying JVM need to be given: e.g. see method @{scala_method (in
|
|
217 |
java.lang.Object) getClass}. |
|
218 |
||
219 |
Particular services require particular subclasses: instances are filtered |
|
220 |
according to their dynamic type. For example, class |
|
221 |
\<^scala_type>\<open>isabelle.Isabelle_Scala_Tools\<close> collects Scala command-line |
|
222 |
tools, and class \<^scala_type>\<open>isabelle.Scala.Functions\<close> collects Scala |
|
223 |
functions (\secref{sec:scala-functions}).
|
|
224 |
\<close> |
|
225 |
||
226 |
||
227 |
subsection \<open>Explicit Isabelle/Scala/Java build \label{sec:tool-scala-build}\<close>
|
|
228 |
||
229 |
text \<open> |
|
230 |
The @{tool_def scala_build} tool explicitly invokes the build process for
|
|
231 |
all registered components. |
|
232 |
@{verbatim [display]
|
|
233 |
\<open>Usage: isabelle scala_build [OPTIONS] |
|
234 |
||
235 |
Options are: |
|
236 |
-f force fresh build |
|
237 |
-q quiet mode: suppress stdout/stderr |
|
238 |
||
239 |
Build Isabelle/Scala/Java modules of all registered components |
|
240 |
(if required). |
|
241 |
\<close>} |
|
242 |
||
243 |
For each registered Isabelle component that provides |
|
244 |
\<^path>\<open>etc/build.props\<close>, the specified output \<^verbatim>\<open>module\<close> is checked against |
|
245 |
the corresponding input \<^verbatim>\<open>requirements\<close>, \<^verbatim>\<open>resources\<close>, \<^verbatim>\<open>sources\<close>. If |
|
246 |
required, there is an automatic build using \<^verbatim>\<open>scalac\<close> or \<^verbatim>\<open>javac\<close> (or both). |
|
247 |
The identity of input files is recorded within the output \<^verbatim>\<open>jar\<close>, using SHA1 |
|
248 |
digests in \<^verbatim>\<open>META-INF/isabelle/shasum\<close>. |
|
249 |
||
250 |
\<^medskip> |
|
251 |
Option \<^verbatim>\<open>-f\<close> forces a fresh build, regardless of the up-to-date status of |
|
252 |
input files vs. the output module. |
|
253 |
||
254 |
\<^medskip> |
|
255 |
Option \<^verbatim>\<open>-q\<close> suppresses all output on stdout/stderr produced by the Scala or |
|
256 |
Java compiler. |
|
257 |
||
258 |
\<^medskip> Explicit invocation of \<^verbatim>\<open>isabelle scala_build\<close> mainly serves testing or |
|
259 |
applications with special options: the Isabelle system normally does an |
|
260 |
automatic the build on demand. |
|
261 |
\<close> |
|
262 |
||
263 |
||
264 |
subsection \<open>Project setup for common Scala IDEs \label{sec:tool-scala-project}\<close>
|
|
265 |
||
266 |
text \<open> |
|
267 |
The @{tool_def scala_project} tool creates a project configuration for all
|
|
268 |
Isabelle/Scala/Java modules specified in components via \<^path>\<open>etc/build.props\<close>: |
|
|
71378
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
269 |
@{verbatim [display]
|
|
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
270 |
\<open>Usage: isabelle scala_project [OPTIONS] PROJECT_DIR |
|
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
271 |
|
|
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
272 |
Options are: |
| 71503 | 273 |
-L make symlinks to original scala files |
|
71378
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
274 |
|
|
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
275 |
Setup Gradle project for Isabelle/Scala/jEdit --- to support Scala IDEs |
|
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
276 |
such as IntelliJ IDEA.\<close>} |
|
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
277 |
|
| 71389 | 278 |
The generated configuration is for Gradle\<^footnote>\<open>\<^url>\<open>https://gradle.org\<close>\<close>, but the |
279 |
main purpose is to import it into common Scala IDEs, such as IntelliJ |
|
280 |
IDEA\<^footnote>\<open>\<^url>\<open>https://www.jetbrains.com/idea\<close>\<close>. This allows to explore the |
|
281 |
sources with static analysis and other hints in real-time. |
|
|
71378
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
282 |
|
| 71907 | 283 |
The specified project directory needs to be fresh. The generated files refer |
284 |
to physical file-system locations, using the path notation of the underlying |
|
285 |
OS platform. Thus the project needs to be recreated whenever the Isabelle |
|
286 |
installation is changed or moved. |
|
|
71378
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
287 |
|
| 71907 | 288 |
\<^medskip> |
289 |
By default, Scala sources are \<^emph>\<open>copied\<close> from the Isabelle distribution and |
|
|
71378
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
290 |
editing them within the IDE has no permanent effect. |
|
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
291 |
|
| 71523 | 292 |
Option \<^verbatim>\<open>-L\<close> produces \<^emph>\<open>symlinks\<close> to the original files: this allows to |
| 74041 | 293 |
develop Isabelle/Scala/jEdit within an external Scala IDE. Note that the |
294 |
result cannot be built within the IDE: it requires implicit or explicit |
|
295 |
\<^verbatim>\<open>isabelle scala_build\<close> (\secref{sec:tool-scala-build}).
|
|
|
71378
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
296 |
\<close> |
|
820cf124dced
added "isabelle scala_project" to support e.g. IntelliJ IDEA;
wenzelm
parents:
63680
diff
changeset
|
297 |
|
| 71907 | 298 |
|
299 |
section \<open>Registered Isabelle/Scala functions \label{sec:scala-functions}\<close>
|
|
300 |
||
301 |
subsection \<open>Defining functions in Isabelle/Scala\<close> |
|
302 |
||
303 |
text \<open> |
|
304 |
A Scala functions of type \<^scala_type>\<open>String => String\<close> may be wrapped as |
|
305 |
\<^scala_type>\<open>isabelle.Scala.Fun\<close> and collected via an instance of the |
|
| 74041 | 306 |
class \<^scala_type>\<open>isabelle.Scala.Functions\<close>. A system component can then |
307 |
register that class via \<^verbatim>\<open>services\<close> in \<^path>\<open>etc/build.props\<close> |
|
308 |
(\secref{sec:scala-build}). An example is the predefined collection of
|
|
309 |
\<^scala_type>\<open>isabelle.Scala.Functions\<close> in \<^file>\<open>$ISABELLE_HOME/etc/build.props\<close>. |
|
| 71907 | 310 |
|
311 |
The overall list of registered functions is accessible in Isabelle/Scala as |
|
312 |
\<^scala_object>\<open>isabelle.Scala.functions\<close>. |
|
313 |
\<close> |
|
314 |
||
315 |
||
316 |
subsection \<open>Invoking functions in Isabelle/ML\<close> |
|
317 |
||
318 |
text \<open> |
|
319 |
Isabelle/PIDE provides a protocol to invoke registered Scala functions in |
|
| 72103 | 320 |
ML: this works both within the Prover IDE and in batch builds. |
| 71907 | 321 |
|
322 |
The subsequent ML antiquotations refer to Scala functions in a |
|
323 |
formally-checked manner. |
|
324 |
||
325 |
\begin{matharray}{rcl}
|
|
326 |
@{ML_antiquotation_def "scala_function"} & : & \<open>ML_antiquotation\<close> \\
|
|
327 |
@{ML_antiquotation_def "scala"} & : & \<open>ML_antiquotation\<close> \\
|
|
328 |
\end{matharray}
|
|
329 |
||
330 |
\<^rail>\<open> |
|
|
72332
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72252
diff
changeset
|
331 |
(@{ML_antiquotation scala_function} |
|
|
73419
22f3f2117ed7
clarified signature: function_thread is determined in Isabelle/Scala, not Isabelle/ML;
wenzelm
parents:
72759
diff
changeset
|
332 |
@{ML_antiquotation scala}) @{syntax embedded}
|
| 71907 | 333 |
\<close> |
334 |
||
335 |
\<^descr> \<open>@{scala_function name}\<close> inlines the checked function name as ML string
|
|
336 |
literal. |
|
337 |
||
|
72332
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72252
diff
changeset
|
338 |
\<^descr> \<open>@{scala name}\<close> and \<open>@{scala_thread name}\<close> invoke the checked function via
|
|
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72252
diff
changeset
|
339 |
the PIDE protocol. In Isabelle/ML this appears as a function of type |
| 71907 | 340 |
\<^ML_type>\<open>string -> string\<close>, which is subject to interrupts within the ML |
341 |
runtime environment as usual. A \<^scala>\<open>null\<close> result in Scala raises an |
|
|
72332
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72252
diff
changeset
|
342 |
exception \<^ML>\<open>Scala.Null\<close> in ML. The execution of \<open>@{scala}\<close> works via a
|
|
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72252
diff
changeset
|
343 |
Scala future on a bounded thread farm, while \<open>@{scala_thread}\<close> always forks
|
|
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72252
diff
changeset
|
344 |
a separate Java thread. |
| 71907 | 345 |
|
346 |
The standard approach of representing datatypes via strings works via XML in |
|
347 |
YXML transfer syntax. See Isabelle/ML operations and modules @{ML
|
|
348 |
YXML.string_of_body}, @{ML YXML.parse_body}, @{ML_structure XML.Encode},
|
|
349 |
@{ML_structure XML.Decode}; similarly for Isabelle/Scala. Isabelle symbols
|
|
350 |
may have to be recoded via Scala operations |
|
351 |
\<^scala_method>\<open>isabelle.Symbol.decode\<close> and |
|
352 |
\<^scala_method>\<open>isabelle.Symbol.encode\<close>. |
|
353 |
\<close> |
|
354 |
||
355 |
||
356 |
subsubsection \<open>Examples\<close> |
|
357 |
||
358 |
text \<open> |
|
| 72759 | 359 |
Invoke the predefined Scala function \<^scala_function>\<open>echo\<close>: |
| 71907 | 360 |
\<close> |
361 |
||
362 |
ML \<open> |
|
363 |
val s = "test"; |
|
364 |
val s' = \<^scala>\<open>echo\<close> s; |
|
365 |
\<^assert> (s = s') |
|
366 |
\<close> |
|
367 |
||
368 |
text \<open> |
|
369 |
Let the Scala compiler process some toplevel declarations, producing a list |
|
370 |
of errors: |
|
371 |
\<close> |
|
372 |
||
373 |
ML \<open> |
|
374 |
val source = "class A(a: Int, b: Boolean)" |
|
375 |
val errors = |
|
376 |
\<^scala>\<open>scala_toplevel\<close> source |
|
377 |
|> YXML.parse_body |
|
378 |
|> let open XML.Decode in list string end; |
|
379 |
||
380 |
\<^assert> (null errors)\<close> |
|
381 |
||
382 |
text \<open> |
|
383 |
The above is merely for demonstration. See \<^ML>\<open>Scala_Compiler.toplevel\<close> |
|
384 |
for a more convenient version with builtin decoding and treatment of errors. |
|
385 |
\<close> |
|
386 |
||
387 |
||
388 |
section \<open>Documenting Isabelle/Scala entities\<close> |
|
389 |
||
390 |
text \<open> |
|
391 |
The subsequent document antiquotations help to document Isabelle/Scala |
|
392 |
entities, with formal checking of names against the Isabelle classpath. |
|
393 |
||
394 |
\begin{matharray}{rcl}
|
|
395 |
@{antiquotation_def "scala"} & : & \<open>antiquotation\<close> \\
|
|
396 |
@{antiquotation_def "scala_object"} & : & \<open>antiquotation\<close> \\
|
|
397 |
@{antiquotation_def "scala_type"} & : & \<open>antiquotation\<close> \\
|
|
398 |
@{antiquotation_def "scala_method"} & : & \<open>antiquotation\<close> \\
|
|
399 |
\end{matharray}
|
|
400 |
||
401 |
\<^rail>\<open> |
|
402 |
(@@{antiquotation scala} | @@{antiquotation scala_object})
|
|
403 |
@{syntax embedded}
|
|
404 |
; |
|
405 |
@@{antiquotation scala_type} @{syntax embedded} types
|
|
406 |
; |
|
407 |
@@{antiquotation scala_method} class @{syntax embedded} types args
|
|
408 |
; |
|
409 |
class: ('(' @'in' @{syntax name} types ')')?
|
|
410 |
; |
|
411 |
types: ('[' (@{syntax name} ',' +) ']')?
|
|
412 |
; |
|
413 |
args: ('(' (nat | (('_' | @{syntax name}) + ',')) ')')?
|
|
414 |
\<close> |
|
415 |
||
416 |
\<^descr> \<open>@{scala s}\<close> is similar to \<open>@{verbatim s}\<close>, but the given source text is
|
|
417 |
checked by the Scala compiler as toplevel declaration (without evaluation). |
|
418 |
This allows to write Isabelle/Scala examples that are statically checked. |
|
419 |
||
420 |
\<^descr> \<open>@{scala_object x}\<close> checks the given Scala object name (simple value or
|
|
421 |
ground module) and prints the result verbatim. |
|
422 |
||
423 |
\<^descr> \<open>@{scala_type T[A]}\<close> checks the given Scala type name (with optional type
|
|
424 |
parameters) and prints the result verbatim. |
|
425 |
||
426 |
\<^descr> \<open>@{scala_method (in c[A]) m[B](n)}\<close> checks the given Scala method \<open>m\<close> in
|
|
427 |
the context of class \<open>c\<close>. The method argument slots are either specified by |
|
428 |
a number \<open>n\<close> or by a list of (optional) argument types; this may refer to |
|
429 |
type variables specified for the class or method: \<open>A\<close> or \<open>B\<close> above. |
|
430 |
||
431 |
Everything except for the method name \<open>m\<close> is optional. The absence of the |
|
432 |
class context means that this is a static method. The absence of arguments |
|
433 |
with types means that the method can be determined uniquely as \<^verbatim>\<open>(\<close>\<open>m\<close>\<^verbatim>\<open> _)\<close> |
|
434 |
in Scala (no overloading). |
|
435 |
\<close> |
|
436 |
||
437 |
||
438 |
subsubsection \<open>Examples\<close> |
|
439 |
||
440 |
text \<open> |
|
441 |
Miscellaneous Isabelle/Scala entities: |
|
442 |
||
443 |
\<^item> object: \<^scala_object>\<open>isabelle.Isabelle_Process\<close> |
|
444 |
\<^item> type without parameter: @{scala_type isabelle.Console_Progress}
|
|
445 |
\<^item> type with parameter: @{scala_type List[A]}
|
|
446 |
\<^item> static method: \<^scala_method>\<open>isabelle.Isabelle_System.bash\<close> |
|
447 |
\<^item> class and method with type parameters: |
|
448 |
@{scala_method (in List[A]) map[B]("A => B")}
|
|
449 |
\<^item> overloaded method with argument type: @{scala_method (in Int) "+" (Int)}
|
|
450 |
\<close> |
|
451 |
||
| 47825 | 452 |
end |