I. the qualification principle ------------------------------------------ THE QUALIFICATION PRINCIPLE (Schmidt 4) or BLOCK STRUCTURE Any semantically meaningful syntactic category should be allowed to have U-blocks : U ::= ... | Typing rule: Semantic analogy: ------------------------------------------ What are expression-blocks in Haskell or ML? How is the qualification principle like the abstracion principle? II. Command Blocks (4.1) A. syntax and typing ------------------------------------------ COMMAND BLOCKS (4.1) Syntax: C ::= ... | begin D in C end Type Rule: Example: begin var A: newint; proc P = begin var C: newint in C:= @A end; proc Q = begin var B: newint; var A: newint in A := 1; call P end in A := 0; call P; call Q end ------------------------------------------ B. semantics (4.1.1) How is storage used in the previous example? ------------------------------------------ SEMANTICS (4.1.1) Behavior of the store: ------------------------------------------ ------------------------------------------ NEW STORE OPERATIONS > type Store storable = [storable] ... > sizeOf :: Store storable -> Integer > sizeOf = genericLength > free :: Integer -> Store storable > -> Store storable > free = genericTake ------------------------------------------ ------------------------------------------ SEMANTICS OF COMMAND BLOCKS data C = ... | Begin D C meaningC((Begin d c)) env s = ------------------------------------------ III. Scope (4.2) A. terms ------------------------------------------ SCOPE (4.2) begin var X: newint in !-----------------------! ! begin var Y: newint in! ! !------------------! ! ! ! X := 0; Y := X ! ! ! !------------------! ! ! end ! !-----------------------! end def: a declaration's *region* is an area of the program's text that within which def: a declaration's *scope* is that part of its region within which ------------------------------------------ B. dynamic scoping ------------------------------------------ DYNAMIC SCOPING (4.2.1) A *dynamic binding* is extant References to a dynamically-bound name refer to the ------------------------------------------ What's the difference from static scoping? ------------------------------------------ EXAMPLES begin var A: newint; proc P = (A := 0) in begin fun A = true in call P end end ------------------------------------------ ------------------------------------------ STATIC vs. DYNAMIC SCOPING (4.2.1) Dynamic scoping: [[invoke I]] e s = f e s where (I,f) \in e [[define I = U]]e s = ({(I,f)},s) where f e' s' = [[U]] e' s' -- OR -- [[invoke I]] e s = [[U]] e s where (I,U) \in e [[define I = U]]e s = ({(I,U)},s) Static scoping: [[invoke I]] e s = f s where (I,f) \in e [[define I = U]]e s = ({(I,f)},s) where f s' = [[U]] e s' ------------------------------------------ IV. extent (4.3) A. terms ------------------------------------------ EXTENT or LIFETIMES (4.3) def: The *extent* of a binding is A bindings extent is can be either: indefinite = dynamic = ALTERNATIVES scope binding \ extent indefinite dynamic lexical dynamic ------------------------------------------ B. dangling references ------------------------------------------ DANGLING REFERENCES AND OTHER FORMS OF ESCAPE Why is it okay to free storage allocated at the time of exit from a block? Examples: /* some C code */ int * hmm() { int i = 0; return &i; } begin proc P = begin var A: newint; proc Q(X:int exp) = A := X in Q end in (call P)(Q) ------------------------------------------ V. declaration blocks (4.4) A. syntax and examples ------------------------------------------ DECLARATION BLOCKS AND INFORMATION-HIDING (4.4) Syntax: D ::= ... | begin D1 in D2 end Example: module GLOBALSTACK(N:int) = begin var CTR: newint, var STACK: array[1..N] of newint in proc PUSH(X:int exp) = if @CTR=N then skip else CTR := @CTR+1; STACK[@CTR] := X fi, proc POP = if @CTR = 0 then skip else CTR := @CTR -1 fi proc TOP = if @CTR = 0 then error else @(STACK[@CTR]) fi proc INIT = CTR := 0 end ------------------------------------------ How does this guarantee information hiding? ------------------------------------------ STATIC VARIABLES As in C and C++ int timescalled() { static int i = 0; i++; return i; } main() { return timescalled() + timescalled(); } ------------------------------------------ How could you do this using local declarations? B. semantics ------------------------------------------ SEMANTICS OF LOCAL DECLARATIONS Typing rule: Semantics: ------------------------------------------ What's the typing rule that's appropriate for this? Do we deallocate the storage at the end of a declaration block? C. problems with the direct model ------------------------------------------ USING HIDDEN TYPE STRUCTURES Example of the problem: module RATIONAL = begin class RAT = record var NUM: newint, var DEN: newint end in proc INITRAT(N:int exp, D: int exp, M:RAT) = (M.NUM := N; M.DEN := D), proc MULTRAT(M:RAT, N: RAT, P: RAT) = (P.NUM := @M.NUM * @N.NUM; P.DEN := @M.DEN * @N.DEN) ... end Can clients use RAT in declarations? ------------------------------------------ Is this a problem in the indirect model too?