Abstract
We take another look at 1ML, a language in the ML tradition, but with core and modules merged into one unified language, rendering all modules first-class values. 1ML already comes with a simple form of effect system that distinguishes pure from impure computations. Now we enrich it with effect polymorphism: by introducing effect declarations and, more interestingly, abstract effect specifications, effects can be parameterised over, and treated as abstract or concrete in the type system, very much like types themselves. Because type generativity in 1ML is controlled by (im)purity effects, this yields a somewhat exotic novel notion of generativity polymorphism – that is, a given functor can be asked to behave as either “generative” or “applicative”. And this time, we even get to define an interesting (poly)monad for that!
Access this chapter
Tax calculation will be finalised at checkout
Purchases are for personal use only
Similar content being viewed by others
Notes
- 1.
I apologise for any confusion this may cause with the original 1ML paper, where “\(\rightarrow \)” is spelled “\(\Rightarrow \)” and “\(\leadsto \)” is spelled “\(\rightarrow \)”. I chose to change the syntax for the extended system because pure arrows are the more common case now, and I like them to be represented by their natural operator.
References
Biswas, S.K.: Higher-order functors with transparent signatures. In: POPL (1995)
Dreyer, D., Crary, K., Harper, R.: A type system for higher-order modules. In: POPL (2003)
Gifford, D., Lucassen, J.: Integrating functional and imperative programming. In: LFP (1986)
Harper, R., Lillibridge, M.: A type-theoretic approach to higher-order modules with sharing. In: POPL (1994)
Hicks, M., Bierman, G., Guts, N., Leijen, D., Swamy, N.: Polymonadic programming. In: MSFP (2014)
Kuan, G.: A true higher-order module system. Ph.D. thesis, University of Chicago (2010)
Kuan, G., MacQueen, D.: Engineering higher-order modules in SML/NJ. In: Morazán, M.T., Scholz, S.-B. (eds.) IFL 2009. LNCS, vol. 6041, pp. 218–235. Springer, Heidelberg (2010)
Leroy, X.: Applicative functors and fully transparent higher-order modules. In: POPL (1995)
Lucassen, J., Gifford, D.: Polymorphic effect systems. In: POPL (1988)
MacQueen, D., Tofte, M.: A semantics for higher-order functors. In: Sannella, D. (ed.) ESOP 1994. LNCS, vol. 788. Springer, Heidelberg (1994)
Mitchell, J.C., Plotkin, G.D.: Abstract types have existential type. ACM TOPLAS 10(3), 470–502 (1988)
Moggi, E.: Computational lambda calculus and monads. In: LICS (1989)
Rossberg, A.: 1ML - Core and modules united. In: ICFP (2015)
Rossberg, A., Dreyer, D.: Mixin’ up the ML module system. ACM TOPLAS 35(1) (2013)
Rossberg, A., Russo, C., Dreyer, D.: F-ing modules. JFP 24(5), 529–607 (2014)
Russo, C.: Types for modules. In: ENTCS, vol. 60 (2003)
Shao, Z.: Transparent modules with fully syntactic signatures. In: ICFP (1999)
Talpin, J.-P., Jouvelot, P.: Polymorphic type, region and effect inference. JFP 2(3), 245271 (1992)
Tate, R.: The sequential semantics of producer effect systems. In: POPL (2013)
Wadler, P.: The essence of functional programming. In: POPL (1992)
Wadler, P., Thiemann, P.: The marriage of effects and monads. TOCL, 4(1) (2003)
Author information
Authors and Affiliations
Corresponding author
Editor information
Editors and Affiliations
A Elaboration
A Elaboration
1.1 A.1 Internal Language
As in the F-ing modules semantics [15] and the original 1ML paper [13], we define the semantics of the extended language by elaborating 1ML\(_{\mathop {\mathrm {ex}}\nolimits }\) types and terms into types and terms of a (call-by-value, impredicative) variant of System F\(_\omega \) with simple record types – see the syntax in Fig. 7.
However, this time we need a small extension over plain F\(_\omega \): to track generativity effects and the different forms of quantification they can cause in an indexed sum, we require a simple notion of GADT. We add this to F\(_\omega \) in the simplest possible form: an indexed binary sum \((\tau _1 + \tau _2)^\tau \). Operationally, it is equivalent to an ordinary sum, with injections \({\mathsf {inl}} \,e\) and \({\mathsf {inr}} \,e\) and a \({\mathsf {case}} \) construct for elimination. However, the index \(\tau \) allows deducing the choice statically: if it is equivalent to the type \(\top \), then the value is known to be a left injection; analogously, \(\bot \) implies a right injection. Accordingly, there are two additional elimination constructs, \({\mathsf {asl}} \,e\) and \({\mathsf {asr}} \,e\), that are only valid on operands with known index, and perform the respective projection (they correspond to a one-armed case in more general forms of GADTs).
Figure 7 shows the syntax for this IL. The non-standard extensions just described are . The figure also includes the typing and kinding rules for those additional constructs. We omit reduction rules, because they are straightforward. The semantics is otherwise completely standard, and reuses the formulation from [15].
We write \(\varGamma \vdash e : \tau \) for the F\(_\omega \) typing judgement, and let \(e \hookrightarrow e'\) denote (one-step) reduction. As one would hope, the language enjoys the standard soundness properties:
Theorem 1
(Preservation). If \(\cdot \vdash e : \tau \) and \(e \hookrightarrow e'\), then \(\cdot \vdash e' : \tau \).
Theorem 2
(Progress). If \(\cdot \vdash e : \tau \) and e is not a value, then \(e \hookrightarrow e'\) for some \(e'\).
To establish soundness of 1ML it suffices to ensure that elaboration always produces well-typed F\(_\omega \) terms (Sect. A.3).
1.2 A.2 Encoding Semantic Types
Elaboration translates 1ML\(_{\mathop {\mathrm {ex}}\nolimits }\) types directly into “equivalent” System F\(_\omega \) types. The shape of these semantic types was given by the grammar in Fig. 2.
Not all the forms in that grammar are unadorned F\(_\omega \) types, however. Some are auxiliary forms that are definable as syntactic sugar. Figure 8 shows how they can be encoded, along with respective term-level constructs for defining the evidence terms of the elaboration.
Several tricks in the elaboration are new relative to plain 1ML:
-
Computation types are represented using the indexed binary sums introduced in the previous section. Their index is (the desugaring of) an effect type applied to \(\top \) and \(\bot \).
-
To this end, effect types are represented as type constructors representing a simple Church-style encoding of Booleans. The kind of effect types hence is \({{\mathsf {Eff}}} = \varOmega \rightarrow \varOmega \rightarrow \varOmega \), and their application behaves like a conditional.
-
Effects also need to be reified on the term level, however, in order to enable reflection as needed in rule \(\textsc {Sr}\). We use a binary sum (over units) for that purpose that is indexed by the corresponding type-level effect encoding – terms of type \(\textsf {eff}\; \eta \) are term-level encodings of effect type \(\eta \).
-
Since effects \(\eta \) can contain effect variables \(\iota \), this in turn requires those to be represented on both the type and term level. We use the trick of “twinning” each effect variable \(\iota \) in the environment \(\varGamma \) as both a type variable \(\alpha _\iota \) and a term variable \(x_\iota \), assuming appropriate namespace injections. Likewise, every abstraction and quantification over effect variables consistently happens on both levels.
These encodings make sense, because the following consistency properties hold (note how we overload effects \(\eta \) as notation for both types and terms):
Proposition 1
(Derivable Rules for Effect Encodings). Let \(\varGamma \) be a well-formed System F\(_\omega \) environment.
-
1.
\(\varGamma \vdash {\mathop {\mathrm {\texttt {I}}}\nolimits }: {{\mathsf {Eff}}}\).
-
2.
\(\varGamma \vdash {\mathop {\mathrm {\texttt {P}}}\nolimits }: {{\mathsf {Eff}}}\).
-
3.
If \(\iota \in \varGamma \), then \(\varGamma \vdash \alpha _\iota : {{\mathsf {Eff}}}\).
-
4.
If \(\varGamma \vdash \eta _1 : {{\mathsf {Eff}}}\) and \(\varGamma \vdash \eta _2 : {{\mathsf {Eff}}}\), then \(\varGamma \vdash \eta _1 \vee \eta _2 : {{\mathsf {Eff}}}\)
-
5.
\(\varGamma \vdash {\mathop {\mathrm {\texttt {I}}}\nolimits }: {\mathsf {eff}} {\mathop {\mathrm {\texttt {I}}}\nolimits }\).
-
6.
\(\varGamma \vdash {\mathop {\mathrm {\texttt {P}}}\nolimits }: {\mathsf {eff}} {\mathop {\mathrm {\texttt {P}}}\nolimits }\).
-
7.
If \(\iota \in \varGamma \), then \(\varGamma \vdash x_\iota : {\mathsf {eff}} \alpha _\iota \).
-
8.
If \(\varGamma \vdash \eta _1 : {\mathsf {eff}} \eta _1\) and \(\varGamma \vdash \eta _2 : {\mathsf {eff}} \eta _2\), then \(\varGamma \vdash \eta _1 \vee \eta _2 : {\mathsf {eff}} (\eta _1 \vee \eta _2)\).
Here, we write “\(\iota \in \varGamma \) as a shorthand for “\(\varGamma (\alpha _\iota ) = {{\mathsf {Eff}}} \wedge \varGamma (x_\iota ) = {\mathsf {eff}} \alpha _\iota \)”, in correspondence to the twinning for effect variables explained above.
With the notation \(\mathrel {\mathsf {Mon}} _{\overline{\kappa }}\) to denote the kind of a monadic computation constructor mentioning abstract types of kinds \(\overline{\kappa }\), similar consistency properties can be shown for the polymonad notation from Fig. 5:
Proposition 2
(Derivable Rules for Polymonads). Let \(\varGamma \) be a well-formed System F\(_\omega \) environment.
-
1.
If \(\overline{\varGamma , \overline{\alpha }\vdash \pi : \kappa }\), then \(\varGamma \vdash \exists \overline{\alpha }[\overline{\pi }] : {{\mathsf {Mon}}}_{\overline{\kappa }}\).
-
2.
If \(\varGamma \vdash M_1 : {{\mathsf {Mon}}}_{\overline{\kappa }}\) and \(\varGamma \vdash M_2 : {{\mathsf {Mon}}}_{\overline{\kappa }}\) and \(\varGamma \vdash \eta : {{\mathsf {Eff}}}\), then \(\varGamma \vdash (M_1 + M_2)^\eta : {{\mathsf {Mon}}}_{\overline{\kappa }}\).
-
3.
If \(\varGamma \vdash M_1 : {{\mathsf {Mon}}}_{\overline{\kappa }_1}\) and \(\varGamma \vdash M_2 : {{\mathsf {Mon}}}_{\overline{\kappa }_2}\), then \(\varGamma \vdash M_1 M_2 : {{\mathsf {Mon}}}_{\overline{\kappa }_1 \overline{\kappa }_2}\).
-
4.
If \(\varGamma \vdash M : {{\mathsf {Mon}}}_{\overline{\kappa }_\alpha }\) and \(\varGamma \vdash e_1 : M \lambda \overline{\alpha }. \tau _1\) and \(\varGamma , \overline{\alpha }, x{:}\tau _1 \vdash e_2 : \tau _2\), then \(\varGamma \vdash ({\mathsf {do}} _M \overline{\alpha }, x \leftarrow e_1 \mathrel {\mathsf {in}} e_2) : M \lambda \overline{\alpha }. \tau _2\).
-
5.
If \(\varGamma \vdash M_1 : {{\mathsf {Mon}}}_{\overline{\kappa }_1}\) and \(\varGamma \vdash M_2 : {{\mathsf {Mon}}}_{\overline{\kappa }_2}\) and \(\varGamma \vdash e : M_1 \lambda \overline{\alpha }_1. M_2 \lambda \overline{\alpha }_2. \tau \), then \(\varGamma \vdash {\mathsf {join}} _{M_1 M_2} e : M_1 M_2 \lambda \overline{\alpha }_1 \overline{\alpha }_2. \tau \).
Note that our use of \({\mathsf {do}} \)-notation is a slight abuse (if you’re coming from Haskell, anyway): it actually is a \({{\mathsf {map}}}\), not a monadic \({{\mathsf {bind}}}\) – both are instances of polymonadic binds, however.
1.3 A.3 Meta-Theory
With the previous propositions we can verify that elaboration is correct:
Proposition 3
(Correctness of Elaboration). Let \(\varGamma \) be a well-formed F\(_\omega \) environment.
-
1.
If \(\varGamma \vdash T/D \rightsquigarrow \varXi \), then \(\varGamma \vdash \varXi : \varOmega \).
-
2.
If \(\varGamma \vdash F \rightsquigarrow \eta \), then \(\varGamma \vdash \eta : {\mathsf {Eff}} \).
-
3.
If \(\varGamma \vdash E/B :_\eta \varPhi \rightsquigarrow e\), then \(\varGamma \vdash e : \varPhi \) and \(\varGamma \vdash \eta : {\mathsf {Eff}} \). Furthermore, if \(\eta = {\mathop {\mathrm {\texttt {P}}}\nolimits }\) then \({\varPhi \,!} = \varSigma \).
-
4.
If \(\varGamma \vdash \varPhi ' \le _{\overline{\alpha \overline{\alpha }'}} \varPhi \rightsquigarrow \delta ; f\) and \(\varGamma \vdash \varPhi ' : \varOmega \) and \(\varGamma , \overline{\alpha }\vdash \varPhi : \varOmega \), then \(\mathbin {\mathrm {dom}} (\delta ) = \overline{\alpha }\) and \(\varGamma \vdash \delta : \varGamma ,\overline{\alpha }\) and \(\varGamma \vdash f : \varPhi ' \rightarrow \delta \varPhi \).
Together with the standard soundness result for F\(_\omega \) we can tell that the extension of 1ML\(_{\mathop {\mathrm {ex}}\nolimits }\) is still sound:
Theorem 3
(Soundness of \(\mathbf {1ML}_\mathrm{ex}\) with Effect Polymorphism). If \(\cdot \vdash E : \varPhi \rightsquigarrow e\), then either \(e \uparrow \) or \(e \hookrightarrow ^* v\) such that \(\cdot \vdash v : \varPhi \) and v is a value.
Rights and permissions
Copyright information
© 2016 Springer International Publishing Switzerland
About this chapter
Cite this chapter
Rossberg, A. (2016). 1ML with Special Effects. In: Lindley, S., McBride, C., Trinder, P., Sannella, D. (eds) A List of Successes That Can Change the World. Lecture Notes in Computer Science(), vol 9600. Springer, Cham. https://doi.org/10.1007/978-3-319-30936-1_18
Download citation
DOI: https://doi.org/10.1007/978-3-319-30936-1_18
Published:
Publisher Name: Springer, Cham
Print ISBN: 978-3-319-30935-4
Online ISBN: 978-3-319-30936-1
eBook Packages: Computer ScienceComputer Science (R0)