Com S 641 meeting -*- Outline -*- * lazy and eager evaluation of abstracts (2.4-2.6) subject: choices for semantics of abstractions and which is (generally) better ------------------------------------------ LAZY vs. EAGER EVALUATION OF ABSTRACTS (2.4-2.6) fun F = @loc 1 + 2 in loc 1 := F; loc 2 := F Eager for store [5,4,1], get Lazy for store [5,4,1], get ------------------------------------------ ... [7,7,1] ... [7,9,1] ** lazy evaluation and the copy rule (2.4) How is lazy evaluation better? ------------------------------------------ WHY LAZY EVALUATION IS BETTER Lazy evaluation allows one to think of an abstract as an Copy rule fun I=E in ... I ... ==> ... ... Example: fun F = @loc 1+2 in loc 1 := F; loc 2 := F ==> ------------------------------------------ ... abbreviation ... E *** formalization ------------------------------------------ FORMALIZING THE COPY RULE Notation: [V1/I1,...,Vn/In]U is simultaneous substitution of the Vi for the Ii. Copy rule for simulataneous declarations D1, D2, ..., Dn define I1 = V1, ..., define In = Vn in U ==> Example: fun two = 2, fun inc1 = @loc 1 + 1 in while not(inc1 = 3) do loc 1 := @loc 1 + two od ==> while not( = 3) do loc 1 := @loc 1 + od ------------------------------------------ Q: How is this like or different from Haskell declarations? simultaneously substitute, but don't permit recursion Q: How would you formally define simultaneous substitution? by induction on the syntax Q: what is it for L := E? see the book p. 43 for the formal definition ------------------------------------------ COPY RULE AND SEQUENTIAL DECLARATIONS Does copy rule work for sequential declarations? fun two = 2; fun inc2 = @loc 1 + two in loc 1 := inc2 ==> loc 1 := ------------------------------------------ ... @loc 1 + two -- oops Q: How could we fix this? define sequential substitution, or reduce this to the previous case by another rule... ------------------------------------------ SEQUENTIAL SUBSTITUTION Copy rule for sequential declarations D1; D2; ...; Dn define I1 = V1; ...; define In = Vn in U ==> Example: fun two = 2; fun inc2 = @loc 1 + two in loc 1 := inc2 ==> ------------------------------------------ ... [V1/I1](... ([Vn/In]U) ...) with the sequential substitution, have to remember that the Di may be simultaneous. ------------------------------------------ COPY RULE FOR DECLARATIONS Copy rule for declarations (define I1 = V1, ..., define In = Vn); D ==> Example: fun two = 2; fun inc2 = @loc 1 + two in loc 1 := inc2 ==> ------------------------------------------ ... define I1 = V1, ..., define In = Vn, [V1/I1,...,Vn/In]D Q: What should [Vj/Ij](define I = U) mean? don't replace the I define I = [Vj/Ij]U Q: Can we substitute @loc 1 for A in (fun A = @loc 2; fun B = A+1)? no, D1;D2 is a binding form, this would be like not respecting bound variables in the lambda calculus. *** debugging Q: Is there anything we could prove about the copy rule that would increase our confidence in it? could prove it preserves typing (thm 2.2) How? show that substitutions preserve typing first could prove it's sound (semantics-preserving) (thm 2.5) How? show substitution into commands preserves meaning (thm 2.3) then show that meaning is same for programs without identifiers (thm 2.4) *** importance Q: How does the copy rule help us understand the semantics? computes effect of declarations translates program back to the core language thus we're sure that all the nice properties of the core language still hold Q: Is lazy fun declaration any different than a macro define? Not much, but... It has to denote a whole expression It is type-checked There are no nasty parentheses problems ** eager evaluation (2.5) Q: Does the copy rule work for eager evaluation? ------------------------------------------ EAGER EVALUATION (2.5) with store [5, 4, 1] fun F = @loc 1+2 in loc 1 := F; loc 2 := F ==> by copy rule fun F = @loc 1+2 in loc 1 := F; loc 2 := F ==> [@loc 1+2/F](loc 1 := F); [@loc 1+2/F](loc 2 := F) ==> [@loc 1+2/F]loc 1 := [@loc 1+2/F](F); [@loc 1+2/F]loc 2 := [@loc 1+2/F](F) ==> loc 1 := @loc 1+2; loc 2 := @loc 1+2 ------------------------------------------ ... [7,7,1] Since copy rule fails, can't refer back to core language semantics Q: What's an eager evaluation declaration like in C or C++? a const declaration Q: Might you want to have both kinds, lazy and eager declarations in a language? Why? yes, but will complicate the language to have both... ** semantics of lazy and eager evaluation (2.6) ------------------------------------------ GENERAL SEMANTICS FOR DECLARATIONS (2.6) Lazy evaluation: [[pi |- define I=U:{I:theta}dec]] e s = [[pi |- invoke I:theta]] e s = Eager evaluation: [[pi |- define I=U:{I:theta}dec]] e s = [[pi |- invoke I:theta]] e s = ------------------------------------------ ... {(I, f)}, where f s' = [[pi |- U:theta]]e s' ... f s, where (I, f) \in e ... {(I,v)}, where v = [[pi |- U:theta]]e s ... v, where (I, v) \in e Q: What's the type of each kind of environment? lazy :: Identifier -> Store -> ExpressibleValue eager :: Identifier -> ExpressibleValue (both of the expressible values are lifted) In eager, the store is given to body directly, so get a value for the expression, to which the identifier is bound ------------------------------------------ FOR YOU TO DO Give the semantics of eager evaluation for functions. [[pi |- fun I = E : {I: t exp}dec]] e s = [[pi |- I : t exp]] e s = ------------------------------------------ There is a problem if the value is \bot in eager evaluation ------------------------------------------ STRICTNESS CONSIDERATIONS Suppose [[pi |- ohno: bool exp]] e s = _|_ What should the meaning of: [[ |- fun A = ohno in skip: comm]] s ------------------------------------------ should be _|_, because we want it to be eager, not lazy, Q: How do we get that to happen compositionally? make (I, _|_) = _|_ { _|_ } = _|_ [[..]] _|_ s = _|_ will also want that e \union _|_ = _|_ \union e = _|_ ** summary Q: How would you summarize the advantages and disadvantages of lazy and eager evaluation of declarations (abstracts)? lazy evaluation is best, because it satisfies the copy rule corresponds to the usual intuition about abstracts, eager evaluation is useful for named constants, but have to be careful, and complicates the semantics (need separate semantics for declarations)