Abstract
When a new programming language appears, the syntax and intended behaviour of its programs need to be specified. The behaviour of each language construct can be concisely specified by translating it to fundamental constructs (funcons), compositionally. In contrast to the informal explanations commonly found in reference manuals, such formal specifications of translations to funcons can be precise and complete. They are also easy to write and read, and to update when the language evolves.
The PLanCompS project has developed a large collection of funcons. Each funcon is defined independently, using a modular variant of structural operational semantics. The definitions are available online, along with tools for generating funcon interpreters from them.
This paper introduces and motivates funcons. It illustrates translation of language constructs to funcons, and funcon definition. It also relates funcons to the notation used in some previous language specification frameworks, including monadic semantics and action semantics.
Access this chapter
Tax calculation will be finalised at checkout
Purchases are for personal use only
Similar content being viewed by others
Notes
- 1.
- 2.
At the time of writing, the collection has not yet been released, and could change.
- 3.
Nowadays, a Unix command often has a multitude of obscure options, documented in a manual ‘page’ that fills many screens.
- 4.
Singular forms of type names are used as value constructors.
- 5.
Currently, Funcons-beta does not support namespaces in collections of funcons.
- 6.
Funcons have not yet been developed for ‘relaxed’ memory models or data marshalling.
- 7.
‘L’ and ‘R’ refer to the left and right sides of typical assignment commands [32].
- 8.
Funcons for using un-typed locations as variables would be slightly simpler.
- 9.
- 10.
- 11.
- 12.
See [20] for discussion of earlier uses of similar operations in denotational semantics.
References
Appel, A.W., Palsberg, J.: Modern Compiler Implementation in Java, 2nd edn. Cambridge University Press, Cambridge (2002)
Batory, D.S., Höfner, P., Kim, J.: Feature interactions, products, and composition. In: Denney, E., Schultz, U.P. (eds.) GPCE 2011, pp. 13–22. ACM (2011). https://doi.org/10.1145/2047862.2047867
van Binsbergen, L.T.: Funcons for HGMP: the fundamental constructs of homogeneous generative meta-programming (short paper). In: Wyk, E.V., Rompf, T. (eds.) GPCE 2018, pp. 168–174. ACM (2018). https://doi.org/10.1145/3278122.3278132
van Binsbergen, L.T., Mosses, P.D., Sculthorpe, N.: Executable component-based semantics. J. Log. Algebr. Meth. Program. 103, 184–212 (2019). https://doi.org/10.1016/j.jlamp.2018.12.004
van Binsbergen, L.T., Sculthorpe, N.: Funcons-tools: a modular interpreter for executing funcons. https://hackage.haskell.org/package/funcons-tools. Software package. Accessed 08 Aug 2021
van den Brand, M., Iversen, J., Mosses, P.D.: An action environment. Sci. Comput. Program. 61(3), 245–264 (2006). https://doi.org/10.1016/j.scico.2006.04.005
Churchill, M., Mosses, P.D.: Modular bisimulation theory for computations and values. In: Pfenning, F. (ed.) FoSSaCS 2013. LNCS, vol. 7794, pp. 97–112. Springer, Heidelberg (2013). https://doi.org/10.1007/978-3-642-37075-5_7
Churchill, M., Mosses, P.D., Sculthorpe, N., Torrini, P.: Reusable components of semantic specifications. In: Chiba, S., Tanter, É., Ernst, E., Hirschfeld, R. (eds.) Transactions on Aspect-Oriented Software Development XII. LNCS, vol. 8989, pp. 132–179. Springer, Heidelberg (2015). https://doi.org/10.1007/978-3-662-46734-3_4
van Deursen, A., Mosses, P.D.: ASD: the action semantic description tools. In: Wirsing, M., Nivat, M. (eds.) AMAST 1996. LNCS, vol. 1101, pp. 579–582. Springer, Heidelberg (1996). https://doi.org/10.1007/BFb0014346
GraalVM: Introduction to SimpleLanguage. https://www.graalvm.org/graalvm-as-a-platform/implement-language. Accessed 08 Aug 2021
Jones, C.B.: The transition from VDL to VDM. J. Univers. Comput. Sci. 7(8), 631–640 (2001). https://doi.org/10.3217/jucs-007-08-0631
Kats, L.C.L., Visser, E.: The Spoofax language workbench: Rules for declarative specification of languages and IDEs. In: Cook, W.R., Clarke, S., Rinard, M.C. (eds.) OOPSLA 2010, pp. 444–463. ACM (2010). https://doi.org/10.1145/1869459.1869497
Klein, C., et al.: Run your research: on the effectiveness of lightweight mechanization. In: Field, J., Hicks, M. (eds.) POPL 2012, pp. 285–296. ACM (2012). https://doi.org/10.1145/2103656.2103691
Madlener, K., Smetsers, S., van Eekelen, M.C.J.D.: Formal component-based semantics. In: Reniers, M.A., Sobocinski, P. (eds.) SOS 2011. EPTCS, vol. 62, pp. 17–29 (2011). https://doi.org/10.4204/EPTCS.62.2
Moggi, E.: An abstract view of programming languages. Technical report, ECS-LFCS-90-113, Edinburgh Univ. (1989)
Mosses, P.D.: The mathematical semantics of Algol 60. Technical Monograph, PRG-12, Oxford Univ. Comp. Lab. (1974)
Mosses, P.D.: Action Semantics, Cambridge Tracts in TCS, vol. 26. Cambridge University Press, Cambridge (1992). https://doi.org/10.1017/CBO9780511569869
Mosses, P.D.: Theory and practice of action semantics. In: Penczek, W., Szałas, A. (eds.) MFCS 1996. LNCS, vol. 1113, pp. 37–61. Springer, Heidelberg (1996). https://doi.org/10.1007/3-540-61550-4_139
Mosses, P.D.: Modular structural operational semantics. J. Log. Algebr. Program. 60–61, 195–228 (2004). https://doi.org/10.1016/j.jlap.2004.03.008
Mosses, P.D.: VDM semantics of programming languages: Combinators and monads. Formal Aspects Comput. 23(2), 221–238 (2011). https://doi.org/10.1007/s00165-009-0145-4
Mosses, P.D.: A component-based formal language workbench. In: Monahan, R., Prevosto, V., Proença, J. (eds.) F-IDE@FM. EPTCS, vol. 310, pp. 29–34 (2019). https://doi.org/10.4204/EPTCS.310.4
Mosses, P.D.: Software meta-language engineering and CBS. J. Comput. Lang. 50, 39–48 (2019). https://doi.org/10.1016/j.jvlc.2018.11.003
Mosses, P.D., New, M.J.: Implicit propagation in structural operational semantics. ENTCS 229(4), 49–66 (2009). https://doi.org/10.1016/j.entcs.2009.07.073
Mosses, P.D., Vesely, F.: FunKons: component-based semantics in K. In: Escobar, S. (ed.) WRLA 2014. LNCS, vol. 8663, pp. 213–229. Springer, Cham (2014). https://doi.org/10.1007/978-3-319-12904-4_12
Mosses, P.D., Watt, D.A.: The use of action semantics. In: Wirsing, M. (ed.) Formal Description of Programming Concepts III, pp. 135–166. North-Holland (1987)
PLanCompS Project: CBS: A framework for component-based specification of programming languages. https://plancomps.github.io/CBS-beta. Accessed 08 Aug 2021
Plotkin, G.D.: A structural approach to operational semantics. J. Log. Algebr. Program. 60–61, 17–139 (2004). https://doi.org/10.1016/j.jlap.2004.05.001
Rosu, G.: K: a semantic framework for programming languages and formal analysis tools. In: Pretschner, A., Peled, D., Hutzelmann, T. (eds.) Dependable Software Systems Engineering, pp. 186–206. IOS Press (2017). https://doi.org/10.3233/978-1-61499-810-5-186
Scott, D.S., Strachey, C.: Toward a mathematical semantics for computer languages. In: Fox, J. (ed.) Proceedings of the Symposium on Computers and Automata. Microwave Research Institute Symposia, vol. 21, pp. 19–46. Polytechnic Institute of Brooklyn (1971). Also Technical Monograph, PRG-6, Oxford University Computing Laboratory
Sculthorpe, N., Torrini, P., Mosses, P.D.: A modular structural operational semantics for delimited continuations. In: Danvy, O., de’Liguoro, U. (eds.) WoC 2016. EPTCS, vol. 212, pp. 63–80 (2015). https://doi.org/10.4204/EPTCS.212.5
Strachey, C.: Towards a formal semantics. In: Formal Language Description Languages for Computer Programming, pp. 198–216. North-Holland (1966)
Strachey, C.S.: Fundamental concepts in programming languages. High. Order Symb. Comput. 13(1/2), 11–49 (2000). https://doi.org/10.1023/A:1010000313106. Lecture Notes, Int. Summer School in Comput. Prog., Copenhagen (1967)
Torrini, P., Schrijvers, T.: Reasoning about modular datatypes with Mendler induction. In: Matthes, R., Mio, M. (eds.) FICS 2015. EPTCS, vol. 191, pp. 143–157 (2015). https://doi.org/10.4204/EPTCS.191.13
Wansbrough, K., Hamer, J.: A modular monadic action semantics. In: Ramming, C. (ed.) DSL 1997. USENIX (1997). http://www.usenix.org/publications/library/proceedings/dsl97/wansbrough.html
Acknowledgements
Helpful comments on a previous version were provided by Thomas van Binsbergen, Cliff Jones, Neil Sculthorpe, members of the PL Group at Delft, and the anonymous reviewers. Thanks to the track organisers Klaus Havelund and Bernhard Steffen for extra space for the appendices.
The initial development of funcons was supported by an EPSRC grant to Swansea University for the PLanCompS project (EP/I032495/1). The author is now an emeritus at Swansea, and a visitor at Delft University of Technology.
Author information
Authors and Affiliations
Corresponding author
Editor information
Editors and Affiliations
Appendices
A Data
1.1 A.1 Datatypes
Primitive values. Conceptually, primitive values are atomic, and not formed from other values. For large (or infinite) types of primitive values, however, it is infeasible to declare a separate constant for each value. So in practice, funcons used to construct primitive values usually take other values as arguments.
-
\({{\textsf {booleans}}}\) are the values \({{\textsf {true}}}\), \({{\textsf {false}}}\); funcons corresponding to the usual Boolean operations are defined.
-
\({{\textsf {integers}}}\) is the built-in type of unbounded integers, with funcons for the usual mathematical operations. Funcons corresponding to associative binary operations are extended to arbitrary numbers of arguments. Subtypes include \({{\textsf {naturals}}}\) and \({{\textsf {bounded}}(M, N)}\); compositions with casts to such subtypes correspond to partial operations representing computer arithmetic.
-
\({{\textsf {floats}}}\) is the built-in type of IEEE floating point numbers, with funcons for the required operations.
-
\({{\textsf {characters}}}\) is the built-in type of all Unicode characters. Its subtypes include \({{\textsf {ascii}}\text {-}{\textsf {characters}}}\) and \({{\textsf {iso}}\text {-}{\textsf {latin}}\text {-}{\textsf {1}}\text {-}{\textsf {characters}}}\). Its funcons incude the UTF-8, UTF-16, and UTF-32 encodings of characters as byte sequences.
-
\({{\textsf {null}}\text {-}{\textsf {type}}}\) has the single value \({{\textsf {null}}\text {-}{\textsf {value}}}\), alias \({{\textsf {null}}}\).
Composite values. Conceptually, composite values are constructed from finite sequences of argument values. The types of composite values include parametrised algebraic data types, with a generic representation. Various algebraic datatypes are defined, and new ones can be introduced. Composite values include also built-in parametrised types of sets, maps, multi-sets, and graphs.
Algebraic datatypes
-
\({{\textsf {datatype}}\text {-}{\textsf {values}}}\) are generic representations for all algebraic datatype values.
-
\({{\textsf {tuples}}( T_1, \cdots , T_n )}\) are grouped sequences of values of the specified types.
-
\({{\textsf {lists}}(T)}\) are grouped sequences of values of type T, with the usual operations; \({{\textsf {strings}}}\) are lists of characters.
-
\({{\textsf {vectors}}(T)}\) are grouped sequences of values of type T, accessed by index.
-
\({{\textsf {trees}}(T)}\) are finite, with values of type T at nodes and leaves.
-
\({{\textsf {references}}(T)}\) are values that refer to values of type T.
-
\({{\textsf {pointers}}(T)}\) are references to values of type T or \({{\textsf {pointer}}\text {-}{\textsf {null}}}\).
-
\({{\textsf {records}}(T)}\) are unordered aggregate values, indexed by identifiers.
-
\({{\textsf {variants}}(T)}\) are pairs of identifiers and values of type T.
-
\({{\textsf {classes}}}\) are collections of features, allowing multiple superclasses, used to classify objects.
-
\({{\textsf {objects}}}\) are classified collections of features.
-
\({{\textsf {bit}}\text {-}{\textsf {vectors}} ( N )}\) has instantiations for \({{\textsf {bits}}}\) and \({{\textsf {bytes}}}\).
Built-in datatypes
-
\({{\textsf {sets}}(\textit{GT})}\) are finite sets of ground values of type \({\textit{GT}}\).
-
\({{\textsf {maps}}(\textit{GT}, T^?)}\) are finite maps from type \({\textit{GT}}\) to type \(T^?\).
-
\({{\textsf {multisets}}(\textit{GT})}\) are finite multisets of ground values of type \({\textit{GT}}\).
-
\({{\textsf {directed}}\text {-}{\textsf {graphs}}(\textit{GT})}\) have values of type \({\textit{GT}}\) as vertices.
See [26] for funcons that operate on the above types of values.
1.2 A.2 Abstractions
Generic Abstractions. These non-ground values are used for constructing thunks, functions, and patterns. An abstraction body of computation type \(T \mathop {\Rightarrow }T'\) may refer to a given value of type T, and compute values of type \(T'\).
-
\({{\textsf {abstractions}}(CT)}\) are procedural abstractions of computation type CT.
-
\({{\textsf {abstraction}}(X)}\) constructs an abstraction with dynamic bindings.
-
\({{\textsf {closure}} ( X )}\) computes an abstraction with static bindings.
-
\({{\textsf {enact}} ( A )}\) evaluates the body of the abstraction A.
Thunks. The abstraction body of a thunk does not reference a given value.
-
\({{\textsf {thunks}} ( T )}\) are constructed from abstractions with bodies of type \(( \ ) \mathop {\Rightarrow }T'\).
-
\({{\textsf {thunk}}( A )}\) constructs a thunk from the abstraction A.
-
\({{\textsf {force}}( V )}\) enacts the abstraction of the thunk V.
Functions. The abstraction body of a function may reference a given value.
-
\({{\textsf {functions}}( T, T' )}\) are constructed from abstractions with bodies of type \(T \mathop {\Rightarrow }T'\).
-
\({{\textsf {function}} ( {\textsf {abstraction}} ( X ) )}\) constructs a function with dynamic bindings.
-
\({{\textsf {function}} ( {\textsf {closure}}( X ) )}\) computes a function with static bindings.
-
\({{\textsf {apply}} ( F, V )}\) gives the value V to the body of the abstraction of function F.
-
\({{\textsf {supply}}( F, V )}\) determines the argument value of a function application, but returns a thunk that defers evaluating the body of the function.
-
\({{\textsf {compose}}( F_2, F_1 )}\) returns the function that first applies \(F_1\) then \(F_2\).
-
\({{\textsf {curry}} ( F )}\) takes a function F that takes a pair of arguments, and returns the corresponding ‘curried’ function.
-
\({{\textsf {uncurry}}( F )}\) takes a curried function F and returns a function that takes a pair of arguments.
-
\({{\textsf {partial}}\text {-}{\textsf {apply}} ( F, V )}\) takes a function F that takes a pair of arguments, and determines the first argument, returning a function of the second argument.
Patterns. The abstractions of patterns match a given value.
-
\({{\textsf {patterns}}}\) are constructed from abstractions with bodies of computation type \({{\textsf {values}} \mathop {\Rightarrow }{\textsf {environments}}}\).
-
\({{\textsf {pattern}}(A)}\) constructs patterns from abstractions A.
-
\({{\textsf {match}}(X, {\textsf {pattern}}(A))}\) enacts the abstraction A, giving it the value of X.
B Flow of Control
-
\({{\textsf {left}}\text {-}{\textsf {to}}\text {-}{\textsf {right}} ( \cdots )}\) evaluates its arguments sequentially, and concatenates the computed value sequences. Composing it with a funcon having pre-computed arguments prevents interleaving; e.g., \({{\textsf {integer}}\text {-}{\textsf {add}} ( {\textsf {left}}\text {-}{\textsf {to}}\text {-}{\textsf {right}} ( X, Y ) )}\) always executes X before Y.
\({{\textsf {right}}\text {-}{\textsf {to}}\text {-}{\textsf {left}} ( \cdots )}\) is analogous.
\({{\textsf {interleave}} ( \cdots )}\) evaluates its arguments in any order, possibly with interleaving, and concatenates the computed value sequences.
-
\({{\textsf {sequential}} ( X, \cdots )}\) executes the command X, then any remaining arguments, evaluating to the same value(s) as the last argument.
-
\({{\textsf {effect}} ( \cdots )}\) interleaves the evaluations of its arguments, discarding their computed values, and gives \({{\textsf {null}}\text {-}{\textsf {value}}}\).
-
\({{\textsf {choice}} ( Y, \cdots )}\) selects one of its arguments, then evaluates it.
-
\({{\textsf {if}}\text {-}{\textsf {true}}\text {-}{\textsf {else}} ( B, X, Y )}\) evaluates B to a Boolean value, then evaluates either X or Y (which have to compute values of the same type).
-
\({{\textsf {while}}\text {-}{\textsf {true}} ( B, X )}\) evaluates B to a Boolean value, then either executes X (which has to correspond to a command) and iterates, or terminates.
C Flow of Data
-
\({{\textsf {given}}}\) evaluates to the current value of the auxiliary entity \({{\textsf {given}}\text {-}{\textsf {value}}}\).
-
\({{\textsf {give}}( X, Y )}\) evaluates X. It then executes Y with the value of X as the value of the auxiliary entity \({{\textsf {given}}\text {-}{\textsf {value}}}\).
-
\({{\textsf {left}}\text {-}{\textsf {to}}\text {-}{\textsf {right}}\text {-}{\textsf {map}} ( F, V^* )}\) evaluates F for each value in the sequence \(V^*\) in the same order, computing the sequence of resulting values.
\({{\textsf {interleave}}\text {-}{\textsf {map}} ( F, V^* )}\) allows interleaving of the evaluations.
-
\({{\textsf {left}}\text {-}{\textsf {to}}\text {-}{\textsf {right}}\text {-}{\textsf {repeat}}( F, M, N )}\) evaluates F for each integer from M up to N sequentially, computing the sequence of resulting values.
\({{\textsf {interleave}}\text {-}{\textsf {repeat}} ( F, M, N )}\) allows interleaving of the evaluations.
-
\({{\textsf {left}}\text {-}{\textsf {to}}\text {-}{\textsf {right}}\text {-}{\textsf {filter}} ( P, V^* )}\) evaluates P for each value in \(V^*\), computing the sequence of argument values for which the value of P is true.
\({{\textsf {interleave}}\text {-}{\textsf {filter}} ( P, V^* )}\) allows interleaving of the evaluations.
-
\({{\textsf {fold}}\text {-}{\textsf {left}} ( F, A, V^* )}\) reduces a sequence \(V^*\) to a single value by folding it from the left, using A as the initial accumulator value.
\({{\textsf {fold}}\text {-}{\textsf {right}} ( F, A, V^* )}\) is analogous.
For any list L, the funcon term \({{\textsf {list}}\text {-}{\textsf {elements}}(L)}\) evaluates to the sequence \(V^*\) of elements in L, and \({{\textsf {list}}(V^*)}\) reconstructs L. Composition with these funcons allows the above funcons on sequences to be used with lists; similarly for vectors, sets, multisets, and the datatype of maps.
D Name Binding
-
\({{\textsf {bind}}\text {-}{\textsf {value}} ( I, X )}\) computes the singleton environment mapping I to the value computed by X.
-
\({{\textsf {unbind}} ( I )}\) computes an environment that hides the binding of I.
-
\({{\textsf {bound}}\text {-}{\textsf {value}} ( I )}\) computes the value to which I is currently bound (possibly recursively, via a link), if any, and otherwise fails.
-
\({{\textsf {scope}} ( D, X )}\) first evaluates D to compute an environment \(\rho \). It then extends the auxiliary environment entity with \(\rho \) for the execution of X.
-
\({{\textsf {closed}} ( X )}\) prevents references to non-local bindings while evaluating X.
-
\({{\textsf {accumulate}} ( D_1, D_2 )}\) first evaluates \(D_1\), to compute an environment \(\rho _1\). It then extends the auxiliary environment entity by \(\rho _1\) for the evaluation of \(D_2\), to compute an environment \(\rho _2\). The result is \(\rho _1\) extended by \(\rho _2\).
-
\({{\textsf {collateral}} ( D_1, \cdots )}\) evaluates its arguments to compute environments. It returns their union as result, failing if their domains are not pairwise disjoint.
-
\({{\textsf {bind}}\text {-}{\textsf {recursively}} ( I, X )}\) makes \({{\textsf {bind}}\text {-}{\textsf {value}} ( I, X )}\) recursive. It first computes a singleton environment \(\rho \) mapping I to a fresh link L. It then extends the auxiliary environment entity by \(\rho \) for the execution of X, to compute a value V. Finally, it sets L to refer to V, and gives \(\rho \) as the computed result.
-
\({{\textsf {recursive}}( \textit{SI}, D )}\) makes D recursive on the identifiers in the set \({\textit{SI}}\). It first computes an environment \(\rho \) mapping all I in \({\textit{SI}}\) to fresh links. It then extends the auxiliary environment entity by \(\rho \) for the execution of D, to compute an environment \(\rho '\). Finally, it sets the link for each I to refer to the value of I in \(\rho '\), and gives \(\rho '\) as the computed result.
E Imperative Variables
-
\({{\textsf {variables}}}\) is the type of all simple variables.
-
\({{\textsf {allocate}}\text {-}{\textsf {variable}} ( T )}\) constructs a simple variable for storing values of type T in a location not in the current store.
-
\({{\textsf {recycle}}\text {-}{\textsf {variables}}( \textit{Var}, \cdots )}\) removes locations allocated to variables from the current store.
-
\({{\textsf {initialise}}\text {-}{\textsf {variable}}( \textit{Var}, V )}\) assigns V as the initial value of \({\textit{Var}}\).
-
\({{\textsf {allocate}}\text {-}{\textsf {initialised}}\text {-}{\textsf {variable}}( T, V )}\) is a composition of \({{\textsf {allocate}}\text {-}{\textsf {variable}} ( T )}\) and \({{\textsf {initialise}}\text {-}{\textsf {variable}}( \_\,, V )}\).
-
\({{\textsf {assign}}( \textit{Var}, V )}\) stores V at the location of \({\textit{Var}}\) when the type contains V.
-
\({{\textsf {assigned}} ( \textit{Var} )}\) gives the value last assigned to \({\textit{Var}}\).
-
\({{\textsf {current}}\text {-}{\textsf {value}} ( V )}\) gives the same result as \({{\textsf {assigned}} ( V )}\) when V is a simple variable, otherwise V.
-
\({{\textsf {un}}\text {-}{\textsf {assign}} ( \textit{Var} )}\) makes \({\textit{Var}}\) uninitialised.
-
\({{\textsf {structural}}\text {-}{\textsf {assign}} ( V_1, V_2 )}\) assigns to all the simple variables in \(V_1\) the corresponding values in \(V_2\), provided that the structure and all non-variable values in \(V_1\) match the structure and corresponding values of \(V_2\).
-
\({{\textsf {structural}}\text {-}{\textsf {assigned}} ( V )}\) computes V with all simple variables replaced by their assigned values. When V is a simple variable or a value with no component variables, \({{\textsf {structural}}\text {-}{\textsf {assigned}} ( V )}\) gives the same result as \({{\textsf {current}}\text {-}{\textsf {value}} ( V )}\).
F Abrupt Termination
-
\({{\textsf {abrupt}} ( V )}\) terminates abruptly for reason V.
-
\({{\textsf {handle}}\text {-}{\textsf {abrupt}}( X, Y )}\) first executes X. If X terminates normally, Y is ignored. If X terminates abruptly for any reason, Y is executed, with the reason as the given value.
-
\({{\textsf {finally}} ( X, Y )}\) first executes X. On normal or abrupt termination of X, it executes Y. If Y terminates normally, its computed value is ignored, and the funcon terminates in the same way as X; otherwise it terminates in the same way as Y.
-
\({{\textsf {fail}}}\) abruptly terminates for reason \({{\textsf {failed}}}\).
-
\({{\textsf {else}} ( X_1, X_2, \cdots )}\) executes the arguments in turn until either some \(X_i\) does not fail, or all arguments \(X_i\) have been executed. The last argument executed determines the result.
\({{\textsf {else}}\text {-}{\textsf {choice}} ( X_1, X_2, \cdots )}\) is similar, but executes the arguments sequentially in any order.
-
\({{\textsf {check}}\text {-}{\textsf {true}} ( X )}\) terminates normally if the value computed by X is \({{\textsf {true}}}\), and fails if it is \({{\textsf {false}}}\).
-
\({{\textsf {checked}} ( X )}\) fails when X computes the empty sequence of values \(( \ )\), representing that a value has not been computed. It otherwise computes the same as X.
-
\({{\textsf {throw}} ( V )}\) abruptly terminates for reason \({{\textsf {thrown}} ( V )}\).
\({{\textsf {handle}}\text {-}{\textsf {thrown}}( X, Y )}\) handles abrupt termination of X for reason \({{\textsf {thrown}} ( V )}\) with Y.
\({{\textsf {handle}}\text {-}{\textsf {recursively}}( X, Y )}\) is similar to \({{\textsf {handle}}\text {-}{\textsf {thrown}} ( X, Y )}\), except that another copy of the handler attempts to handle any values thrown by Y.
-
\({{\textsf {return}} ( V )}\) abruptly terminates for reason \({{\textsf {returned}} ( V )}\).
\({{\textsf {handle}}\text {-}{\textsf {return}} ( X )}\) evaluates X. If X either terminates abruptly for reason \({{\textsf {returned}} ( V )}\), or terminates normally with value V, it terminates normally giving V.
-
\({{\textsf {break}}}\) abruptly terminates for reason \({{\textsf {broken}}}\).
\({{\textsf {handle}}\text {-}{\textsf {break}} ( X )}\) terminates normally when X terminates abruptly for reason \({{\textsf {broken}}}\).
-
\({{\textsf {continue}}}\) abruptly terminates for reason \({{\textsf {continued}}}\).
\({{\textsf {handle}}\text {-}{\textsf {continue}} ( X )}\) terminates normally when X terminates abruptly for reason \({{\textsf {continued}}}\).
Further funcons are provided for expressing delimited continuations [26, 30].
G Communication
-
\({{\textsf {read}}}\) inputs a single non-null value from the \({{\textsf {standard}}\text {-}{\textsf {in}}}\) entity, and gives it as the result.
-
\({{\textsf {print}} ( V^* )}\) outputs the sequence of values \(V^*\) to the \({{\textsf {standard}}\text {-}{\textsf {out}}}\) entity.
Rights and permissions
Copyright information
© 2021 Springer Nature Switzerland AG
About this paper
Cite this paper
Mosses, P.D. (2021). Fundamental Constructs in Programming Languages. In: Margaria, T., Steffen, B. (eds) Leveraging Applications of Formal Methods, Verification and Validation. ISoLA 2021. Lecture Notes in Computer Science(), vol 13036. Springer, Cham. https://doi.org/10.1007/978-3-030-89159-6_19
Download citation
DOI: https://doi.org/10.1007/978-3-030-89159-6_19
Published:
Publisher Name: Springer, Cham
Print ISBN: 978-3-030-89158-9
Online ISBN: 978-3-030-89159-6
eBook Packages: Computer ScienceComputer Science (R0)