Abstract
Contract monitoring for strict higher-order functional languages has an intuitive meaning, an established theoretical basis, and a standard implementation. For lazy functional languages, the situation is less clear-cut. There is no agreed-upon intended meaning or theory, and there are competing implementations with subtle semantic differences.
This paper proposes meaning preservation and completeness as formally defined properties for evaluating implementations of contract monitoring. Both properties have definitions that can be checked by straightforward inductive proof. A survey of existing suggestions for lazy contract systems reveals that some are meaning preserving, some are complete, and some have neither property. The main result is that contract monitoring for lazy functional languages cannot be complete and meaning preserving at the same time, although each property can be achieved in isolation.
Similar content being viewed by others
Notes
We assume familiarity with Haskell throughout [28].
Pred describes a predicate contract by a boolean function. Fun describes a dependent function contract where the contract on the result depends on the value of the argument. Figure 1 describes the contract API.
Chitil’s lazy contract system [5] avoids this particular pitfall by restricting predicate contracts to base types.
The figure omits blame assignment, which is one of the contributions of their work.
Thanks to IEEE 754, sqrt (-1.0) does not crash but returns NaN. A variation of this example with lists instead of Double can provoke a crash.
This is neither suggested nor implied by the work on lazy assertions.
References
Abercrombie, P., Karaorman, M.: jContractor: design by contract for Java. http://jcontractor.sourceforge.net/ (2003)
Benton, N., Kennedy, A.: Monads, effects, and transformations. In: The Third International Workshop on Higher Order Operational Techniques in Semantics (HOOTS), Paris, France, Sept. 1999 Electronic Notes in Theoretical Computer Science, vol. 26, pp. 3–20. Elsevier, Amsterdam (1999)
Blume, M., McAllester, D.: Sound and complete models of contracts. J. Funct. Program. 16, 375–414 (2006)
Chitil, O.: A semantics for lazy assertions. In: Proceedings of the 20th ACM SIGPLAN Workshop on Partial Evaluation and Program Manipulation, PEPM ’11, Austin, Texas, USA, pp. 141–150. ACM, New York (2011)
Chitil, O.: Practical typed lazy contracts. In: Proceedings of the 17th ACM SIGPLAN International Conference on Functional Programming (ICFP 2012), Copenhagen, Denmark. ACM, New York (2012)
Chitil, O., Huch, F.: Monadic prompt lazy assertions in Haskell. In: Shao, Z. (ed.) Programming Languages and Systems, 5th Asian Symposium, APLAS 2007. LNCS, vol. 4807, pp. 38–53. Springer, Berlin (2007)
Chitil, O., Huch, F.: A pattern logic for prompt lazy assertions. In: Horváth, Z., Zsók, V., Butterfield, A. (eds.) Implementation and Application of Functional Languages, 18th International Symposium, IFL 2006. Budapest, Hungary, LNCS, vol. 4449, pp. 126–144. Springer, Berlin (2007)
Chitil, O., McNeill, D., Runciman, C.: Lazy assertions. In: Trinder, P., Michaelson, G., Pena, R. (eds.) Implementation of Functional Languages, 15th International Symposium, IFL 2003, Edinburgh, UK, Nov. 2004, LNCS, vol. 3145, pp. 1–19. Springer, Berlin (2004)
Degen, M., Thiemann, P., Wehr, S.: True lies: lazy contracts for lazy languages. In: Workshop ATPS 2009, Lübeck, Germany, LNI, vol. 154, pp. 2946–2959 (2009)
Degen, M., Thiemann, P., Wehr, S.: Eager and delayed contract monitoring for call-by-value and call-by-name evaluation. J. Log. Algebr. Program. (2010). doi:10.1016/j.jlap.2010.07.006
Degen, M., Thiemann, P., Wehr, S.: The interaction of contracts and laziness. In: Kiselyov, O., Thompson, S. (eds.) Partial Evaluation and Program Manipulation, PEPM 2012, Philadelphia, PA, USA, pp. 97–106. ACM, New York (2012)
Dimoulas, C., Tobin-Hochstadt, S., Felleisen, M.: Complete monitors for behavioral contracts. In: European Symposium on Programming. Tallinn, Estonia, Apr. 2012, Lecture Notes in Computer Science, vol. 7211. Springer, Berlin (2012)
Fähndrich, M., Barnett, M., Logozzo, F.: Embedded contract languages. In: Shin, S.Y., Ossowski, S., Schumacher, M., Palakal, M.J., Hung, C.-C. (eds.) SAC, Sierre, Switzerland, pp. 2103–2110. ACM, New York (2010)
Findler, R.B., Blume, M.: Contracts as pairs of projections. In: Wadler and Hagiya [31], pp. 226–241
Findler, R.B., Blume, M., Felleisen, M.: An investigation of contracts as projections. Technical report TR-2004-02, University of Chicago, Computer Science Department (2004)
Findler, R.B., Felleisen, M.: Contracts for higher-order functions. In: Peyton-Jones, S. (ed.) Proceedings International Conference on Functional Programming 2002, Pittsburgh, PA, USA, Oct. 2002, pp. 48–59. ACM Press, New York (2002)
Flatt, M., PLT: Reference: Racket. Technical report PLT-TR-2010-1, PLT Inc, (2010) http://racket-lang.org/tr1/
Greenberg, M., Pierce, B.C., Weirich, S.: Contracts made manifest. In: Palsberg, J. (ed.) Proceedings 37th Annual ACM Symposium on Principles of Programming Languages, Madrid, Spain, Jan. 2010, pp. 353–364. ACM Press, New York (2010)
Gronski, J., Knowles, K., Tomb, A., Freund, S.N., Flanagan, C.: Sage: hybrid checking for flexible specifications. In: Workshop on Scheme and Functional Programming (2006)
Hanus, M.: Lazy and faithful assertions for functional logic programs. In: Proc. of the 19th International Workshop on Functional and (Constraint) Logic Programming (WFLP 2010), Universidad Politécnica de Madrid, pp. 50–64 (2010)
Hinze, R., Jeuring, J., Löh, A.: Typed contracts for functional programming. In: Wadler and Hagiya [31], pp. 208–225
Kinsey, Ø.S.: jsContract (2010). http://kinsey.no/projects/jsContract/
Kramer, R.: iContract — the Java design by contract tool. In: Proceedings of the Technology of Object-Oriented Languages and Systems, Santa Barbara, CA, USA, pp. 295–307. IEEE Comput. Soc., Los Alamitos (1998)
Meyer, B.: Applying “Design by contract”. IEEE Comput. 25(10), 40–51 (1992)
Meyer, B.: Eiffel: the Language. Prentice-Hall, New York (1992)
Meyer, B.: Object-Oriented Software Construction, 2nd edn. Prentice-Hall, Upper Saddle River (1997)
Ou, X., Tan, G., Mandelbaum, Y., Walker, D.: Dynamic typing with dependent types. In: Lévy, J.-J., Mayr, E.W., Mitchell, J.C. (eds.) IFIP TCS, pp. 437–450. Kluwer, Norwell (2004)
Peyton Jones, S. (ed.): Haskell 98 Language and Libraries, the Revised Report. Cambridge University Press, Cambridge (2003)
Sun Microsystems: Project Fortress website (2008). http://projectfortress.sun.com/
Wadler, P., Findler, R.B.: Well-typed programs can’t be blamed. In: Castagna, G. (ed.) Proceedings 18th European Symposium on Programming. Lecture Notes in Computer Science, vol. 5502, York, UK, pp. 1–16. Springer, Berlin (2009)
Wadler, P., Hagiya, M. (eds.): Proceedings of the 8th International Symposium on Functional and Logic Programming FLOPS 2006, Fuji Susono, Japan, Apr. 2006. Springer, Berlin (2006)
Xu, D.N., Peyton Jones, S., Claessen, K.: Static contract checking for Haskell. In: Pierce, B. (ed.) Proceedings 36th Annual ACM Symposium on Principles of Programming Languages, Savannah, GA, USA, Jan. 2009, pp. 41–52. ACM Press, New York (2009)
Author information
Authors and Affiliations
Corresponding author
Appendices
Appendix A: Pair-completeness of strict contract monitoring
Throughout the proofs we let === denote definitional equality and contextual equivalence. Recall that this Appendix A and the following Appendix B perform reasoning in a call-by-value calculus. We sometimes misuse notation by writing for a term e such that . Analogous misuse happens for ⇑ and .
Proof
To establish pair-completeness of strict contract monitoring, we have to show that
Thus, we have to check that, for all a, it holds that
If f⇓True then we obtain
If f⇓False then we obtain
Analogously for f⇑ and . □
Appendix B: Uniform monitoring of strict contract monitoring
The proof requires a lemma which states that c t is the identity contract that does not affect its argument.
Lemma 18
For all t and e::t, assert c t e === e.
Proof
The result is trivial if e does not terminate or if e crashes. Hence, assume that e⇓v.
Induction on t.
Case t=().
assert c () e⟶∗
assert c () ()===
assert pok ()===
if True then () else error===
() ok because e⇓()
Case t=( t 1 , t 2 ).
( v 1 , v 2 ) ok because e⇓( v 1 , v 2 )
Case t=t 1→t 2.
(induction applicable because we only pass values to this function)
(induction)
ok □
2.1 B.1 Uniform monitoring
Proof
To establish uniform monitoring for strict contract monitoring, we have to show that for each type t and for each j∈Addr t :
-
1.
G t [assert c t F t ]⇓()
-
2.
;
-
3.
G t [assert c t [j↦pdiverge] F t ]⇑; and
-
4.
.
The first item follows by Lemma 18 and unwinding (Lemma 8).
The proof is by induction on t.
Case t=().
G () [assert c () [j↦pdiverge] F () ]=assert pdiverge ()⇑
Case t=( t 1 , t 2 ).
===
{ two cases, depending on whether \(j \in c_{t_{1}}\) or \(j \in c_{t_{2}}\); suppose \(j\in c_{t_{1}}\) }
by induction:
===
The case \(j\in c_{t_{2}}\) is analogous.
G t [assert c t [j↦pdiverge] F t ]⇑
Similar.
Similar.
Case t=t 1→t 2.
===
===
===
===
===
{assume \(j\in c_{t_{2}}\)}
===
{Lemma 18}
===
===
===
(by induction and because \(G_{t_{2}}\) is an evaluation context)
(if \(j\in c_{t_{1}}\) then by induction)
The cases for divergence and crashes are similar. □
Appendix C: Uniform monitoring of eager contract monitoring
First, a few lemmas are required. The first says that asserting the identity contract c t to F t is not observable for context G t .
Lemma 19
For all t, it holds that G t [assert c t F t ] === ()
Proof
Additional induction hypothesis: For all t, it holds that such that .
Induction on t.
*** Case t=().
This outcome fulfills the claim.
*** Case t=( t 1 , t 2 ).
Fulfills the claim because if \(G_{t_{1}}[F_{t_{1}}']\) and \(G_{t_{2}}[F_{t_{2}}']\) both do, which can be assumed by induction.
*** Case t=t 1→t 2.
It remains to show that \(G_{t_{1} \to t_{2}}\) of the second component reduces to ().
□
Lemma 20
For all t, if asrt c t [j↦pblame] F 1⇓(False, F′), then .
Proof
Induction on t.
*** Case t=()
Clearly, .
*** Case t=( t 1 , t 2 ).
By assumption, b1 && True is False, hence b1 must be False and force x’ .
Clearly, force r === force (force F ′) .
The case where j=1.j′ is proved analogously.
Case t=t 1→t 2.
This case violates the assumption that the first component is False and thus fulfills the claim vacuously. □
3.1 C.2 Main theorem
Proof
To establish uniform monitoring for eager contract monitoring, we have to show that for each type t and for each j∈Addr t :
-
1.
G t [assert c t F t ]⇓();
-
2.
;
-
3.
G t [assert c t [j↦pdiverge] F t ]⇑; and
-
4.
.
The first item is Lemma 19.
The proof is by induction on t. We only elaborate the case for pblame, the other cases are analogous.
We need to rephrase the statement to get a viable inductive hypothesis: For all t, it holds that . The original statement is immediate from this hypothesis.
Case t=().
Case t=( t 1 , t 2 ).
Applying G t [snd[…]] yields
ALTERNATIVES: b1 could be False; in this case force x’ yields by Lemma 20. Also, b1 implies that the case expression . The reasoning for the remaining case b1⇓True is as follows.
The case j=1.j′ is established analogously.
Case t=t 1→t 2.
Applying G t [snd[…]] yields
As \(G_{t_{2}}\) is an evaluation context, there are the following cases for evaluation in the hole.
-
1.
b is False. In this case, if not b then force x’ else ... === force x’ and Lemma 20 yields that force x’ .
-
2.
b is . In this case, the conditional .
-
3.
b is True. In this case, the reasoning continues as follows.
By induction so that the whole expression .
Assuming that j=1.j′ leads to a similar development, except that the last step reads
By Lemma 19:
which by induction. □
Appendix D: Pair-completeness of eager contract monitoring
Proof
(Pair-completeness of eager contract monitoring)
To establish pair-completeness of eager contract monitoring, we have to show that
Thus, we have to check that, for all a, it holds that
Suppose that f,g⇓True.
Suppose that f⇓True, g⇓False.
Suppose that f⇓False, g⇓True.
Alternatively:
Suppose that f,g⇓False.
□