2 |
2 |
3 theory "ML" |
3 theory "ML" |
4 imports Base |
4 imports Base |
5 begin |
5 begin |
6 |
6 |
7 chapter {* Isabelle/ML *} |
7 chapter \<open>Isabelle/ML\<close> |
8 |
8 |
9 text {* Isabelle/ML is best understood as a certain culture based on |
9 text \<open>Isabelle/ML is best understood as a certain culture based on |
10 Standard ML. Thus it is not a new programming language, but a |
10 Standard ML. Thus it is not a new programming language, but a |
11 certain way to use SML at an advanced level within the Isabelle |
11 certain way to use SML at an advanced level within the Isabelle |
12 environment. This covers a variety of aspects that are geared |
12 environment. This covers a variety of aspects that are geared |
13 towards an efficient and robust platform for applications of formal |
13 towards an efficient and robust platform for applications of formal |
14 logic with fully foundational proof construction --- according to |
14 logic with fully foundational proof construction --- according to |
25 wealth of experience that is expressed in the source text and its |
25 wealth of experience that is expressed in the source text and its |
26 history of changes.\footnote{See |
26 history of changes.\footnote{See |
27 @{url "http://isabelle.in.tum.de/repos/isabelle"} for the full |
27 @{url "http://isabelle.in.tum.de/repos/isabelle"} for the full |
28 Mercurial history. There are symbolic tags to refer to official |
28 Mercurial history. There are symbolic tags to refer to official |
29 Isabelle releases, as opposed to arbitrary \emph{tip} versions that |
29 Isabelle releases, as opposed to arbitrary \emph{tip} versions that |
30 merely reflect snapshots that are never really up-to-date.} *} |
30 merely reflect snapshots that are never really up-to-date.}\<close> |
31 |
31 |
32 |
32 |
33 section {* Style and orthography *} |
33 section \<open>Style and orthography\<close> |
34 |
34 |
35 text {* The sources of Isabelle/Isar are optimized for |
35 text \<open>The sources of Isabelle/Isar are optimized for |
36 \emph{readability} and \emph{maintainability}. The main purpose is |
36 \emph{readability} and \emph{maintainability}. The main purpose is |
37 to tell an informed reader what is really going on and how things |
37 to tell an informed reader what is really going on and how things |
38 really work. This is a non-trivial aim, but it is supported by a |
38 really work. This is a non-trivial aim, but it is supported by a |
39 certain style of writing Isabelle/ML that has emerged from long |
39 certain style of writing Isabelle/ML that has emerged from long |
40 years of system development.\footnote{See also the interesting style |
40 years of system development.\footnote{See also the interesting style |
55 |
55 |
56 In a sense, good coding style is like an \emph{orthography} for the |
56 In a sense, good coding style is like an \emph{orthography} for the |
57 sources: it helps to read quickly over the text and see through the |
57 sources: it helps to read quickly over the text and see through the |
58 main points, without getting distracted by accidental presentation |
58 main points, without getting distracted by accidental presentation |
59 of free-style code. |
59 of free-style code. |
60 *} |
60 \<close> |
61 |
61 |
62 |
62 |
63 subsection {* Header and sectioning *} |
63 subsection \<open>Header and sectioning\<close> |
64 |
64 |
65 text {* Isabelle source files have a certain standardized header |
65 text \<open>Isabelle source files have a certain standardized header |
66 format (with precise spacing) that follows ancient traditions |
66 format (with precise spacing) that follows ancient traditions |
67 reaching back to the earliest versions of the system by Larry |
67 reaching back to the earliest versions of the system by Larry |
68 Paulson. See @{file "~~/src/Pure/thm.ML"}, for example. |
68 Paulson. See @{file "~~/src/Pure/thm.ML"}, for example. |
69 |
69 |
70 The header includes at least @{verbatim Title} and @{verbatim |
70 The header includes at least @{verbatim Title} and @{verbatim |
96 as in the example above. |
96 as in the example above. |
97 |
97 |
98 \medskip The precise wording of the prose text given in these |
98 \medskip The precise wording of the prose text given in these |
99 headings is chosen carefully to introduce the main theme of the |
99 headings is chosen carefully to introduce the main theme of the |
100 subsequent formal ML text. |
100 subsequent formal ML text. |
101 *} |
101 \<close> |
102 |
102 |
103 |
103 |
104 subsection {* Naming conventions *} |
104 subsection \<open>Naming conventions\<close> |
105 |
105 |
106 text {* Since ML is the primary medium to express the meaning of the |
106 text \<open>Since ML is the primary medium to express the meaning of the |
107 source text, naming of ML entities requires special care. |
107 source text, naming of ML entities requires special care. |
108 |
108 |
109 \paragraph{Notation.} A name consists of 1--3 \emph{words} (rarely |
109 \paragraph{Notation.} A name consists of 1--3 \emph{words} (rarely |
110 4, but not more) that are separated by underscore. There are three |
110 4, but not more) that are separated by underscore. There are three |
111 variants concerning upper or lower case letters, which are used for |
111 variants concerning upper or lower case letters, which are used for |
280 in the @{verbatim ctxt} argument above. Do not refer to the background |
280 in the @{verbatim ctxt} argument above. Do not refer to the background |
281 theory of @{verbatim st} -- it is not a proper context, but merely a formal |
281 theory of @{verbatim st} -- it is not a proper context, but merely a formal |
282 certificate. |
282 certificate. |
283 |
283 |
284 \end{itemize} |
284 \end{itemize} |
285 *} |
285 \<close> |
286 |
286 |
287 |
287 |
288 subsection {* General source layout *} |
288 subsection \<open>General source layout\<close> |
289 |
289 |
290 text {* |
290 text \<open> |
291 The general Isabelle/ML source layout imitates regular type-setting |
291 The general Isabelle/ML source layout imitates regular type-setting |
292 conventions, augmented by the requirements for deeply nested expressions |
292 conventions, augmented by the requirements for deeply nested expressions |
293 that are commonplace in functional programming. |
293 that are commonplace in functional programming. |
294 |
294 |
295 \paragraph{Line length} is limited to 80 characters according to ancient |
295 \paragraph{Line length} is limited to 80 characters according to ancient |
517 \end{verbatim} |
517 \end{verbatim} |
518 |
518 |
519 \medskip In general the source layout is meant to emphasize the |
519 \medskip In general the source layout is meant to emphasize the |
520 structure of complex language expressions, not to pretend that SML |
520 structure of complex language expressions, not to pretend that SML |
521 had a completely different syntax (say that of Haskell, Scala, Java). |
521 had a completely different syntax (say that of Haskell, Scala, Java). |
522 *} |
522 \<close> |
523 |
523 |
524 |
524 |
525 section {* ML embedded into Isabelle/Isar *} |
525 section \<open>ML embedded into Isabelle/Isar\<close> |
526 |
526 |
527 text {* ML and Isar are intertwined via an open-ended bootstrap |
527 text \<open>ML and Isar are intertwined via an open-ended bootstrap |
528 process that provides more and more programming facilities and |
528 process that provides more and more programming facilities and |
529 logical content in an alternating manner. Bootstrapping starts from |
529 logical content in an alternating manner. Bootstrapping starts from |
530 the raw environment of existing implementations of Standard ML |
530 the raw environment of existing implementations of Standard ML |
531 (mainly Poly/ML, but also SML/NJ). |
531 (mainly Poly/ML, but also SML/NJ). |
532 |
532 |
542 ".ML"} files that are loading from some theory. Thus Isabelle/HOL is defined |
542 ".ML"} files that are loading from some theory. Thus Isabelle/HOL is defined |
543 as a regular user-space application within the Isabelle framework. Further |
543 as a regular user-space application within the Isabelle framework. Further |
544 add-on tools can be implemented in ML within the Isar context in the same |
544 add-on tools can be implemented in ML within the Isar context in the same |
545 manner: ML is part of the standard repertoire of Isabelle, and there is no |
545 manner: ML is part of the standard repertoire of Isabelle, and there is no |
546 distinction between ``users'' and ``developers'' in this respect. |
546 distinction between ``users'' and ``developers'' in this respect. |
547 *} |
547 \<close> |
548 |
548 |
549 |
549 |
550 subsection {* Isar ML commands *} |
550 subsection \<open>Isar ML commands\<close> |
551 |
551 |
552 text {* |
552 text \<open> |
553 The primary Isar source language provides facilities to ``open a window'' to |
553 The primary Isar source language provides facilities to ``open a window'' to |
554 the underlying ML compiler. Especially see the Isar commands @{command_ref |
554 the underlying ML compiler. Especially see the Isar commands @{command_ref |
555 "ML_file"} and @{command_ref "ML"}: both work the same way, but the source |
555 "ML_file"} and @{command_ref "ML"}: both work the same way, but the source |
556 text is provided differently, via a file vs.\ inlined, respectively. Apart |
556 text is provided differently, via a file vs.\ inlined, respectively. Apart |
557 from embedding ML into the main theory definition like that, there are many |
557 from embedding ML into the main theory definition like that, there are many |
558 more commands that refer to ML source, such as @{command_ref setup} or |
558 more commands that refer to ML source, such as @{command_ref setup} or |
559 @{command_ref declaration}. Even more fine-grained embedding of ML into Isar |
559 @{command_ref declaration}. Even more fine-grained embedding of ML into Isar |
560 is encountered in the proof method @{method_ref tactic}, which refines the |
560 is encountered in the proof method @{method_ref tactic}, which refines the |
561 pending goal state via a given expression of type @{ML_type tactic}. |
561 pending goal state via a given expression of type @{ML_type tactic}. |
562 *} |
562 \<close> |
563 |
563 |
564 text %mlex {* The following artificial example demonstrates some ML |
564 text %mlex \<open>The following artificial example demonstrates some ML |
565 toplevel declarations within the implicit Isar theory context. This |
565 toplevel declarations within the implicit Isar theory context. This |
566 is regular functional programming without referring to logical |
566 is regular functional programming without referring to logical |
567 entities yet. |
567 entities yet. |
568 *} |
568 \<close> |
569 |
569 |
570 ML {* |
570 ML \<open> |
571 fun factorial 0 = 1 |
571 fun factorial 0 = 1 |
572 | factorial n = n * factorial (n - 1) |
572 | factorial n = n * factorial (n - 1) |
573 *} |
573 \<close> |
574 |
574 |
575 text {* Here the ML environment is already managed by Isabelle, i.e.\ |
575 text \<open>Here the ML environment is already managed by Isabelle, i.e.\ |
576 the @{ML factorial} function is not yet accessible in the preceding |
576 the @{ML factorial} function is not yet accessible in the preceding |
577 paragraph, nor in a different theory that is independent from the |
577 paragraph, nor in a different theory that is independent from the |
578 current one in the import hierarchy. |
578 current one in the import hierarchy. |
579 |
579 |
580 Removing the above ML declaration from the source text will remove any trace |
580 Removing the above ML declaration from the source text will remove any trace |
587 |
587 |
588 \medskip The next example shows how to embed ML into Isar proofs, using |
588 \medskip The next example shows how to embed ML into Isar proofs, using |
589 @{command_ref "ML_prf"} instead of Instead of @{command_ref "ML"}. |
589 @{command_ref "ML_prf"} instead of Instead of @{command_ref "ML"}. |
590 As illustrated below, the effect on the ML environment is local to |
590 As illustrated below, the effect on the ML environment is local to |
591 the whole proof body, but ignoring the block structure. |
591 the whole proof body, but ignoring the block structure. |
592 *} |
592 \<close> |
593 |
593 |
594 notepad |
594 notepad |
595 begin |
595 begin |
596 ML_prf %"ML" {* val a = 1 *} |
596 ML_prf %"ML" \<open>val a = 1\<close> |
597 { |
597 { |
598 ML_prf %"ML" {* val b = a + 1 *} |
598 ML_prf %"ML" \<open>val b = a + 1\<close> |
599 } -- {* Isar block structure ignored by ML environment *} |
599 } -- \<open>Isar block structure ignored by ML environment\<close> |
600 ML_prf %"ML" {* val c = b + 1 *} |
600 ML_prf %"ML" \<open>val c = b + 1\<close> |
601 end |
601 end |
602 |
602 |
603 text {* By side-stepping the normal scoping rules for Isar proof |
603 text \<open>By side-stepping the normal scoping rules for Isar proof |
604 blocks, embedded ML code can refer to the different contexts and |
604 blocks, embedded ML code can refer to the different contexts and |
605 manipulate corresponding entities, e.g.\ export a fact from a block |
605 manipulate corresponding entities, e.g.\ export a fact from a block |
606 context. |
606 context. |
607 |
607 |
608 \medskip Two further ML commands are useful in certain situations: |
608 \medskip Two further ML commands are useful in certain situations: |
610 the sense that there is no effect on the underlying environment, and can |
610 the sense that there is no effect on the underlying environment, and can |
611 thus be used anywhere. The examples below produce long strings of digits by |
611 thus be used anywhere. The examples below produce long strings of digits by |
612 invoking @{ML factorial}: @{command ML_val} takes care of printing the ML |
612 invoking @{ML factorial}: @{command ML_val} takes care of printing the ML |
613 toplevel result, but @{command ML_command} is silent so we produce an |
613 toplevel result, but @{command ML_command} is silent so we produce an |
614 explicit output message. |
614 explicit output message. |
615 *} |
615 \<close> |
616 |
616 |
617 ML_val {* factorial 100 *} |
617 ML_val \<open>factorial 100\<close> |
618 ML_command {* writeln (string_of_int (factorial 100)) *} |
618 ML_command \<open>writeln (string_of_int (factorial 100))\<close> |
619 |
619 |
620 notepad |
620 notepad |
621 begin |
621 begin |
622 ML_val {* factorial 100 *} |
622 ML_val \<open>factorial 100\<close> |
623 ML_command {* writeln (string_of_int (factorial 100)) *} |
623 ML_command \<open>writeln (string_of_int (factorial 100))\<close> |
624 end |
624 end |
625 |
625 |
626 |
626 |
627 subsection {* Compile-time context *} |
627 subsection \<open>Compile-time context\<close> |
628 |
628 |
629 text {* Whenever the ML compiler is invoked within Isabelle/Isar, the |
629 text \<open>Whenever the ML compiler is invoked within Isabelle/Isar, the |
630 formal context is passed as a thread-local reference variable. Thus |
630 formal context is passed as a thread-local reference variable. Thus |
631 ML code may access the theory context during compilation, by reading |
631 ML code may access the theory context during compilation, by reading |
632 or writing the (local) theory under construction. Note that such |
632 or writing the (local) theory under construction. Note that such |
633 direct access to the compile-time context is rare. In practice it |
633 direct access to the compile-time context is rare. In practice it |
634 is typically done via some derived ML functions instead. |
634 is typically done via some derived ML functions instead. |
635 *} |
635 \<close> |
636 |
636 |
637 text %mlref {* |
637 text %mlref \<open> |
638 \begin{mldecls} |
638 \begin{mldecls} |
639 @{index_ML ML_Context.the_generic_context: "unit -> Context.generic"} \\ |
639 @{index_ML ML_Context.the_generic_context: "unit -> Context.generic"} \\ |
640 @{index_ML "Context.>>": "(Context.generic -> Context.generic) -> unit"} \\ |
640 @{index_ML "Context.>>": "(Context.generic -> Context.generic) -> unit"} \\ |
641 @{index_ML ML_Thms.bind_thms: "string * thm list -> unit"} \\ |
641 @{index_ML ML_Thms.bind_thms: "string * thm list -> unit"} \\ |
642 @{index_ML ML_Thms.bind_thm: "string * thm -> unit"} \\ |
642 @{index_ML ML_Thms.bind_thm: "string * thm -> unit"} \\ |
665 It is important to note that the above functions are really |
665 It is important to note that the above functions are really |
666 restricted to the compile time, even though the ML compiler is |
666 restricted to the compile time, even though the ML compiler is |
667 invoked at run-time. The majority of ML code either uses static |
667 invoked at run-time. The majority of ML code either uses static |
668 antiquotations (\secref{sec:ML-antiq}) or refers to the theory or |
668 antiquotations (\secref{sec:ML-antiq}) or refers to the theory or |
669 proof context at run-time, by explicit functional abstraction. |
669 proof context at run-time, by explicit functional abstraction. |
670 *} |
670 \<close> |
671 |
671 |
672 |
672 |
673 subsection {* Antiquotations \label{sec:ML-antiq} *} |
673 subsection \<open>Antiquotations \label{sec:ML-antiq}\<close> |
674 |
674 |
675 text {* A very important consequence of embedding ML into Isar is the |
675 text \<open>A very important consequence of embedding ML into Isar is the |
676 concept of \emph{ML antiquotation}. The standard token language of |
676 concept of \emph{ML antiquotation}. The standard token language of |
677 ML is augmented by special syntactic entities of the following form: |
677 ML is augmented by special syntactic entities of the following form: |
678 |
678 |
679 @{rail \<open> |
679 @{rail \<open> |
680 @{syntax_def antiquote}: '@{' nameref args '}' |
680 @{syntax_def antiquote}: '@{' nameref args '}' |
689 \emph{inline} text (e.g.\ @{text "@{term t}"}) or abstract |
689 \emph{inline} text (e.g.\ @{text "@{term t}"}) or abstract |
690 \emph{value} (e.g. @{text "@{thm th}"}). This pre-compilation |
690 \emph{value} (e.g. @{text "@{thm th}"}). This pre-compilation |
691 scheme allows to refer to formal entities in a robust manner, with |
691 scheme allows to refer to formal entities in a robust manner, with |
692 proper static scoping and with some degree of logical checking of |
692 proper static scoping and with some degree of logical checking of |
693 small portions of the code. |
693 small portions of the code. |
694 *} |
694 \<close> |
695 |
695 |
696 |
696 |
697 subsection {* Printing ML values *} |
697 subsection \<open>Printing ML values\<close> |
698 |
698 |
699 text {* The ML compiler knows about the structure of values according |
699 text \<open>The ML compiler knows about the structure of values according |
700 to their static type, and can print them in the manner of its |
700 to their static type, and can print them in the manner of its |
701 toplevel, although the details are non-portable. The |
701 toplevel, although the details are non-portable. The |
702 antiquotations @{ML_antiquotation_def "make_string"} and |
702 antiquotations @{ML_antiquotation_def "make_string"} and |
703 @{ML_antiquotation_def "print"} provide a quasi-portable way to |
703 @{ML_antiquotation_def "print"} provide a quasi-portable way to |
704 refer to this potential capability of the underlying ML system in |
704 refer to this potential capability of the underlying ML system in |
705 generic Isabelle/ML sources. |
705 generic Isabelle/ML sources. |
706 |
706 |
707 This is occasionally useful for diagnostic or demonstration |
707 This is occasionally useful for diagnostic or demonstration |
708 purposes. Note that production-quality tools require proper |
708 purposes. Note that production-quality tools require proper |
709 user-level error messages, avoiding raw ML values in the output. *} |
709 user-level error messages, avoiding raw ML values in the output.\<close> |
710 |
710 |
711 text %mlantiq {* |
711 text %mlantiq \<open> |
712 \begin{matharray}{rcl} |
712 \begin{matharray}{rcl} |
713 @{ML_antiquotation_def "make_string"} & : & @{text ML_antiquotation} \\ |
713 @{ML_antiquotation_def "make_string"} & : & @{text ML_antiquotation} \\ |
714 @{ML_antiquotation_def "print"} & : & @{text ML_antiquotation} \\ |
714 @{ML_antiquotation_def "print"} & : & @{text ML_antiquotation} \\ |
715 \end{matharray} |
715 \end{matharray} |
716 |
716 |
731 unit"} to output the result of @{text "@{make_string}"} above, |
731 unit"} to output the result of @{text "@{make_string}"} above, |
732 together with the source position of the antiquotation. The default |
732 together with the source position of the antiquotation. The default |
733 output function is @{ML writeln}. |
733 output function is @{ML writeln}. |
734 |
734 |
735 \end{description} |
735 \end{description} |
736 *} |
736 \<close> |
737 |
737 |
738 text %mlex {* The following artificial examples show how to produce |
738 text %mlex \<open>The following artificial examples show how to produce |
739 adhoc output of ML values for debugging purposes. *} |
739 adhoc output of ML values for debugging purposes.\<close> |
740 |
740 |
741 ML {* |
741 ML \<open> |
742 val x = 42; |
742 val x = 42; |
743 val y = true; |
743 val y = true; |
744 |
744 |
745 writeln (@{make_string} {x = x, y = y}); |
745 writeln (@{make_string} {x = x, y = y}); |
746 |
746 |
747 @{print} {x = x, y = y}; |
747 @{print} {x = x, y = y}; |
748 @{print tracing} {x = x, y = y}; |
748 @{print tracing} {x = x, y = y}; |
749 *} |
749 \<close> |
750 |
750 |
751 |
751 |
752 section {* Canonical argument order \label{sec:canonical-argument-order} *} |
752 section \<open>Canonical argument order \label{sec:canonical-argument-order}\<close> |
753 |
753 |
754 text {* Standard ML is a language in the tradition of @{text |
754 text \<open>Standard ML is a language in the tradition of @{text |
755 "\<lambda>"}-calculus and \emph{higher-order functional programming}, |
755 "\<lambda>"}-calculus and \emph{higher-order functional programming}, |
756 similar to OCaml, Haskell, or Isabelle/Pure and HOL as logical |
756 similar to OCaml, Haskell, or Isabelle/Pure and HOL as logical |
757 languages. Getting acquainted with the native style of representing |
757 languages. Getting acquainted with the native style of representing |
758 functions in that setting can save a lot of extra boiler-plate of |
758 functions in that setting can save a lot of extra boiler-plate of |
759 redundant shuffling of arguments, auxiliary abstractions etc. |
759 redundant shuffling of arguments, auxiliary abstractions etc. |
816 insert a value @{text "a"}. These can be composed naturally as |
816 insert a value @{text "a"}. These can be composed naturally as |
817 @{text "insert c \<circ> insert b \<circ> insert a"}. The slightly awkward |
817 @{text "insert c \<circ> insert b \<circ> insert a"}. The slightly awkward |
818 inversion of the composition order is due to conventional |
818 inversion of the composition order is due to conventional |
819 mathematical notation, which can be easily amended as explained |
819 mathematical notation, which can be easily amended as explained |
820 below. |
820 below. |
821 *} |
821 \<close> |
822 |
822 |
823 |
823 |
824 subsection {* Forward application and composition *} |
824 subsection \<open>Forward application and composition\<close> |
825 |
825 |
826 text {* Regular function application and infix notation works best for |
826 text \<open>Regular function application and infix notation works best for |
827 relatively deeply structured expressions, e.g.\ @{text "h (f x y + g |
827 relatively deeply structured expressions, e.g.\ @{text "h (f x y + g |
828 z)"}. The important special case of \emph{linear transformation} |
828 z)"}. The important special case of \emph{linear transformation} |
829 applies a cascade of functions @{text "f\<^sub>n (\<dots> (f\<^sub>1 x))"}. This |
829 applies a cascade of functions @{text "f\<^sub>n (\<dots> (f\<^sub>1 x))"}. This |
830 becomes hard to read and maintain if the functions are themselves |
830 becomes hard to read and maintain if the functions are themselves |
831 given as complex expressions. The notation can be significantly |
831 given as complex expressions. The notation can be significantly |
851 \begin{tabular}{lll} |
851 \begin{tabular}{lll} |
852 @{text "(x, y) |-> f"} & @{text "\<equiv>"} & @{text "f x y"} \\ |
852 @{text "(x, y) |-> f"} & @{text "\<equiv>"} & @{text "f x y"} \\ |
853 @{text "(f #-> g) x"} & @{text "\<equiv>"} & @{text "x |> f |-> g"} \\ |
853 @{text "(f #-> g) x"} & @{text "\<equiv>"} & @{text "x |> f |-> g"} \\ |
854 \end{tabular} |
854 \end{tabular} |
855 \medskip |
855 \medskip |
856 *} |
856 \<close> |
857 |
857 |
858 text %mlref {* |
858 text %mlref \<open> |
859 \begin{mldecls} |
859 \begin{mldecls} |
860 @{index_ML_op "|> ": "'a * ('a -> 'b) -> 'b"} \\ |
860 @{index_ML_op "|> ": "'a * ('a -> 'b) -> 'b"} \\ |
861 @{index_ML_op "|-> ": "('c * 'a) * ('c -> 'a -> 'b) -> 'b"} \\ |
861 @{index_ML_op "|-> ": "('c * 'a) * ('c -> 'a -> 'b) -> 'b"} \\ |
862 @{index_ML_op "#> ": "('a -> 'b) * ('b -> 'c) -> 'a -> 'c"} \\ |
862 @{index_ML_op "#> ": "('a -> 'b) * ('b -> 'c) -> 'a -> 'c"} \\ |
863 @{index_ML_op "#-> ": "('a -> 'c * 'b) * ('c -> 'b -> 'd) -> 'a -> 'd"} \\ |
863 @{index_ML_op "#-> ": "('a -> 'c * 'b) * ('c -> 'b -> 'd) -> 'a -> 'd"} \\ |
864 \end{mldecls} |
864 \end{mldecls} |
865 *} |
865 \<close> |
866 |
866 |
867 |
867 |
868 subsection {* Canonical iteration *} |
868 subsection \<open>Canonical iteration\<close> |
869 |
869 |
870 text {* As explained above, a function @{text "f: \<alpha> \<rightarrow> \<beta> \<rightarrow> \<beta>"} can be |
870 text \<open>As explained above, a function @{text "f: \<alpha> \<rightarrow> \<beta> \<rightarrow> \<beta>"} can be |
871 understood as update on a configuration of type @{text "\<beta>"}, |
871 understood as update on a configuration of type @{text "\<beta>"}, |
872 parameterized by an argument of type @{text "\<alpha>"}. Given @{text "a: \<alpha>"} |
872 parameterized by an argument of type @{text "\<alpha>"}. Given @{text "a: \<alpha>"} |
873 the partial application @{text "(f a): \<beta> \<rightarrow> \<beta>"} operates |
873 the partial application @{text "(f a): \<beta> \<rightarrow> \<beta>"} operates |
874 homogeneously on @{text "\<beta>"}. This can be iterated naturally over a |
874 homogeneously on @{text "\<beta>"}. This can be iterated naturally over a |
875 list of parameters @{text "[a\<^sub>1, \<dots>, a\<^sub>n]"} as @{text "f a\<^sub>1 #> \<dots> #> f a\<^sub>n"}. |
875 list of parameters @{text "[a\<^sub>1, \<dots>, a\<^sub>n]"} as @{text "f a\<^sub>1 #> \<dots> #> f a\<^sub>n"}. |
889 |
889 |
890 The @{text "fold_map"} combinator essentially performs @{text |
890 The @{text "fold_map"} combinator essentially performs @{text |
891 "fold"} and @{text "map"} simultaneously: each application of @{text |
891 "fold"} and @{text "map"} simultaneously: each application of @{text |
892 "f"} produces an updated configuration together with a side-result; |
892 "f"} produces an updated configuration together with a side-result; |
893 the iteration collects all such side-results as a separate list. |
893 the iteration collects all such side-results as a separate list. |
894 *} |
894 \<close> |
895 |
895 |
896 text %mlref {* |
896 text %mlref \<open> |
897 \begin{mldecls} |
897 \begin{mldecls} |
898 @{index_ML fold: "('a -> 'b -> 'b) -> 'a list -> 'b -> 'b"} \\ |
898 @{index_ML fold: "('a -> 'b -> 'b) -> 'a list -> 'b -> 'b"} \\ |
899 @{index_ML fold_rev: "('a -> 'b -> 'b) -> 'a list -> 'b -> 'b"} \\ |
899 @{index_ML fold_rev: "('a -> 'b -> 'b) -> 'a list -> 'b -> 'b"} \\ |
900 @{index_ML fold_map: "('a -> 'b -> 'c * 'b) -> 'a list -> 'b -> 'c list * 'b"} \\ |
900 @{index_ML fold_map: "('a -> 'b -> 'c * 'b) -> 'a list -> 'b -> 'c list * 'b"} \\ |
901 \end{mldecls} |
901 \end{mldecls} |
921 Isabelle library also has the historic @{ML Library.foldl} and @{ML |
921 Isabelle library also has the historic @{ML Library.foldl} and @{ML |
922 Library.foldr}. To avoid unnecessary complication, all these historical |
922 Library.foldr}. To avoid unnecessary complication, all these historical |
923 versions should be ignored, and the canonical @{ML fold} (or @{ML fold_rev}) |
923 versions should be ignored, and the canonical @{ML fold} (or @{ML fold_rev}) |
924 used exclusively. |
924 used exclusively. |
925 \end{warn} |
925 \end{warn} |
926 *} |
926 \<close> |
927 |
927 |
928 text %mlex {* The following example shows how to fill a text buffer |
928 text %mlex \<open>The following example shows how to fill a text buffer |
929 incrementally by adding strings, either individually or from a given |
929 incrementally by adding strings, either individually or from a given |
930 list. |
930 list. |
931 *} |
931 \<close> |
932 |
932 |
933 ML {* |
933 ML \<open> |
934 val s = |
934 val s = |
935 Buffer.empty |
935 Buffer.empty |
936 |> Buffer.add "digits: " |
936 |> Buffer.add "digits: " |
937 |> fold (Buffer.add o string_of_int) (0 upto 9) |
937 |> fold (Buffer.add o string_of_int) (0 upto 9) |
938 |> Buffer.content; |
938 |> Buffer.content; |
939 |
939 |
940 @{assert} (s = "digits: 0123456789"); |
940 @{assert} (s = "digits: 0123456789"); |
941 *} |
941 \<close> |
942 |
942 |
943 text {* Note how @{ML "fold (Buffer.add o string_of_int)"} above saves |
943 text \<open>Note how @{ML "fold (Buffer.add o string_of_int)"} above saves |
944 an extra @{ML "map"} over the given list. This kind of peephole |
944 an extra @{ML "map"} over the given list. This kind of peephole |
945 optimization reduces both the code size and the tree structures in |
945 optimization reduces both the code size and the tree structures in |
946 memory (``deforestation''), but it requires some practice to read |
946 memory (``deforestation''), but it requires some practice to read |
947 and write fluently. |
947 and write fluently. |
948 |
948 |
949 \medskip The next example elaborates the idea of canonical |
949 \medskip The next example elaborates the idea of canonical |
950 iteration, demonstrating fast accumulation of tree content using a |
950 iteration, demonstrating fast accumulation of tree content using a |
951 text buffer. |
951 text buffer. |
952 *} |
952 \<close> |
953 |
953 |
954 ML {* |
954 ML \<open> |
955 datatype tree = Text of string | Elem of string * tree list; |
955 datatype tree = Text of string | Elem of string * tree list; |
956 |
956 |
957 fun slow_content (Text txt) = txt |
957 fun slow_content (Text txt) = txt |
958 | slow_content (Elem (name, ts)) = |
958 | slow_content (Elem (name, ts)) = |
959 "<" ^ name ^ ">" ^ |
959 "<" ^ name ^ ">" ^ |
966 fold add_content ts #> |
966 fold add_content ts #> |
967 Buffer.add ("</" ^ name ^ ">"); |
967 Buffer.add ("</" ^ name ^ ">"); |
968 |
968 |
969 fun fast_content tree = |
969 fun fast_content tree = |
970 Buffer.empty |> add_content tree |> Buffer.content; |
970 Buffer.empty |> add_content tree |> Buffer.content; |
971 *} |
971 \<close> |
972 |
972 |
973 text {* The slowness of @{ML slow_content} is due to the @{ML implode} of |
973 text \<open>The slowness of @{ML slow_content} is due to the @{ML implode} of |
974 the recursive results, because it copies previously produced strings |
974 the recursive results, because it copies previously produced strings |
975 again and again. |
975 again and again. |
976 |
976 |
977 The incremental @{ML add_content} avoids this by operating on a |
977 The incremental @{ML add_content} avoids this by operating on a |
978 buffer that is passed through in a linear fashion. Using @{ML_text |
978 buffer that is passed through in a linear fashion. Using @{ML_text |
992 |
992 |
993 Note that @{ML fast_content} above is only defined as example. In |
993 Note that @{ML fast_content} above is only defined as example. In |
994 many practical situations, it is customary to provide the |
994 many practical situations, it is customary to provide the |
995 incremental @{ML add_content} only and leave the initialization and |
995 incremental @{ML add_content} only and leave the initialization and |
996 termination to the concrete application to the user. |
996 termination to the concrete application to the user. |
997 *} |
997 \<close> |
998 |
998 |
999 |
999 |
1000 section {* Message output channels \label{sec:message-channels} *} |
1000 section \<open>Message output channels \label{sec:message-channels}\<close> |
1001 |
1001 |
1002 text {* Isabelle provides output channels for different kinds of |
1002 text \<open>Isabelle provides output channels for different kinds of |
1003 messages: regular output, high-volume tracing information, warnings, |
1003 messages: regular output, high-volume tracing information, warnings, |
1004 and errors. |
1004 and errors. |
1005 |
1005 |
1006 Depending on the user interface involved, these messages may appear |
1006 Depending on the user interface involved, these messages may appear |
1007 in different text styles or colours. The standard output for |
1007 in different text styles or colours. The standard output for |
1013 Messages are associated with the transaction context of the running |
1013 Messages are associated with the transaction context of the running |
1014 Isar command. This enables the front-end to manage commands and |
1014 Isar command. This enables the front-end to manage commands and |
1015 resulting messages together. For example, after deleting a command |
1015 resulting messages together. For example, after deleting a command |
1016 from a given theory document version, the corresponding message |
1016 from a given theory document version, the corresponding message |
1017 output can be retracted from the display. |
1017 output can be retracted from the display. |
1018 *} |
1018 \<close> |
1019 |
1019 |
1020 text %mlref {* |
1020 text %mlref \<open> |
1021 \begin{mldecls} |
1021 \begin{mldecls} |
1022 @{index_ML writeln: "string -> unit"} \\ |
1022 @{index_ML writeln: "string -> unit"} \\ |
1023 @{index_ML tracing: "string -> unit"} \\ |
1023 @{index_ML tracing: "string -> unit"} \\ |
1024 @{index_ML warning: "string -> unit"} \\ |
1024 @{index_ML warning: "string -> unit"} \\ |
1025 @{index_ML error: "string -> 'a"} % FIXME Output.error_message (!?) \\ |
1025 @{index_ML error: "string -> 'a"} % FIXME Output.error_message (!?) \\ |
1080 The message channels should be used in a message-oriented manner. |
1080 The message channels should be used in a message-oriented manner. |
1081 This means that multi-line output that logically belongs together is |
1081 This means that multi-line output that logically belongs together is |
1082 issued by a single invocation of @{ML writeln} etc.\ with the |
1082 issued by a single invocation of @{ML writeln} etc.\ with the |
1083 functional concatenation of all message constituents. |
1083 functional concatenation of all message constituents. |
1084 \end{warn} |
1084 \end{warn} |
1085 *} |
1085 \<close> |
1086 |
1086 |
1087 text %mlex {* The following example demonstrates a multi-line |
1087 text %mlex \<open>The following example demonstrates a multi-line |
1088 warning. Note that in some situations the user sees only the first |
1088 warning. Note that in some situations the user sees only the first |
1089 line, so the most important point should be made first. |
1089 line, so the most important point should be made first. |
1090 *} |
1090 \<close> |
1091 |
1091 |
1092 ML_command {* |
1092 ML_command \<open> |
1093 warning (cat_lines |
1093 warning (cat_lines |
1094 ["Beware the Jabberwock, my son!", |
1094 ["Beware the Jabberwock, my son!", |
1095 "The jaws that bite, the claws that catch!", |
1095 "The jaws that bite, the claws that catch!", |
1096 "Beware the Jubjub Bird, and shun", |
1096 "Beware the Jubjub Bird, and shun", |
1097 "The frumious Bandersnatch!"]); |
1097 "The frumious Bandersnatch!"]); |
1098 *} |
1098 \<close> |
1099 |
1099 |
1100 |
1100 |
1101 section {* Exceptions \label{sec:exceptions} *} |
1101 section \<open>Exceptions \label{sec:exceptions}\<close> |
1102 |
1102 |
1103 text {* The Standard ML semantics of strict functional evaluation |
1103 text \<open>The Standard ML semantics of strict functional evaluation |
1104 together with exceptions is rather well defined, but some delicate |
1104 together with exceptions is rather well defined, but some delicate |
1105 points need to be observed to avoid that ML programs go wrong |
1105 points need to be observed to avoid that ML programs go wrong |
1106 despite static type-checking. Exceptions in Isabelle/ML are |
1106 despite static type-checking. Exceptions in Isabelle/ML are |
1107 subsequently categorized as follows. |
1107 subsequently categorized as follows. |
1108 |
1108 |
1235 @{ML_type "bool -> unit"} that raises @{ML Fail} if the argument is |
1235 @{ML_type "bool -> unit"} that raises @{ML Fail} if the argument is |
1236 @{ML false}. Due to inlining the source position of failed |
1236 @{ML false}. Due to inlining the source position of failed |
1237 assertions is included in the error output. |
1237 assertions is included in the error output. |
1238 |
1238 |
1239 \end{description} |
1239 \end{description} |
1240 *} |
1240 \<close> |
1241 |
1241 |
1242 |
1242 |
1243 section {* Strings of symbols \label{sec:symbols} *} |
1243 section \<open>Strings of symbols \label{sec:symbols}\<close> |
1244 |
1244 |
1245 text {* A \emph{symbol} constitutes the smallest textual unit in |
1245 text \<open>A \emph{symbol} constitutes the smallest textual unit in |
1246 Isabelle/ML --- raw ML characters are normally not encountered at |
1246 Isabelle/ML --- raw ML characters are normally not encountered at |
1247 all. Isabelle strings consist of a sequence of symbols, represented |
1247 all. Isabelle strings consist of a sequence of symbols, represented |
1248 as a packed string or an exploded list of strings. Each symbol is |
1248 as a packed string or an exploded list of strings. Each symbol is |
1249 in itself a small string, which has either one of the following |
1249 in itself a small string, which has either one of the following |
1250 forms: |
1250 forms: |
1292 the standard {\LaTeX} setup of the Isabelle document preparation system |
1292 the standard {\LaTeX} setup of the Isabelle document preparation system |
1293 would present ``\verb,\,\verb,<alpha>,'' as @{text "\<alpha>"}, and |
1293 would present ``\verb,\,\verb,<alpha>,'' as @{text "\<alpha>"}, and |
1294 ``\verb,\,\verb,<^bold>,\verb,\,\verb,<alpha>,'' as @{text "\<^bold>\<alpha>"}. On-screen |
1294 ``\verb,\,\verb,<^bold>,\verb,\,\verb,<alpha>,'' as @{text "\<^bold>\<alpha>"}. On-screen |
1295 rendering usually works by mapping a finite subset of Isabelle symbols to |
1295 rendering usually works by mapping a finite subset of Isabelle symbols to |
1296 suitable Unicode characters. |
1296 suitable Unicode characters. |
1297 *} |
1297 \<close> |
1298 |
1298 |
1299 text %mlref {* |
1299 text %mlref \<open> |
1300 \begin{mldecls} |
1300 \begin{mldecls} |
1301 @{index_ML_type "Symbol.symbol": string} \\ |
1301 @{index_ML_type "Symbol.symbol": string} \\ |
1302 @{index_ML Symbol.explode: "string -> Symbol.symbol list"} \\ |
1302 @{index_ML Symbol.explode: "string -> Symbol.symbol list"} \\ |
1303 @{index_ML Symbol.is_letter: "Symbol.symbol -> bool"} \\ |
1303 @{index_ML Symbol.is_letter: "Symbol.symbol -> bool"} \\ |
1304 @{index_ML Symbol.is_digit: "Symbol.symbol -> bool"} \\ |
1304 @{index_ML Symbol.is_digit: "Symbol.symbol -> bool"} \\ |
1346 somewhat anachronistic 8-bit or 16-bit characters, but the idea of |
1346 somewhat anachronistic 8-bit or 16-bit characters, but the idea of |
1347 exploding a string into a list of small strings was extended to |
1347 exploding a string into a list of small strings was extended to |
1348 ``symbols'' as explained above. Thus Isabelle sources can refer to |
1348 ``symbols'' as explained above. Thus Isabelle sources can refer to |
1349 an infinite store of user-defined symbols, without having to worry |
1349 an infinite store of user-defined symbols, without having to worry |
1350 about the multitude of Unicode encodings that have emerged over the |
1350 about the multitude of Unicode encodings that have emerged over the |
1351 years. *} |
1351 years.\<close> |
1352 |
1352 |
1353 |
1353 |
1354 section {* Basic data types *} |
1354 section \<open>Basic data types\<close> |
1355 |
1355 |
1356 text {* The basis library proposal of SML97 needs to be treated with |
1356 text \<open>The basis library proposal of SML97 needs to be treated with |
1357 caution. Many of its operations simply do not fit with important |
1357 caution. Many of its operations simply do not fit with important |
1358 Isabelle/ML conventions (like ``canonical argument order'', see |
1358 Isabelle/ML conventions (like ``canonical argument order'', see |
1359 \secref{sec:canonical-argument-order}), others cause problems with |
1359 \secref{sec:canonical-argument-order}), others cause problems with |
1360 the parallel evaluation model of Isabelle/ML (such as @{ML |
1360 the parallel evaluation model of Isabelle/ML (such as @{ML |
1361 TextIO.print} or @{ML OS.Process.system}). |
1361 TextIO.print} or @{ML OS.Process.system}). |
1362 |
1362 |
1363 Subsequently we give a brief overview of important operations on |
1363 Subsequently we give a brief overview of important operations on |
1364 basic ML data types. |
1364 basic ML data types. |
1365 *} |
1365 \<close> |
1366 |
1366 |
1367 |
1367 |
1368 subsection {* Characters *} |
1368 subsection \<open>Characters\<close> |
1369 |
1369 |
1370 text %mlref {* |
1370 text %mlref \<open> |
1371 \begin{mldecls} |
1371 \begin{mldecls} |
1372 @{index_ML_type char} \\ |
1372 @{index_ML_type char} \\ |
1373 \end{mldecls} |
1373 \end{mldecls} |
1374 |
1374 |
1375 \begin{description} |
1375 \begin{description} |
1413 like ``\verb,\,\verb,<alpha>,'' natively, \emph{without} escaping |
1413 like ``\verb,\,\verb,<alpha>,'' natively, \emph{without} escaping |
1414 the backslash. This is a consequence of Isabelle treating all |
1414 the backslash. This is a consequence of Isabelle treating all |
1415 source text as strings of symbols, instead of raw characters. |
1415 source text as strings of symbols, instead of raw characters. |
1416 |
1416 |
1417 \end{description} |
1417 \end{description} |
1418 *} |
1418 \<close> |
1419 |
1419 |
1420 text %mlex {* The subsequent example illustrates the difference of |
1420 text %mlex \<open>The subsequent example illustrates the difference of |
1421 physical addressing of bytes versus logical addressing of symbols in |
1421 physical addressing of bytes versus logical addressing of symbols in |
1422 Isabelle strings. |
1422 Isabelle strings. |
1423 *} |
1423 \<close> |
1424 |
1424 |
1425 ML_val {* |
1425 ML_val \<open> |
1426 val s = "\<A>"; |
1426 val s = "\<A>"; |
1427 |
1427 |
1428 @{assert} (length (Symbol.explode s) = 1); |
1428 @{assert} (length (Symbol.explode s) = 1); |
1429 @{assert} (size s = 4); |
1429 @{assert} (size s = 4); |
1430 *} |
1430 \<close> |
1431 |
1431 |
1432 text {* Note that in Unicode renderings of the symbol @{text "\<A>"}, |
1432 text \<open>Note that in Unicode renderings of the symbol @{text "\<A>"}, |
1433 variations of encodings like UTF-8 or UTF-16 pose delicate questions |
1433 variations of encodings like UTF-8 or UTF-16 pose delicate questions |
1434 about the multi-byte representations of its codepoint, which is outside |
1434 about the multi-byte representations of its codepoint, which is outside |
1435 of the 16-bit address space of the original Unicode standard from |
1435 of the 16-bit address space of the original Unicode standard from |
1436 the 1990-ies. In Isabelle/ML it is just ``\verb,\,\verb,<A>,'' |
1436 the 1990-ies. In Isabelle/ML it is just ``\verb,\,\verb,<A>,'' |
1437 literally, using plain ASCII characters beyond any doubts. *} |
1437 literally, using plain ASCII characters beyond any doubts.\<close> |
1438 |
1438 |
1439 |
1439 |
1440 subsection {* Integers *} |
1440 subsection \<open>Integers\<close> |
1441 |
1441 |
1442 text %mlref {* |
1442 text %mlref \<open> |
1443 \begin{mldecls} |
1443 \begin{mldecls} |
1444 @{index_ML_type int} \\ |
1444 @{index_ML_type int} \\ |
1445 \end{mldecls} |
1445 \end{mldecls} |
1446 |
1446 |
1447 \begin{description} |
1447 \begin{description} |
1483 point numbers are easy to use as configuration options in the |
1483 point numbers are easy to use as configuration options in the |
1484 context (see \secref{sec:config-options}) or system options that |
1484 context (see \secref{sec:config-options}) or system options that |
1485 are maintained externally. |
1485 are maintained externally. |
1486 |
1486 |
1487 \end{description} |
1487 \end{description} |
1488 *} |
1488 \<close> |
1489 |
1489 |
1490 |
1490 |
1491 subsection {* Options *} |
1491 subsection \<open>Options\<close> |
1492 |
1492 |
1493 text %mlref {* |
1493 text %mlref \<open> |
1494 \begin{mldecls} |
1494 \begin{mldecls} |
1495 @{index_ML Option.map: "('a -> 'b) -> 'a option -> 'b option"} \\ |
1495 @{index_ML Option.map: "('a -> 'b) -> 'a option -> 'b option"} \\ |
1496 @{index_ML is_some: "'a option -> bool"} \\ |
1496 @{index_ML is_some: "'a option -> bool"} \\ |
1497 @{index_ML is_none: "'a option -> bool"} \\ |
1497 @{index_ML is_none: "'a option -> bool"} \\ |
1498 @{index_ML the: "'a option -> 'a"} \\ |
1498 @{index_ML the: "'a option -> 'a"} \\ |
1499 @{index_ML these: "'a list option -> 'a list"} \\ |
1499 @{index_ML these: "'a list option -> 'a list"} \\ |
1500 @{index_ML the_list: "'a option -> 'a list"} \\ |
1500 @{index_ML the_list: "'a option -> 'a list"} \\ |
1501 @{index_ML the_default: "'a -> 'a option -> 'a"} \\ |
1501 @{index_ML the_default: "'a -> 'a option -> 'a"} \\ |
1502 \end{mldecls} |
1502 \end{mldecls} |
1503 *} |
1503 \<close> |
1504 |
1504 |
1505 text {* Apart from @{ML Option.map} most other operations defined in |
1505 text \<open>Apart from @{ML Option.map} most other operations defined in |
1506 structure @{ML_structure Option} are alien to Isabelle/ML and never |
1506 structure @{ML_structure Option} are alien to Isabelle/ML and never |
1507 used. The operations shown above are defined in @{file |
1507 used. The operations shown above are defined in @{file |
1508 "~~/src/Pure/General/basics.ML"}. *} |
1508 "~~/src/Pure/General/basics.ML"}.\<close> |
1509 |
1509 |
1510 |
1510 |
1511 subsection {* Lists *} |
1511 subsection \<open>Lists\<close> |
1512 |
1512 |
1513 text {* Lists are ubiquitous in ML as simple and light-weight |
1513 text \<open>Lists are ubiquitous in ML as simple and light-weight |
1514 ``collections'' for many everyday programming tasks. Isabelle/ML |
1514 ``collections'' for many everyday programming tasks. Isabelle/ML |
1515 provides important additions and improvements over operations that |
1515 provides important additions and improvements over operations that |
1516 are predefined in the SML97 library. *} |
1516 are predefined in the SML97 library.\<close> |
1517 |
1517 |
1518 text %mlref {* |
1518 text %mlref \<open> |
1519 \begin{mldecls} |
1519 \begin{mldecls} |
1520 @{index_ML cons: "'a -> 'a list -> 'a list"} \\ |
1520 @{index_ML cons: "'a -> 'a list -> 'a list"} \\ |
1521 @{index_ML member: "('b * 'a -> bool) -> 'a list -> 'b -> bool"} \\ |
1521 @{index_ML member: "('b * 'a -> bool) -> 'a list -> 'b -> bool"} \\ |
1522 @{index_ML insert: "('a * 'a -> bool) -> 'a -> 'a list -> 'a list"} \\ |
1522 @{index_ML insert: "('a * 'a -> bool) -> 'a -> 'a list -> 'a list"} \\ |
1523 @{index_ML remove: "('b * 'a -> bool) -> 'b -> 'a list -> 'a list"} \\ |
1523 @{index_ML remove: "('b * 'a -> bool) -> 'b -> 'a list -> 'a list"} \\ |
1544 often more appropriate in declarations of context data |
1544 often more appropriate in declarations of context data |
1545 (\secref{sec:context-data}) that are issued by the user in Isar |
1545 (\secref{sec:context-data}) that are issued by the user in Isar |
1546 source: later declarations take precedence over earlier ones. |
1546 source: later declarations take precedence over earlier ones. |
1547 |
1547 |
1548 \end{description} |
1548 \end{description} |
1549 *} |
1549 \<close> |
1550 |
1550 |
1551 text %mlex {* Using canonical @{ML fold} together with @{ML cons} (or |
1551 text %mlex \<open>Using canonical @{ML fold} together with @{ML cons} (or |
1552 similar standard operations) alternates the orientation of data. |
1552 similar standard operations) alternates the orientation of data. |
1553 The is quite natural and should not be altered forcible by inserting |
1553 The is quite natural and should not be altered forcible by inserting |
1554 extra applications of @{ML rev}. The alternative @{ML fold_rev} can |
1554 extra applications of @{ML rev}. The alternative @{ML fold_rev} can |
1555 be used in the few situations, where alternation should be |
1555 be used in the few situations, where alternation should be |
1556 prevented. |
1556 prevented. |
1557 *} |
1557 \<close> |
1558 |
1558 |
1559 ML {* |
1559 ML \<open> |
1560 val items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; |
1560 val items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; |
1561 |
1561 |
1562 val list1 = fold cons items []; |
1562 val list1 = fold cons items []; |
1563 @{assert} (list1 = rev items); |
1563 @{assert} (list1 = rev items); |
1564 |
1564 |
1565 val list2 = fold_rev cons items []; |
1565 val list2 = fold_rev cons items []; |
1566 @{assert} (list2 = items); |
1566 @{assert} (list2 = items); |
1567 *} |
1567 \<close> |
1568 |
1568 |
1569 text {* The subsequent example demonstrates how to \emph{merge} two |
1569 text \<open>The subsequent example demonstrates how to \emph{merge} two |
1570 lists in a natural way. *} |
1570 lists in a natural way.\<close> |
1571 |
1571 |
1572 ML {* |
1572 ML \<open> |
1573 fun merge_lists eq (xs, ys) = fold_rev (insert eq) ys xs; |
1573 fun merge_lists eq (xs, ys) = fold_rev (insert eq) ys xs; |
1574 *} |
1574 \<close> |
1575 |
1575 |
1576 text {* Here the first list is treated conservatively: only the new |
1576 text \<open>Here the first list is treated conservatively: only the new |
1577 elements from the second list are inserted. The inside-out order of |
1577 elements from the second list are inserted. The inside-out order of |
1578 insertion via @{ML fold_rev} attempts to preserve the order of |
1578 insertion via @{ML fold_rev} attempts to preserve the order of |
1579 elements in the result. |
1579 elements in the result. |
1580 |
1580 |
1581 This way of merging lists is typical for context data |
1581 This way of merging lists is typical for context data |
1582 (\secref{sec:context-data}). See also @{ML merge} as defined in |
1582 (\secref{sec:context-data}). See also @{ML merge} as defined in |
1583 @{file "~~/src/Pure/library.ML"}. |
1583 @{file "~~/src/Pure/library.ML"}. |
1584 *} |
1584 \<close> |
1585 |
1585 |
1586 |
1586 |
1587 subsection {* Association lists *} |
1587 subsection \<open>Association lists\<close> |
1588 |
1588 |
1589 text {* The operations for association lists interpret a concrete list |
1589 text \<open>The operations for association lists interpret a concrete list |
1590 of pairs as a finite function from keys to values. Redundant |
1590 of pairs as a finite function from keys to values. Redundant |
1591 representations with multiple occurrences of the same key are |
1591 representations with multiple occurrences of the same key are |
1592 implicitly normalized: lookup and update only take the first |
1592 implicitly normalized: lookup and update only take the first |
1593 occurrence into account. |
1593 occurrence into account. |
1594 *} |
1594 \<close> |
1595 |
1595 |
1596 text {* |
1596 text \<open> |
1597 \begin{mldecls} |
1597 \begin{mldecls} |
1598 @{index_ML AList.lookup: "('a * 'b -> bool) -> ('b * 'c) list -> 'a -> 'c option"} \\ |
1598 @{index_ML AList.lookup: "('a * 'b -> bool) -> ('b * 'c) list -> 'a -> 'c option"} \\ |
1599 @{index_ML AList.defined: "('a * 'b -> bool) -> ('b * 'c) list -> 'a -> bool"} \\ |
1599 @{index_ML AList.defined: "('a * 'b -> bool) -> ('b * 'c) list -> 'a -> bool"} \\ |
1600 @{index_ML AList.update: "('a * 'a -> bool) -> 'a * 'b -> ('a * 'b) list -> ('a * 'b) list"} \\ |
1600 @{index_ML AList.update: "('a * 'a -> bool) -> 'a * 'b -> ('a * 'b) list -> ('a * 'b) list"} \\ |
1601 \end{mldecls} |
1601 \end{mldecls} |
1621 |
1621 |
1622 Association lists are adequate as simple implementation of finite mappings |
1622 Association lists are adequate as simple implementation of finite mappings |
1623 in many practical situations. A more advanced table structure is defined in |
1623 in many practical situations. A more advanced table structure is defined in |
1624 @{file "~~/src/Pure/General/table.ML"}; that version scales easily to |
1624 @{file "~~/src/Pure/General/table.ML"}; that version scales easily to |
1625 thousands or millions of elements. |
1625 thousands or millions of elements. |
1626 *} |
1626 \<close> |
1627 |
1627 |
1628 |
1628 |
1629 subsection {* Unsynchronized references *} |
1629 subsection \<open>Unsynchronized references\<close> |
1630 |
1630 |
1631 text %mlref {* |
1631 text %mlref \<open> |
1632 \begin{mldecls} |
1632 \begin{mldecls} |
1633 @{index_ML_type "'a Unsynchronized.ref"} \\ |
1633 @{index_ML_type "'a Unsynchronized.ref"} \\ |
1634 @{index_ML Unsynchronized.ref: "'a -> 'a Unsynchronized.ref"} \\ |
1634 @{index_ML Unsynchronized.ref: "'a -> 'a Unsynchronized.ref"} \\ |
1635 @{index_ML "!": "'a Unsynchronized.ref -> 'a"} \\ |
1635 @{index_ML "!": "'a Unsynchronized.ref -> 'a"} \\ |
1636 @{index_ML_op ":=": "'a Unsynchronized.ref * 'a -> unit"} \\ |
1636 @{index_ML_op ":=": "'a Unsynchronized.ref * 'a -> unit"} \\ |
1637 \end{mldecls} |
1637 \end{mldecls} |
1638 *} |
1638 \<close> |
1639 |
1639 |
1640 text {* Due to ubiquitous parallelism in Isabelle/ML (see also |
1640 text \<open>Due to ubiquitous parallelism in Isabelle/ML (see also |
1641 \secref{sec:multi-threading}), the mutable reference cells of |
1641 \secref{sec:multi-threading}), the mutable reference cells of |
1642 Standard ML are notorious for causing problems. In a highly |
1642 Standard ML are notorious for causing problems. In a highly |
1643 parallel system, both correctness \emph{and} performance are easily |
1643 parallel system, both correctness \emph{and} performance are easily |
1644 degraded when using mutable data. |
1644 degraded when using mutable data. |
1645 |
1645 |
1652 |
1652 |
1653 \begin{warn} |
1653 \begin{warn} |
1654 Never @{ML_text "open Unsynchronized"}, not even in a local scope! |
1654 Never @{ML_text "open Unsynchronized"}, not even in a local scope! |
1655 Pretending that mutable state is no problem is a very bad idea. |
1655 Pretending that mutable state is no problem is a very bad idea. |
1656 \end{warn} |
1656 \end{warn} |
1657 *} |
1657 \<close> |
1658 |
1658 |
1659 |
1659 |
1660 section {* Thread-safe programming \label{sec:multi-threading} *} |
1660 section \<open>Thread-safe programming \label{sec:multi-threading}\<close> |
1661 |
1661 |
1662 text {* Multi-threaded execution has become an everyday reality in |
1662 text \<open>Multi-threaded execution has become an everyday reality in |
1663 Isabelle since Poly/ML 5.2.1 and Isabelle2008. Isabelle/ML provides |
1663 Isabelle since Poly/ML 5.2.1 and Isabelle2008. Isabelle/ML provides |
1664 implicit and explicit parallelism by default, and there is no way |
1664 implicit and explicit parallelism by default, and there is no way |
1665 for user-space tools to ``opt out''. ML programs that are purely |
1665 for user-space tools to ``opt out''. ML programs that are purely |
1666 functional, output messages only via the official channels |
1666 functional, output messages only via the official channels |
1667 (\secref{sec:message-channels}), and do not intercept interrupts |
1667 (\secref{sec:message-channels}), and do not intercept interrupts |
1668 (\secref{sec:exceptions}) can participate in the multi-threaded |
1668 (\secref{sec:exceptions}) can participate in the multi-threaded |
1669 environment immediately without further ado. |
1669 environment immediately without further ado. |
1670 |
1670 |
1671 More ambitious tools with more fine-grained interaction with the |
1671 More ambitious tools with more fine-grained interaction with the |
1672 environment need to observe the principles explained below. |
1672 environment need to observe the principles explained below. |
1673 *} |
1673 \<close> |
1674 |
1674 |
1675 |
1675 |
1676 subsection {* Multi-threading with shared memory *} |
1676 subsection \<open>Multi-threading with shared memory\<close> |
1677 |
1677 |
1678 text {* Multiple threads help to organize advanced operations of the |
1678 text \<open>Multiple threads help to organize advanced operations of the |
1679 system, such as real-time conditions on command transactions, |
1679 system, such as real-time conditions on command transactions, |
1680 sub-components with explicit communication, general asynchronous |
1680 sub-components with explicit communication, general asynchronous |
1681 interaction etc. Moreover, parallel evaluation is a prerequisite to |
1681 interaction etc. Moreover, parallel evaluation is a prerequisite to |
1682 make adequate use of the CPU resources that are available on |
1682 make adequate use of the CPU resources that are available on |
1683 multi-core systems.\footnote{Multi-core computing does not mean that |
1683 multi-core systems.\footnote{Multi-core computing does not mean that |
1723 \begin{warn} |
1723 \begin{warn} |
1724 Parallel computing resources are managed centrally by the |
1724 Parallel computing resources are managed centrally by the |
1725 Isabelle/ML infrastructure. User programs must not fork their own |
1725 Isabelle/ML infrastructure. User programs must not fork their own |
1726 ML threads to perform heavy computations. |
1726 ML threads to perform heavy computations. |
1727 \end{warn} |
1727 \end{warn} |
1728 *} |
1728 \<close> |
1729 |
1729 |
1730 |
1730 |
1731 subsection {* Critical shared resources *} |
1731 subsection \<open>Critical shared resources\<close> |
1732 |
1732 |
1733 text {* Thread-safeness is mainly concerned about concurrent |
1733 text \<open>Thread-safeness is mainly concerned about concurrent |
1734 read/write access to shared resources, which are outside the purely |
1734 read/write access to shared resources, which are outside the purely |
1735 functional world of ML. This covers the following in particular. |
1735 functional world of ML. This covers the following in particular. |
1736 |
1736 |
1737 \begin{itemize} |
1737 \begin{itemize} |
1738 |
1738 |
1814 |
1814 |
1815 \item @{ML serial_string}~@{text "()"} creates a new serial number |
1815 \item @{ML serial_string}~@{text "()"} creates a new serial number |
1816 that is unique over the runtime of the Isabelle/ML process. |
1816 that is unique over the runtime of the Isabelle/ML process. |
1817 |
1817 |
1818 \end{description} |
1818 \end{description} |
1819 *} |
1819 \<close> |
1820 |
1820 |
1821 text %mlex {* The following example shows how to create unique |
1821 text %mlex \<open>The following example shows how to create unique |
1822 temporary file names. |
1822 temporary file names. |
1823 *} |
1823 \<close> |
1824 |
1824 |
1825 ML {* |
1825 ML \<open> |
1826 val tmp1 = File.tmp_path (Path.basic ("foo" ^ serial_string ())); |
1826 val tmp1 = File.tmp_path (Path.basic ("foo" ^ serial_string ())); |
1827 val tmp2 = File.tmp_path (Path.basic ("foo" ^ serial_string ())); |
1827 val tmp2 = File.tmp_path (Path.basic ("foo" ^ serial_string ())); |
1828 @{assert} (tmp1 <> tmp2); |
1828 @{assert} (tmp1 <> tmp2); |
1829 *} |
1829 \<close> |
1830 |
1830 |
1831 |
1831 |
1832 subsection {* Explicit synchronization *} |
1832 subsection \<open>Explicit synchronization\<close> |
1833 |
1833 |
1834 text {* Isabelle/ML also provides some explicit synchronization |
1834 text \<open>Isabelle/ML also provides some explicit synchronization |
1835 mechanisms, for the rare situations where mutable shared resources |
1835 mechanisms, for the rare situations where mutable shared resources |
1836 are really required. These are based on the synchronizations |
1836 are really required. These are based on the synchronizations |
1837 primitives of Poly/ML, which have been adapted to the specific |
1837 primitives of Poly/ML, which have been adapted to the specific |
1838 assumptions of the concurrent Isabelle/ML environment. User code |
1838 assumptions of the concurrent Isabelle/ML environment. User code |
1839 must not use the Poly/ML primitives directly! |
1839 must not use the Poly/ML primitives directly! |
1905 \end{description} |
1905 \end{description} |
1906 |
1906 |
1907 There are some further variants of the @{ML |
1907 There are some further variants of the @{ML |
1908 Synchronized.guarded_access} combinator, see @{file |
1908 Synchronized.guarded_access} combinator, see @{file |
1909 "~~/src/Pure/Concurrent/synchronized.ML"} for details. |
1909 "~~/src/Pure/Concurrent/synchronized.ML"} for details. |
1910 *} |
1910 \<close> |
1911 |
1911 |
1912 text %mlex {* The following example implements a counter that produces |
1912 text %mlex \<open>The following example implements a counter that produces |
1913 positive integers that are unique over the runtime of the Isabelle |
1913 positive integers that are unique over the runtime of the Isabelle |
1914 process: |
1914 process: |
1915 *} |
1915 \<close> |
1916 |
1916 |
1917 ML {* |
1917 ML \<open> |
1918 local |
1918 local |
1919 val counter = Synchronized.var "counter" 0; |
1919 val counter = Synchronized.var "counter" 0; |
1920 in |
1920 in |
1921 fun next () = |
1921 fun next () = |
1922 Synchronized.guarded_access counter |
1922 Synchronized.guarded_access counter |
1923 (fn i => |
1923 (fn i => |
1924 let val j = i + 1 |
1924 let val j = i + 1 |
1925 in SOME (j, j) end); |
1925 in SOME (j, j) end); |
1926 end; |
1926 end; |
1927 *} |
1927 \<close> |
1928 |
1928 |
1929 ML {* |
1929 ML \<open> |
1930 val a = next (); |
1930 val a = next (); |
1931 val b = next (); |
1931 val b = next (); |
1932 @{assert} (a <> b); |
1932 @{assert} (a <> b); |
1933 *} |
1933 \<close> |
1934 |
1934 |
1935 text {* \medskip See @{file "~~/src/Pure/Concurrent/mailbox.ML"} how |
1935 text \<open>\medskip See @{file "~~/src/Pure/Concurrent/mailbox.ML"} how |
1936 to implement a mailbox as synchronized variable over a purely |
1936 to implement a mailbox as synchronized variable over a purely |
1937 functional list. *} |
1937 functional list.\<close> |
1938 |
1938 |
1939 |
1939 |
1940 section {* Managed evaluation *} |
1940 section \<open>Managed evaluation\<close> |
1941 |
1941 |
1942 text {* Execution of Standard ML follows the model of strict |
1942 text \<open>Execution of Standard ML follows the model of strict |
1943 functional evaluation with optional exceptions. Evaluation happens |
1943 functional evaluation with optional exceptions. Evaluation happens |
1944 whenever some function is applied to (sufficiently many) |
1944 whenever some function is applied to (sufficiently many) |
1945 arguments. The result is either an explicit value or an implicit |
1945 arguments. The result is either an explicit value or an implicit |
1946 exception. |
1946 exception. |
1947 |
1947 |
1981 evaluations that depend on other evaluations: exceptions stemming |
1981 evaluations that depend on other evaluations: exceptions stemming |
1982 from shared sub-graphs are exposed exactly once and in the order of |
1982 from shared sub-graphs are exposed exactly once and in the order of |
1983 their original occurrence (e.g.\ when printed at the toplevel). |
1983 their original occurrence (e.g.\ when printed at the toplevel). |
1984 Interrupt counts as neutral element here: it is treated as minimal |
1984 Interrupt counts as neutral element here: it is treated as minimal |
1985 information about some canceled evaluation process, and is absorbed |
1985 information about some canceled evaluation process, and is absorbed |
1986 by the presence of regular program exceptions. *} |
1986 by the presence of regular program exceptions.\<close> |
1987 |
1987 |
1988 text %mlref {* |
1988 text %mlref \<open> |
1989 \begin{mldecls} |
1989 \begin{mldecls} |
1990 @{index_ML_type "'a Exn.result"} \\ |
1990 @{index_ML_type "'a Exn.result"} \\ |
1991 @{index_ML Exn.capture: "('a -> 'b) -> 'a -> 'b Exn.result"} \\ |
1991 @{index_ML Exn.capture: "('a -> 'b) -> 'a -> 'b Exn.result"} \\ |
1992 @{index_ML Exn.interruptible_capture: "('a -> 'b) -> 'a -> 'b Exn.result"} \\ |
1992 @{index_ML Exn.interruptible_capture: "('a -> 'b) -> 'a -> 'b Exn.result"} \\ |
1993 @{index_ML Exn.release: "'a Exn.result -> 'a"} \\ |
1993 @{index_ML Exn.release: "'a Exn.result -> 'a"} \\ |
2027 in the original evaluation process is raised again, the others are |
2027 in the original evaluation process is raised again, the others are |
2028 ignored. That single exception may get handled by conventional |
2028 ignored. That single exception may get handled by conventional |
2029 means in ML. |
2029 means in ML. |
2030 |
2030 |
2031 \end{description} |
2031 \end{description} |
2032 *} |
2032 \<close> |
2033 |
2033 |
2034 |
2034 |
2035 subsection {* Parallel skeletons \label{sec:parlist} *} |
2035 subsection \<open>Parallel skeletons \label{sec:parlist}\<close> |
2036 |
2036 |
2037 text {* |
2037 text \<open> |
2038 Algorithmic skeletons are combinators that operate on lists in |
2038 Algorithmic skeletons are combinators that operate on lists in |
2039 parallel, in the manner of well-known @{text map}, @{text exists}, |
2039 parallel, in the manner of well-known @{text map}, @{text exists}, |
2040 @{text forall} etc. Management of futures (\secref{sec:futures}) |
2040 @{text forall} etc. Management of futures (\secref{sec:futures}) |
2041 and their results as reified exceptions is wrapped up into simple |
2041 and their results as reified exceptions is wrapped up into simple |
2042 programming interfaces that resemble the sequential versions. |
2042 programming interfaces that resemble the sequential versions. |
2046 corresponds to one evaluation task. If the granularity is too |
2046 corresponds to one evaluation task. If the granularity is too |
2047 coarse, the available CPUs are not saturated. If it is too |
2047 coarse, the available CPUs are not saturated. If it is too |
2048 fine-grained, CPU cycles are wasted due to the overhead of |
2048 fine-grained, CPU cycles are wasted due to the overhead of |
2049 organizing parallel processing. In the worst case, parallel |
2049 organizing parallel processing. In the worst case, parallel |
2050 performance will be less than the sequential counterpart! |
2050 performance will be less than the sequential counterpart! |
2051 *} |
2051 \<close> |
2052 |
2052 |
2053 text %mlref {* |
2053 text %mlref \<open> |
2054 \begin{mldecls} |
2054 \begin{mldecls} |
2055 @{index_ML Par_List.map: "('a -> 'b) -> 'a list -> 'b list"} \\ |
2055 @{index_ML Par_List.map: "('a -> 'b) -> 'a list -> 'b list"} \\ |
2056 @{index_ML Par_List.get_some: "('a -> 'b option) -> 'a list -> 'b option"} \\ |
2056 @{index_ML Par_List.get_some: "('a -> 'b option) -> 'a list -> 'b option"} \\ |
2057 \end{mldecls} |
2057 \end{mldecls} |
2058 |
2058 |
2079 This generic parallel choice combinator is the basis for derived |
2079 This generic parallel choice combinator is the basis for derived |
2080 forms, such as @{ML Par_List.find_some}, @{ML Par_List.exists}, @{ML |
2080 forms, such as @{ML Par_List.find_some}, @{ML Par_List.exists}, @{ML |
2081 Par_List.forall}. |
2081 Par_List.forall}. |
2082 |
2082 |
2083 \end{description} |
2083 \end{description} |
2084 *} |
2084 \<close> |
2085 |
2085 |
2086 text %mlex {* Subsequently, the Ackermann function is evaluated in |
2086 text %mlex \<open>Subsequently, the Ackermann function is evaluated in |
2087 parallel for some ranges of arguments. *} |
2087 parallel for some ranges of arguments.\<close> |
2088 |
2088 |
2089 ML_val {* |
2089 ML_val \<open> |
2090 fun ackermann 0 n = n + 1 |
2090 fun ackermann 0 n = n + 1 |
2091 | ackermann m 0 = ackermann (m - 1) 1 |
2091 | ackermann m 0 = ackermann (m - 1) 1 |
2092 | ackermann m n = ackermann (m - 1) (ackermann m (n - 1)); |
2092 | ackermann m n = ackermann (m - 1) (ackermann m (n - 1)); |
2093 |
2093 |
2094 Par_List.map (ackermann 2) (500 upto 1000); |
2094 Par_List.map (ackermann 2) (500 upto 1000); |
2095 Par_List.map (ackermann 3) (5 upto 10); |
2095 Par_List.map (ackermann 3) (5 upto 10); |
2096 *} |
2096 \<close> |
2097 |
2097 |
2098 |
2098 |
2099 subsection {* Lazy evaluation *} |
2099 subsection \<open>Lazy evaluation\<close> |
2100 |
2100 |
2101 text {* |
2101 text \<open> |
2102 Classic lazy evaluation works via the @{text lazy}~/ @{text force} pair of |
2102 Classic lazy evaluation works via the @{text lazy}~/ @{text force} pair of |
2103 operations: @{text lazy} to wrap an unevaluated expression, and @{text |
2103 operations: @{text lazy} to wrap an unevaluated expression, and @{text |
2104 force} to evaluate it once and store its result persistently. Later |
2104 force} to evaluate it once and store its result persistently. Later |
2105 invocations of @{text force} retrieve the stored result without another |
2105 invocations of @{text force} retrieve the stored result without another |
2106 evaluation. Isabelle/ML refines this idea to accommodate the aspects of |
2106 evaluation. Isabelle/ML refines this idea to accommodate the aspects of |
2117 This means a lazy value is completely evaluated at most once, in a |
2117 This means a lazy value is completely evaluated at most once, in a |
2118 thread-safe manner. There might be multiple interrupted evaluation attempts, |
2118 thread-safe manner. There might be multiple interrupted evaluation attempts, |
2119 and multiple receivers of intermediate interrupt events. Interrupts are |
2119 and multiple receivers of intermediate interrupt events. Interrupts are |
2120 \emph{not} made persistent: later evaluation attempts start again from the |
2120 \emph{not} made persistent: later evaluation attempts start again from the |
2121 original expression. |
2121 original expression. |
2122 *} |
2122 \<close> |
2123 |
2123 |
2124 text %mlref {* |
2124 text %mlref \<open> |
2125 \begin{mldecls} |
2125 \begin{mldecls} |
2126 @{index_ML_type "'a lazy"} \\ |
2126 @{index_ML_type "'a lazy"} \\ |
2127 @{index_ML Lazy.lazy: "(unit -> 'a) -> 'a lazy"} \\ |
2127 @{index_ML Lazy.lazy: "(unit -> 'a) -> 'a lazy"} \\ |
2128 @{index_ML Lazy.value: "'a -> 'a lazy"} \\ |
2128 @{index_ML Lazy.value: "'a -> 'a lazy"} \\ |
2129 @{index_ML Lazy.force: "'a lazy -> 'a"} \\ |
2129 @{index_ML Lazy.force: "'a lazy -> 'a"} \\ |
2146 \item @{ML Lazy.force}~@{text x} produces the result of the lazy value in a |
2146 \item @{ML Lazy.force}~@{text x} produces the result of the lazy value in a |
2147 thread-safe manner as explained above. Thus it may cause the current thread |
2147 thread-safe manner as explained above. Thus it may cause the current thread |
2148 to wait on a pending evaluation attempt by another thread. |
2148 to wait on a pending evaluation attempt by another thread. |
2149 |
2149 |
2150 \end{description} |
2150 \end{description} |
2151 *} |
2151 \<close> |
2152 |
2152 |
2153 |
2153 |
2154 subsection {* Futures \label{sec:futures} *} |
2154 subsection \<open>Futures \label{sec:futures}\<close> |
2155 |
2155 |
2156 text {* |
2156 text \<open> |
2157 Futures help to organize parallel execution in a value-oriented manner, with |
2157 Futures help to organize parallel execution in a value-oriented manner, with |
2158 @{text fork}~/ @{text join} as the main pair of operations, and some further |
2158 @{text fork}~/ @{text join} as the main pair of operations, and some further |
2159 variants; see also @{cite "Wenzel:2009" and "Wenzel:2013:ITP"}. Unlike lazy |
2159 variants; see also @{cite "Wenzel:2009" and "Wenzel:2013:ITP"}. Unlike lazy |
2160 values, futures are evaluated strictly and spontaneously on separate worker |
2160 values, futures are evaluated strictly and spontaneously on separate worker |
2161 threads. Futures may be canceled, which leads to interrupts on running |
2161 threads. Futures may be canceled, which leads to interrupts on running |
2201 Promises are managed in the same task queue, so regular futures may depend |
2201 Promises are managed in the same task queue, so regular futures may depend |
2202 on them. This allows a form of reactive programming, where some promises are |
2202 on them. This allows a form of reactive programming, where some promises are |
2203 used as minimal elements (or guards) within the future dependency graph: |
2203 used as minimal elements (or guards) within the future dependency graph: |
2204 when these promises are fulfilled the evaluation of subsequent futures |
2204 when these promises are fulfilled the evaluation of subsequent futures |
2205 starts spontaneously, according to their own inter-dependencies. |
2205 starts spontaneously, according to their own inter-dependencies. |
2206 *} |
2206 \<close> |
2207 |
2207 |
2208 text %mlref {* |
2208 text %mlref \<open> |
2209 \begin{mldecls} |
2209 \begin{mldecls} |
2210 @{index_ML_type "'a future"} \\ |
2210 @{index_ML_type "'a future"} \\ |
2211 @{index_ML Future.fork: "(unit -> 'a) -> 'a future"} \\ |
2211 @{index_ML Future.fork: "(unit -> 'a) -> 'a future"} \\ |
2212 @{index_ML Future.forks: "Future.params -> (unit -> 'a) list -> 'a future list"} \\ |
2212 @{index_ML Future.forks: "Future.params -> (unit -> 'a) list -> 'a future list"} \\ |
2213 @{index_ML Future.join: "'a future -> 'a"} \\ |
2213 @{index_ML Future.join: "'a future -> 'a"} \\ |