Constructor Specialization. Torben. Mogensen. the residual programs. 2 Overview. further work.

Size: px
Start display at page:

Download "Constructor Specialization. Torben. Mogensen. the residual programs. 2 Overview. further work."

Transcription

1 Constructor Specialization Torben. Mogensen DIKU, University of Copenhagen, Denmark Abstract In the section on \challenging problems" in the proceedings from the rst international workshop on partial evaluation and mixed computation [BEJ88] a question is stated: \Can PE be used to generate new specialized data types, in a way analogous to generating specialized functions". Since then little has been done to address this problem. In [Lau89], new types are indeed generated, but they are all simpler versions of the types in the original program. It is, e.g. not possible to have types with more constructors than the types in the original program. I propose to alleviate this by means of constructor specialization. Constructors are specialized with respect to the static parts of their arguments, just like residual functions. I show how this is done and argue that it makes it possible to get good results from partial evaluation in cases where the traditional methods fail to produce satisfactory results. The discussion is centered around a small subset of Standard ML, but the idea applies equally well to other languages having user dened constructors, e.g. Haskell and Prolog. 1 Motivation It is usually considered bad practice if all residual programs for a given initial program share some syntactic limits with the original program, when these limits are not present in the language as a whole. This is especially true when partially evaluating an interpreter: any limits in the target programs means that the target language is not fully exploited. An example is if the number of function denitions in a residual program cannot be greater than the number of function denitions in the original program. This limitation is lifted when polyvariant specialization of functions are used ([Bul88], [JSS85], [JSS89]). The literature shows other examples of early partial evaluators having such inheritable limitations which later systems avoid, e.g. the number of arguments to functions being no greater in the residual functions than in the original functions, which is solved by variable splitting ([Ses86], [Mog88], [Rom90], [Lau89]). Basically one can look at features that the programming language allows unlimited use of, but which any particular program uses only nitely. In addition to the above, languages with user denable constructors, usually only allow a nite number of such in any particular program. Partial evaluators of such languages (e.g. [Lau89]) usually allow only constructors from the original program to appear in the residual programs. This can have the eect that data structures in the residual programs are represented suboptimally, as they will have to be forced into the mold of the data types from the original program. This is often the case in interpreters for typed languages: values of all types are represented using a single universal type, and this is carried over to the residual programs, where this ought no longer to be necessary. 2 Overview I show a simple example of a program where normal specialization techniques yield unsatisfactory results, and show that constructor specialization handles this well. I then discuss how to modify binding time analysis and specialization algorithm to handle constructor specialization. I briey touch upon possible renements to these methods and some semantic issues that are raised by constructor specialization. I then revisit the example and show how a simple modication of the program improves the result obtained through constructor specialization. This is an instance of bindingtime improvement [HH91]. Finally I conclude and discuss further work. 3 An example Consider the Standard ML program shown in gure 1. It implements a simple parser for a restricted class of grammars using only one nonterminal. EMPTY corresponds to the empty string, REC is a recursive reference to the entire grammar (and is thus the only nonterminal). SYMB indicates a terminal symbol and SEQ and ALT indicates sequence and alternative. The function parse takes a grammar and a list of terminal symbols and determines if the list is in the language generated by the grammar. It uses a stack of pieces of the grammar, which will be used to match against the remainder of the terminal list. The data type ToDo implements this stack. The parser backtracks on alternatives. Let us consider specialization of the parser with respect to a specic grammar. A simple binding time analysis will tell us that the grammar and the stack are static throughout, so we expect all to be well when specializing. Let's try the grammar G! (G)G j, which is represented in the data type by ALT(SEQ(SYMB("("),SEQ(REC,SEQ(SYMB(")"),REC))), EMPTY)

2 Figure 1: Backtracking parser datatype Gram = EMPTY REC SYMB of string SEQ of Gram*Gram ALT of Gram*Gram datatype ToDo = DONE DO of Gram*ToDo fun parse(g,s) = p(g,s,g,done) fun p(g,s,g0,todo) = case g of EMPTY => nowdo(todo,s,g0) REC => p(g0,s,g0,todo) SYMB c => s<>[] andalso (hd s)=c andalso nowdo(todo,tl s,g0) SEQ (g1,g2) => p(g1,s,g0,do(g2,todo)) ALT (g1,g2) => p(g1,s,g0,todo) orelse p(g2,s,g0,todo) fun nowdo(todo,s,g) = case todo of DONE => s=[] DO (g1,todo') => p(g1,s,g,todo') To our (maybe not so great) surprise the specialization doesn't terminate. The reason is that the stack grows unboundedly during specialization. It is clear that, in general, the size of the stack depends on the input string, so it is not the fault of the partial evaluator per se. The usual solution to handle unbounded data structures is to generalize them, either during specialization or by modifying the binding times. This, however, has the unfortunate eect that, since the grammar is stored on the stack, it too becomes dynamic. The result is that no speedup can be obtained by partial evaluation. It is not obvious that the program can be rewritten to avoid this problem (unless one uses continuations like in [Mos93], but that is a major rewrite, and not an option if the language does not support higher order functions). We take a closer look at why the generalizing the stack causes the grammar to be dynamic. When handling the sequence operator, the parser pushes a part of the grammar on the stack, using the constructor DO. Since the stack is generalized, DO is a dynamic constructor and the normal rules for binding times makes the arguments to it dynamic too. Thus, when we pop the grammar from the stack in nowdo, it is dynamic. But what if we allow dynamic constructors to have static arguments? Then we can pop a static grammar from the stack, even when this is dynamic. \How," I hear you say \are we supposed to do this?". When we use DO to push the grammar on the stack, we must generate code in the residual program that does this (the stack is dynamic, remember), and similarly we must generate residual code to pop the stack in the residual versions of nowdo. Instead of pushing the actual grammar, we can specialize DO to the grammar and use the specialized constructor to do the pushing. When popping, we do a case over the specialized versions of DO and in each branch we can use the static grammar that the corresponding constructor is specialized with. If we use the example grammar from above, we will during execution push the following bits of the grammar: SEQ(REC,SEQ(SYMB(")"),REC)) SEQ(SYMB(")"),REC) REC We can thus make three specialized versions of DO, corresponding to each of these possibilities. Let us call these DO_0, DO_1 and DO_2. When doing a case on these (in nowdo), we can in the branch corresponding to DO_0 use the fact that the grammar (g1) is SEQ(REC,SEQ(SYMB(")"),REC)) etc. Thus the grammar will remain static in all calls to p, and we obtain the residual program shown in gure 2. We have unfolded all calls to p, except the rst and the one in the branch of the REC operator. The calls to nowdo are all left residual. It can be seen that all mention of the grammar has been evaluated away during specialization. It is clear that the residual parser is much more ecient than the original. However, there is still room for improvement: there are two calls to nowdo' with constructors in the arguments. These will immediately be tested upon. Unfolding these calls can remove some dynamic pushing and popping. Note that we still need to push DO_1 and test for this against DONE. We will later see how we can modify the parser slightly so the superuous operations disappear from the residual parser. 4 A small language First we describe a small subset of Standard ML [MTH90], which will be used in the sections on binding time analysis and specialization. The syntax of the language is shown in gure 3. Note that the data type declarations are monomorphic. Polymorphic data types cause some extra bookkeeping during binding time analysis and partial evaluation, so for ease of presentation, these have been left out. For similar reasons

3 Figure 2: Residual parser using constructor specialization datatype ToDo' = DONE DO_0 of ToDo' DO_1 of ToDo' DO_2 of ToDo' fun parse'(s) = p'(s,done) fun p'(s,todo) = (s<>[] andalso (hd s)="(" andalso nowdo'(do_0 todo,tl s)) orelse nowdo'(todo,s) fun nowdo'(todo,s) = case todo of DONE => s=[] DO_0 todo' => p'(s,do_1 todo') DO_1 todo' => s<>[] andalso (hd s)=")" andalso nowdo'(do_2 todo',tl s) DO_2 todo' => p'(s,todo') Figure 3: Syntax of SML subset P rogram! Datatype F unction Datatype! datatype T ypeid = Contype + j Contype! Conid of T ypeid F unction! fun F unid P attern = Exp P attern! (V arid ; ) Exp! V arid j F unid Exp j Basic Exp j ConidExp j (Exp ; ) j case Exp of Branch + j Branch! Conid P att => Exp the language is restricted to rst order functions and no local denitions. Inx operators are assumed to be syntactic sugar for calls to basic functions, and so do not occur in the grammar. Similarly nullary constructors and functions are considered sugar for functions taking an argument of unit type. Constants are nullary basic functions. The notation Nonterminalsymbol is shorthand for a (possibly empty) sequence of separated by symbol. Similarly Nonterminal + symbol stands for a non-empty sequence. We will later use Nonterminal? to stand for zero or one occurrence of Nonterminal. 5 Binding time analysis A common way to describe binding times for functional languages is to use projections [Lau89], [Mog89], but there is no projection that naturally describes a data type where the constructors are unknown and their arguments known. So instead we will us a type-based approach like in [GJ91], [Mog92] and [Hen91]. For simplicity of presentation we'll use a simple monomorphic system, but the idea scales in the usual way to more complex systems. The binding times are described as a set of type rules. Binding time analysis consists of type inference using these rules. Figure 4 shows the syntax of annotated programs. Underlining is used to describe dynamic parts of the program. It is assumed that the program initially contains no underlines, but that a minimal consistent underlining will be provided during a type inference based binding time analysis. Details can be found in [Hen91]. Three environments are used: for variables, for functions and for constructors. All environments map their objects to binding time annotated types. is used to join environments. In case of common names in and 0, 0 takes precedence in 0. An annotated type has the form BT type! T ypeid j T ypeid j BT type j BT type! BT type where underlines denote dynamic types. For convenience of notation we will use the equivalences that the empty product type is the unit type () and that BT 1... BT n = BT 1... BT n. We will thus use BT for a completely dynamic type. Note that since the language is rst order, there is no such thing as a dynamic function. A constructor is considered a function from its argument types to its data type. If a constructor is dynamic, its data type is and vice versa, so there is no need to annotate the function space arrow. We rst present rules for a \traditional" binding type analysis and then modify these to handle constructor specialization. The \traditional" type rules are given in gure 5. The types for the dierent logical connectives are shown with the rules that have them in their conclusion. Obviously, it is the rules involving dynamic constructors that must be modied to accommodate constructor specialization. The rule for constructor declaration states that the argument type of a constructor in a dynamic data type must be dynamic. We remove this side condition. Similarly the rule for dynamic constructor application says that the argument must be dynamic. We change this so it (like in dynamic function applications) can be of any binding time. There is no need to change the rule for case-expressions, as

4 Figure 4: Annotated syntax AP rogram! ADatatype AF unction ADatatype! datatype T ypeid = AContype + j j datatype T ypeid = AContype + j AContype! Conid of AT ypeid AF unction! fun F unid AP attern = AExp AP attern! (AV arid ; ) AExp! V arid j F unid AExp j F unid AExp j Basic AExp j Basic AExp j Conid AExp j Conid AExp j (AExp ; ) j case AExp of ABranch + j j case AExp of ABranch + j ABranch! Conid AP att => AExp AT ypeid! T ypeid j T ypeid AV arid! V arid j V arid it imposes no restrictions on the arguments of constructors. One can note, though, that it is now possible to have static pattern variables in dynamic case-expressions. The modi- ed rules are shown in gure 6. The binding time analysis is thus no more complex than before the modications, if anything it is simpler. If we had used an abstract interpretation approach, we would have had to modify our binding time domain. So in this respect the type/constraint based approach is more exible. 6 Specialization We use inference rules to specify a relation between the original program and the specialized program. Again, this leaves some room for dierent implementations. The rules are shown in gures 7 and 8. The binding time environments and are used in the rules for specialization. In addition to these, maps constructors to the sets of the static arguments to which they are specialized and maps function names to sets of static arguments. The environment binds variables to partially static values. The static parts of these are values, and the dynamic parts are residual expressions: P V al! V alue j Exp j (P V al; ) j Conid(P val) We are a bit sloppy in that we use (;... ; ) both for tupling of values and for constructing tuple-expressions. Specialized functions and constructors are identied by pairs of their original names and the static parts of their arguments. These pairs must be replaced by new names in the usual way. 0 contains the goal function and the arguments to which this must be specialized. The environment ensures that all specialized functions that are called are also dened, and ensures that if a constructor is specialized, then all it's specialized versions are declared and occur in every residual case-expression where the original constructor appears in the corresponding original case-expression. This is handled in the rules for Function, Contype and Dynamic branch. The rules for Pattern and Varid are used to build specialization time environments and residual patterns. The function new creates new unique variable names. The rules for Exp specializes expressions. Static expressions produce values and dynamic expressions produce residual expressions. Partially static expressions produce a mixture of these, which must be taken apart (using %) when needed as arguments to residual function calls or dynamic constructor applications (note the similarity between the rules for these). The most interesting case is the dynamic case-expression. Each branch in the original case-expression is made into several branches in the residual case-expression. These branches are produced by the rule for Dynamic branch; the possible static arguments are fetched from and each value is used to make a residual branch: the constructor name is specialized, the pattern is specialized, a new environment is built, in which the body of the branch is specialized. If constructor specialization is not used, only a single residual branch would be produced, and all pattern variables would be dynamic. Note the similarity between the rule for Dynamic branch and for Function. The main dierence is that the rule for Dynamic branch is used in every dynamic caseexpression, whereas the rule for Function is applied only once for each function. Retyping similar to what is achieved through projection factorisation in [Lau89] is done by the rules for Type: the residual type depends on the static value. Note how these rules parallel the rules for splitting a partially static value into its static and dynamic components and for variable splitting. Static base types are replaced by the unit type and the corresponding dynamic expressions are replaced by the unit constant (). The tuple type constructor used in the rules for constructing residual types is assumed to be associative and has the unit type as unit element. New parameter lists (patterns) to functions and constructors are constructed, such that each dynamic component of a partially static value becomes a separate parameter. For formal parameters this is handled by the rules for Pattern and Variable splitting. For actual parameters the rules for splitting values into static and dynamic components are used. The operator + is used to join tuple expressions and patterns. It obeys the rules below. The rules are prioritized from top to bottom. () ++ x = x x ++ () = x x ++ y = (x; y) (x 1;... ; x n) ++ (y 1;... ; y n) = (x 1;... ; x n; y 1;... y n) x ++ (y 1;... ; y n) = (x; y 1;... ; y n) (x 1;... ; x n) ++ y = (x 1;... ; x n; y) The operation new(v ) used in the rules for Variable splitting creates a new unique name from the name V.

5 Figure 5: Type rules for binding time analysis Program: ` AP rogram / (Conid! BT type)=(f unid! BT type) ` D 1 > 1... ` D 1 > n = 1... n ; ` F n ; ` F n m m = 1... m ` D 1... D n F n 1... F n m / = Datatype: ` ADatatype > (Conid! BT type) ` datatype T i = C 1 of BT 1 j... j C n of BT n > [C 1 7! BT 1! T i ;... ; C n 7! BT n! T i] ` datatype T i = C 1 of BT 1 j... j C n of BT n > [C 1 7! BT 1! T i ;... ; C n 7! BT n! T i] Function: (Conid! BT type); (F unid! BT type) ` AF unction (F unid! BT type) Pattern: ` AP attern ; (V arid! BT type)=bt type ` P ; =BT 1 ; ; ` E : BT 2 ; ` fun F P = E [F : BT 1! BT 2] ` (V 1;... ; V n) ; [V 1 7! BT 1;... V n 7! BT n]=bt 1... BT n Exp: (Conid! BT type); (F unid! BT type); (V arid! BT type) ` AExp : BT type V = BT ; ; ` V : BT F = BT 1! BT 2 ; ; ` E : BT 1 ; ; ` F E : BT 2 F = BT 1! BT 2 ; ; ` E : BT 1 ; ; ` F E : BT 2 B : T 1! T 2 ; ; ` E : T 1 ; ; ` B E : T 2 B : T 1! T 2 ; ; ` E : T 1 ; ; ` B E : T 2 C = BT 1! T i ; ; ` E : BT 1 ; ; ` C E : T i C = BT 1! T i ; ; ` E : BT 1 ; ; ` C E : T i ; ; ` E 1 : BT 1... ; ; ` E n : BT n ; ; ` (E 1;... ; E n) : (BT 1;... ; BT n) ; ; ` E : T i ; ; ; T i ` B 1 :> BT 2... ; ; ; T i ` B n :> BT 2 ; ; ` case E of B 1j... jb n : BT 2 ; ; ` E : T i ; ; ; T i ` B 1 :> BT 2... ; ; ; T i ` B n :> BT 2 ; ; ` case E of B 1j... jb n : BT 2 Branch: (Conid! BT type); (F unid! BT type); (V arid! BT type); BT type ` ABranch :> BT type C = BT 1! T i ` P ; 0 =BT 1 ; ; 0 ` E : BT 2 ; ; ; T i ` C P => E :> BT 2

6 Figure 6: Modied type rules for binding time analysis Datatype: ` datatype T i = C 1 of BT 1 j... j C n of BT n > [C 1 7! BT 1! T i ;... ; C n 7! BT n! T i] Exp: C = BT 1! T i ; ; ` E : BT 1 ; ; ` C E : T i It is easy in an implementation of the specialization rules to maintain : entries are added whenever residual function calls are made, and residual functions are generated for each entry until all entries have denitions. New entries can never cause earlier generated residual function denitions to be invalid, so the new denitions are simply added to the existing denitions. Things are not as simple with. A new specialized constructor requires all residual case-expressions of relevant type to test on this, even those case-expressions that are already generated. Thus either regeneration of old function denitions in a standard xed-point iteration style or an ability to \backpatch" earlier generated case-expressions is needed. The rst solution is simple, but inecient. The second solution is potentially more ecient, as each piece of residual code is only generated once, but requires either destructive updating of the residual program, or a multi-pass algorithm that rst generates \pieces" of code for the caseexpression branches and then assembles these in the nal residual program. 7 Renements and semantic considerations There is a lot of room for improvement of both binding time analysis and specialization as they are shown here. First of all, polyvariant binding time analysis ([GR92], [DNBDV91]) could be used. Specialized constructors add no fundamental extra complexities to this problem, except that projections, as used in [Lau89] and [DNBDV91] appear ill-suited for describing binding times involving specialized constructors. Another problem (which is unrelated to polyvariant binding time analysis) is the fact that types are specialized monovariantly in the specialization denition presented in this paper. Thus the residual program can have no more data type declarations than the original program, something that is against our \guiding rule" of not letting limits be inherited. It also has some potential semantic problems: when specializing a constructor it is automatically assumed that it will be used in any residual version of case-expressions that use the original constructor. Consider an interpreter where a universal data type is used to represent arbitrary types. Consider this interpreter specialized with respect to a program that uses two types. The two types will in the residual program be represented by a single type, and the functions that operate on one of the types will also have to test on the constructors from the other type. This can in the worst case cause run-time errors during specialization, and at best there will be lots of \dead code" in the residual program. The solution to this is to perform polyvariant type specialization: the specialized constructors are not collected into a single type, but grouped corresponding to where they are generated and used in the residual program. It is not clear how best to do this, but one could assume that newly generated specialized constructors are in a type of their own, and only combine the types when necessary, e.g. when they occur as the result of dierent branches to the same caseexpression. A union/nd style algorithm would be suitable for this approach. The rules for specialization say nothing about what happens if specialized constructors occur in the output of the program. The most obvious solution is to disallow this by adding constrains that enforce all parts of output types to be dynamic. Another solution would be to allow specialized constructors in the output, but letting the specializer in addition to the residual program also return a specication of how the specialized constructors correspond to original terms. This can be seen as a derivor mapping the specialized data types to the original data types. Such a derivor can also be allowed as part of the input to the specializer, allowing a program to be specialized with respect to the specialized data type of another program. This can be used to specialize the interface types of multi-pass algorithms. This is an similar what Ershov calls mixed computation [BEJ88]: both residual program and residual data are produced. In our case, though, it is not actual data, but a data specication that is produced. 8 The example revisited In section 3 I promised to show a modication of the parser program from gure 1, which would allow better specialization. The problem was that, in the residual program, p' would call nowdo' with a constructor which immediately would be decomposed inside nowdo'. The problem occurs because all applications of the constructor DO are made residual. The reason we made them residual was to avoid innite growth in the stack, but this only occurs because we have recursion in the grammer. If we can generalize the stack only when recursion occurs, we can make more of the stack static. A way to do this is to leave the type ToDo static, but encapsulate the stack in a dynamic constructor of another type whenever recursion is needed. The modied parser is shown in gure 9. By making ToDo1 dynamic, we can avoid innite growth of the stack. Using the same grammar as in section 3, we will apply GENERALIZE to the following arguments DONE DO(SEQ(SYMB(")"),REC),GENERALIZED(<ToDo1>)) Note that the function generalize ensures that GENERALIZE will not be applied to an already generalized argument. This

7 Figure 7: Rules for specialization (Part 1) Program: (Conid! BT type); (F unid! BT type); (F unid! fp valg) ` AP rogram / P rogram ; ` D i > Ds i for i = 1;... ; n ; ; ; ` F n j F ns j for j = 1;... ; m 0 ; ; 0 ` D 1... D n F n 1... F n m / Ds 1... Ds n F ns 1... F ns m Datatype: (Conid! BT type); (Conid! fp valg) ` ADatatype > Datatype? ; ` datatype T i = Cs > ; ` C 1. Cs 1... ; ` C n. Cs n ; ` datatype T i = C 1j... jc n > datatype T i = Cs 1j... jcs n Contype: (Conid! BT type); (Conid! fp valg) ` AContype. Contype + j Type: (Conid! BT type); BT type ` P val & T ype C = fv 1;... ; v ng ; BT ` v 1 & T 1... ; BT ` v n & T n ; ` C of BT. (C; v 1) of T 1 j j (C; v n) of T n ; T ` v & (T ) ; T i ` v & () if T i is a base type C = BT! T i ; BT ` v & T ; T i ` C(v) & T if T i is a data type ; BT 1 ` v 1 & T 1... ; BT n ` v n & T n ; BT 1... BT n ` (v 1;... ; v n) & T 1... T n Function: (Conid! BT type); (Conid! fp valg); (F unid! BT type); (F unid! fp valg) ` AF unction F unction F = BT 1! BT 2 F = fv 1;... ; v ng ; BT 1; P ` v i ; i=p i ; ; ; ; i ` E : E i for i = 1;... ; n ; ; ; ` fun F P = E fun (F; v 1) P 1 = E 1... fun (F; v n) P n = E n Pattern: (Conid! BT type); BT type; AP attern ` (P V al ; ) ; (V arid! P val)=p attern ; BT 1; V 1 ` v 1,! v 0 1=P 1... ; BT n; V n ` v n,! v 0 n=p n ; BT 1... BT n; (V 1;... ; V n) ` (v 1;... ; v n) ; [V 1 7! v 0 1;... ; V n 7! v 0 n]=p P n Variable splitting: (Conid! BT type); BT type; V arid ` (P V al ; ),! (V arid! P val)=p attern V 0 = new(v ) ; T ; V ` (),! V 0 =V 0 ; T i; V ` v,! v=() if T i is a base type C = BT! T i ; BT; V,! v 0 =P ; T i; V ` C(v),! C(v 0 )=P if T i is a data type ; BT 1; V,! v 0 1=P 1... ; BT n; V,! v 0 n=p n ; BT 1... BT n; V ` (v 1;... ; v n),! (v 0 1;... v 0 n)=p P n

8 Figure 8: Rules for specialization (Part 2) Exp: (Conid! BT type); (Conid! fp valg); (F unid! BT type); (F unid! fp valg); (V arid! P val) ` AExp : P V al V = v ; ; ; ; ` V : v ; ; ; ; ` E : v v ` P ; 0 =P 0 ; ; ; ; 0 ` E 0 : w ; ; ; ; ` F E : w where F is dened by fun F P = E 0 F = BT 1! BT 2 ; ; ; ; ` E : v ; BT 1 ` v % v 0 =E 0 v 0 2 F ; ; ; ; ` F E : (F; v 0 ) E 0 ; ; ; ; ` E : v ; ; ; ; ` B E : b(v) ; ; ; ; ` E : E 0 ; ; ; ; ` B E : B E 0 ; ; ; ; ` E : v ; ; ; ; ` C E : C(v) C = BT 1! T i ; ; ; ; ` E : v ; BT 1 ` v % v 0 =E 0 v 0 2 C ; ; ; ; ` C E : (C; v 0 ) E 0 ; ; ; ; ` E 1 : v 1... ; ; ; ; ` E n : v n ; ; ; ; ` (E 1;... ; E n) : (v 1;... ; v n) ; ; ; ; ` E : C i(v) v ` P i ; 0 =P 0 ; ; ; ; 0 ` E i : w ; ; ; ; ` case E of C 1 P 1 => E 1 j... j C n P n => E n : w ; ; ; ; ` E : E 0 ; ; ; ; ` B i :> Bs i for i = 1;... ; n ; ; ; ; ` case E of B 1j... jb n : case E 0 of Bs 1j... jbs n Dynamic branch: (Conid! BT type); (Conid! fp valg); (F unid! BT type); (F unid! fp valg); (V arid! P val) ` ABranch :> Branch j C = BT! T i C = fv 1;... ; v ng ; BT; P ` v i ; i=p i ; ; ; ; i ` E : E i for i = 1;... ; n ; ; ; ; ` C P => E :> (C; v 1) P 1 => E 1 j... j (C; v n) P n => E n Splitting into static and dynamic parts: (Conid! BT type); BT type ` P val % V al=exp ; T ` E % ()=(E) ; T i ` v % v=() if T i is a base type C = BT! T i ; BT ` v % v 0 =E ; T i ` C(v) % C(v 0 )=E if T i is a data type ; BT 1 ` v 1 % v 0 1=E 1... ; BT n ` v n % v 0 n=e n ; BT 1... BT n ` (v 1;... ; v n) % (v 0 1;... ; v 0 n)=e E n

9 Figure 9: Modied parser datatype Gram = EMPTY REC SYMB of string SEQ of Gram*Gram ALT of Gram*Gram datatype ToDo = DONE DO of Gram*ToDo GENERALIZED ToDo1 datatype ToDo1 = GENERALIZE ToDo fun parse(g,s) = p(g,s,g,generalized(generalize(done))) fun p(g,s,g0,todo) = case g of EMPTY => nowdo(todo,s,g0) REC => p(g0,s,g0,generalize(todo)) SYMB c => s<>[] andalso (hd s)=c andalso nowdo(todo,tl s,g0) SEQ (g1,g2) => p(g1,s,g0,do(g2,todo)) ALT (g1,g2) => p(g1,s,g0,todo) orelse p(g2,s,g0,todo) fun generalize(todo) = case todo of GENERALIZED(t) => t _ => GENERALIZED(GENERALIZE(todo)) fun nowdo(todo,s,g) = case todo of DONE => s=[] DO (g1,todo') => p(g1,s,g,todo') GENERALIZED t => case t of GENERALIZE todo' => nowdo(todo',s,g) Figure 10: Residual modied parser datatype ToDo1' = GENERALIZE_0 GENERALIZE_1 of ToDo1' fun parse'(s) = p'(s,generalize_0) fun p'(s,todo) = (s<>[] andalso (hd s)="(" andalso p'(tl s,generalize_1(todo))) orelse (case todo of GENERALIZE_0 => s = [] GENERALIZE_1(todo') => (s<>[] andalso (hd s)=")" andalso p'(tl s,todo'))

10 would have lead to extra dynamic construction and decomposition. We get the residual program shown in gure 10. All calls to nowdo and all calls to p except the initial call and the call in the REC branch are unfolded. It is now clear from the residual program that the depth of the stack is the number of outstanding parenthesis. Note that the todo argument of p has been retyped: where it originally was ToDo it is now a specialized instance of ToDo1, which is the type of the dynamic argument to a constructor (GENERALIZED) of the original type. The \trick" of generalizing unbounded structures only at particular places, guarded by constructors like GENERALIZE and GENERALIZED corresponds closely to a similar \trick" which is used to generalize continuations in Similix, where the guards are eta-conversions ([Bon91], [Mos93]). 9 Conclusion and further work I rst got the idea of constructor specialization in 1987 when I was writing an interpreter for a functional language in a term rewrite language. This interpreter used a stack and partial evaluatially evaluating it caused the same problems with unbounded stacks as shown in the example here. I considered ways of handling this problem and found that constructor specialization would help. I didn't follow up on the idea, as my attention turned elsewhere. But I have always thought the idea had merit, so I have now tried to formalize the idea and present them to a greater public. I believe constructor specialization will have most impact on two kinds of program: those that use a stack or similar structure (as shown in the example) and interpreters that use a single data type to encode a large family of types in the implemented languages. The latter problem has been investigated in [Lau91b] and [HL91] in the context of selfappliction, where a double level of coding is needed. Constructor specialization does not handle the problem of large space requirements that these papers have dierent solutions to, but instead improves the quality of the residual programs (e.g. compiled programs) by \inventing" suitable data types for each residual program. As mentioned in section 7, the presented specialization method needs a further renement to handle this really well. In higher order languages the problem of unbounded stack can sometimes be solved by using continuations. This is the case with the parser shown in the example, and it is also the solution chosen in [Mos93]. There is no similar approach that will work for coding of data-structures in interpreters. It is in general possible to replace arbitrary algebraic types with higher order functions, but it doesn't yield the desired result and will in most cases cause problems in typed languages, when recursive data types (legal) are replaced by recursive function types (illegal). In the abstract I said that the ideas are applicable to other languages and mentioned Haskell and Prolog. Haskell is suciently similar to ML that this is no surprise. Prolog has two properties that can cause problems: it is untyped and it allows unication of terms containing unbound variables. The untyped nature is not much of a problem, as specialization is mostly at the constructor level rather than the type level anyway. Unication can be a problem, though. It boils down to what happens when two dierently specialized versions of the same constructor are unied. If the static arguments to which they are specialized are uniable, the unication should succeed. But if dierent names are given to the specialized constructors, unication will fail. A solution to this problem is to make sure that the static parts are only uniable if they are in fact equal. If they are ground, this is cartainly true. It would therefore seem reasonable to require the parameters to which constructors are specialized to be ground. In Logimix [MB93], predicates are (for similar reasons) only specialized with respect to ground parameters, so it is not unreasonable that the same should apply to constructors. Another problem is what happens when specialized constructors are unied with values supplied at runtime to the residual program. This problem is similar to the problem of specialized constructors in input and output mentioned in section 7, and can indeed be solved in a similar fashion. At present (March 1993) I have no implementation of constructor specialization except for a prototype binding time analysis, so this is obviously the next step. When the basic method is implemented the renements mentioned in section 7 can be considered. It is possible that constructor specialization can be added to Similix's partially static data-type feature [Bon93]. I will discuss this with Anders Bondorf. References [BEJ88] [Bon91] [Bon93] D. Bjrner, A.P. Ershov, and N.D. Jones, editors. Partial Evaluation and Mixed Computation. Proceedings of the IFIP TC2 Workshop, Gammel Averns, Denmark, October Amsterdam: North-Holland, A. Bondorf. Compiling laziness by partial evaluation. In S.L. Peyton Jones, G. Hutton, and C. Kehler Holst, editors, Functional Programming, Glasgow 1990, pages 9{22, Berlin: Springer-Verlag, A. Bondorf. Similix Manual, System Version 5.0. Technical Report, DIKU, University of Copenhagen, Denmark, [Bul88] M.A. Bulyonkov. A theoretical approach to polyvariant mixed computation. In D. Bjrner, A.P. Ershov, and N.D. Jones, editors, Partial Evaluation and Mixed Computation, pages 51{ 64, Amsterdam: North-Holland, [DNBDV91] A. De Niel, E. Bevers, and K. De Vlaminck. Program bifurcation for a polymorphically typed functional language. In Partial Evaluation and Semantics-Based Program Manipulation, New Haven, Connecticut (Sigplan Notices, vol. 26, no. 9, September 1991), pages 142{153, New York: ACM, [GJ91] [GR92] C.K. Gomard and N.D. Jones. A partial evaluator for the untyped lambda-calculus. Journal of Functional Programming, 1(1):21{69, January M. Gengler and B. Rytz. A polyvariant binding time analysis handling partially known values. In M. Billaud et al., editors, WSA '92, Static Analysis, Bordeaux, France, September Bigre vols 81{82, 1992, pages 322{330, Rennes: IRISA, 1992.

11 [Hen91] [HH91] F. Henglein. Ecient type inference for higherorder binding-time analysis. In J. Hughes, editor, Functional Programming Languages and Computer Architecture, Cambridge, Massachusetts, August 1991 (Lecture Notes in Computer Science, vol. 523), pages 448{472, ACM, Berlin: Springer-Verlag, C.K. Holst and J. Hughes. Towards bindingtime improvement for free. In S.L. Peyton Jones, G. Hutton, and C. Kehler Holst, editors, Functional Programming, Glasgow 1990, pages 83{100, Berlin: Springer-Verlag, [HL91] C.K. Holst and J. Launchbury. Handwriting cogen to avoid problems with static typing. In Draft Proceedings, Fourth Annual Glasgow Workshop on Functional Programming, Skye, Scotland, pages 210{218, Glasgow University, [JSS85] [JSS89] N.D. Jones, P. Sestoft, and H. Sndergaard. An experiment in partial evaluation: the generation of a compiler generator. In J.-P. Jouannaud, editor, Rewriting Techniques and Applications, Dijon, France. (Lecture Notes in Computer Science, vol. 202), pages 124{140, Berlin: Springer-Verlag, N.D. Jones, P. Sestoft, and H. Sndergaard. Mix: a self-applicable partial evaluator for experiments in compiler generation. Lisp and Symbolic Computation, 2(1):9{50, [Lau89] J. Launchbury. Projection Factorisations in Partial Evaluation. PhD thesis, Department of Computing, University of Glasgow, November Revised version in [Lau91a]. [Lau91a] J. Launchbury. Projection Factorisations in Partial Evaluation. Cambridge: Cambridge University Press, [Lau91b] J. Launchbury. A strongly-typed selfapplicable partial evaluator. In J. Hughes, editor, Functional Programming Languages and Computer Architecture, Cambridge, Massachusetts, August 1991 (Lecture Notes in Computer Science, vol. 523), pages 145{164, ACM, Berlin: Springer-Verlag, [MB93] T. Mogensen and A. Bondorf. Logimix: a self-applicable partial evaluator for Prolog. In K.-K. Lau and T. Clement, editors, LOPSTR 92. Workshops in Computing, Berlin: Springer- Verlag, January [Mog88] T. Mogensen. Partially static structures in a self-applicable partial evaluator. In D. Bjrner, A.P. Ershov, and N.D. Jones, editors, Partial Evaluation and Mixed Computation, pages 325{347, Amsterdam: North-Holland, [Mog89] T. Mogensen. Binding time analysis for polymorphically typed higher order languages. In J. Diaz and F. Orejas, editors, TAPSOFT '89. [Mog92] Proc. Int. Conf. Theory and Practice of Software Development, Barcelona, Spain, March 1989 (Lecture Notes in Computer Science, vol. 352), pages 298{312, Berlin: Springer-Verlag, T. Mogensen. Self-applicable partial evaluation for pure lambda calculus. In Partial Evaluation and Semantics-Based Program Manipulation, San Francisco, California, June 1992 (Technical Report YALEU/DCS/RR-909), pages 116{ 121, New Haven, CT: Yale University, [Mos93] C. Mossin. Partial evaluation of general parsers. In PEPM '93: ACM Symposium on Partial Evaluation and Semantics-Based Program Manipulation, New York: ACM, [MTH90] R. Milner, M. Tofte, and R. Harper. The Definition of Standard ML. MIT Press, [Rom90] S.A. Romanenko. Arity raiser and its use in program specialization. In N. Jones, editor, ESOP '90. 3rd European Symposium on Programming, Copenhagen, Denmark, May 1990 (Lecture Notes in Computer Science, vol. 432), pages 341{360, Berlin: Springer-Verlag, [Ses86] P. Sestoft. The structure of a self-applicable partial evaluator. In H. Ganzinger and N.D. Jones, editors, Programs as Data Objects, Copenhagen, Denmark, 1985 (Lecture Notes in Computer Science, vol. 217), pages 236{256, Berlin: Springer-Verlag, 1986.

Information Processing Letters Vol. 30, No. 2, pp , January Acad. Andrei Ershov, ed. Partial Evaluation of Pattern Matching in Strings

Information Processing Letters Vol. 30, No. 2, pp , January Acad. Andrei Ershov, ed. Partial Evaluation of Pattern Matching in Strings Information Processing Letters Vol. 30, No. 2, pp. 79-86, January 1989 Acad. Andrei Ershov, ed. Partial Evaluation of Pattern Matching in Strings Charles Consel Olivier Danvy LITP DIKU { Computer Science

More information

which a value is evaluated. When parallelising a program, instances of this class need to be produced for all the program's types. The paper commented

which a value is evaluated. When parallelising a program, instances of this class need to be produced for all the program's types. The paper commented A Type-Sensitive Preprocessor For Haskell Noel Winstanley Department of Computer Science University of Glasgow September 4, 1997 Abstract This paper presents a preprocessor which generates code from type

More information

Thunks (continued) Olivier Danvy, John Hatcli. Department of Computing and Information Sciences. Kansas State University. Manhattan, Kansas 66506, USA

Thunks (continued) Olivier Danvy, John Hatcli. Department of Computing and Information Sciences. Kansas State University. Manhattan, Kansas 66506, USA Thunks (continued) Olivier Danvy, John Hatcli Department of Computing and Information Sciences Kansas State University Manhattan, Kansas 66506, USA e-mail: (danvy, hatcli)@cis.ksu.edu Abstract: Call-by-name

More information

Self-applicable Partial Evaluation for Pure Lambda Calculus

Self-applicable Partial Evaluation for Pure Lambda Calculus Self-applicable Partial Evaluation for Pure Lambda Calculus Torben Æ. Mogensen DIKU, University of Copenhagen, Denmark Abstract Partial evaluation of an applied lambda calculus was done some years ago

More information

Improving CPS-Based Partial Evaluation: Writing Cogen by Hand

Improving CPS-Based Partial Evaluation: Writing Cogen by Hand Improving CPS-Based Partial Evaluation: Writing Cogen by Hand Anders Bondorf DIKU Department of Computer Science Universitetsparken 1 DK-2100 Copenhagen, Denmark anders@diku.dk Dirk Dussart Departement

More information

University of Utrecht. 1992; Fokker, 1995), the use of monads to structure functional programs (Wadler,

University of Utrecht. 1992; Fokker, 1995), the use of monads to structure functional programs (Wadler, J. Functional Programming 1 (1): 1{000, January 1993 c 1993 Cambridge University Press 1 F U N C T I O N A L P E A R L S Monadic Parsing in Haskell Graham Hutton University of Nottingham Erik Meijer University

More information

interpreted program is type correct. However, if the interpreted program has already been type checked and it is known to be type correct so using the

interpreted program is type correct. However, if the interpreted program has already been type checked and it is known to be type correct so using the An exercise in dependent types: A well-typed interpreter Lennart Augustsson Magnus Carlsson Department of Computing Sciences Chalmers University of Technology S-412 96 G teborg, Sweden Email: {augustss,magnus}@cs.chalmers.se

More information

(Refer Slide Time: 4:00)

(Refer Slide Time: 4:00) Principles of Programming Languages Dr. S. Arun Kumar Department of Computer Science & Engineering Indian Institute of Technology, Delhi Lecture - 38 Meanings Let us look at abstracts namely functional

More information

the application rule M : x:a: B N : A M N : (x:a: B) N and the reduction rule (x: A: B) N! Bfx := Ng. Their algorithm is not fully satisfactory in the

the application rule M : x:a: B N : A M N : (x:a: B) N and the reduction rule (x: A: B) N! Bfx := Ng. Their algorithm is not fully satisfactory in the The Semi-Full Closure of Pure Type Systems? Gilles Barthe Institutionen for Datavetenskap, Chalmers Tekniska Hogskola, Goteborg, Sweden Departamento de Informatica, Universidade do Minho, Braga, Portugal

More information

Expressions that talk about themselves. Maarten Fokkinga, University of Twente, dept. INF, Version of May 6, 1994

Expressions that talk about themselves. Maarten Fokkinga, University of Twente, dept. INF, Version of May 6, 1994 Expressions that talk about themselves Maarten Fokkinga, University of Twente, dept. INF, fokkinga@cs.utwente.nl Version of May 6, 1994 Introduction Self-reference occurs frequently in theoretical investigations

More information

language (no restrictions due to self-application) the generator manipulates only syntax trees (no need to implement a self-interpreter) values in gen

language (no restrictions due to self-application) the generator manipulates only syntax trees (no need to implement a self-interpreter) values in gen Multi-Level Specialization (Extended Abstract) Robert Gluck 1 and Jesper Jrgensen 2 1 DIKU, Department of Computer Science, University of Copenhagen, Universitetsparken 1, DK-2100 Copenhagen, Denmark.

More information

Chalmers University of Technology. Without adding any primitives to the language, we dene a concurrency monad transformer

Chalmers University of Technology. Without adding any primitives to the language, we dene a concurrency monad transformer J. Functional Programming 1 (1): 1{000, January 1993 c 1993 Cambridge University Press 1 F U N C T I O N A L P E A R L S A Poor Man's Concurrency Monad Koen Claessen Chalmers University of Technology email:

More information

Demonstrating Lambda Calculus Reduction

Demonstrating Lambda Calculus Reduction Electronic Notes in Theoretical Computer Science 45 (2001) URL: http://www.elsevier.nl/locate/entcs/volume45.html 9 pages Demonstrating Lambda Calculus Reduction Peter Sestoft 1 Department of Mathematics

More information

1. true / false By a compiler we mean a program that translates to code that will run natively on some machine.

1. true / false By a compiler we mean a program that translates to code that will run natively on some machine. 1. true / false By a compiler we mean a program that translates to code that will run natively on some machine. 2. true / false ML can be compiled. 3. true / false FORTRAN can reasonably be considered

More information

An Efficient Staging Algorithm for Binding-Time Analysis

An Efficient Staging Algorithm for Binding-Time Analysis An Efficient Staging Algorithm for Binding-Time Analysis Takuma Murakami 1, Zhenjiang Hu 1,2, Kazuhiko Kakehi 1, and Masato Takeichi 1 1 Department of Mathematical Informatics, Graduate School of Information

More information

6.001 Notes: Section 8.1

6.001 Notes: Section 8.1 6.001 Notes: Section 8.1 Slide 8.1.1 In this lecture we are going to introduce a new data type, specifically to deal with symbols. This may sound a bit odd, but if you step back, you may realize that everything

More information

residual residual program final result

residual residual program final result C-Mix: Making Easily Maintainable C-Programs run FAST The C-Mix Group, DIKU, University of Copenhagen Abstract C-Mix is a tool based on state-of-the-art technology that solves the dilemma of whether to

More information

perform. If more storage is required, more can be added without having to modify the processor (provided that the extra memory is still addressable).

perform. If more storage is required, more can be added without having to modify the processor (provided that the extra memory is still addressable). How to Make Zuse's Z3 a Universal Computer Raul Rojas January 14, 1998 Abstract The computing machine Z3, built by Konrad Zuse between 1938 and 1941, could only execute xed sequences of oating-point arithmetical

More information

Logimix: A Self-Applicable Partial Evaluator for Prolog

Logimix: A Self-Applicable Partial Evaluator for Prolog Logimix: A Self-Applicable Partial Evaluator for Prolog Torben Æ. Mogensen DIKU, Department of Computer Science, University of Copenhagen Copenhagen, Denmark e-mail: torbenm@diku.dk Anders Bondorf DIKU,

More information

To figure this out we need a more precise understanding of how ML works

To figure this out we need a more precise understanding of how ML works Announcements: What are the following numbers: 74/2/70/17 (2:30,2:30,3:35,7:30) PS2 due Thursday 9/20 11:59PM Guest lecture on Tuesday 9/25 o No RDZ office hours next Friday, I am on travel A brief comment

More information

when a process of the form if be then p else q is executed and also when an output action is performed. 1. Unnecessary substitution: Let p = c!25 c?x:

when a process of the form if be then p else q is executed and also when an output action is performed. 1. Unnecessary substitution: Let p = c!25 c?x: URL: http://www.elsevier.nl/locate/entcs/volume27.html 7 pages Towards Veried Lazy Implementation of Concurrent Value-Passing Languages (Abstract) Anna Ingolfsdottir (annai@cs.auc.dk) BRICS, Dept. of Computer

More information

1.1 Limitations in Turner et al.'s analysis Turner et al.'s analysis can handle simple cases of zero usage by use of structural rules similar to those

1.1 Limitations in Turner et al.'s analysis Turner et al.'s analysis can handle simple cases of zero usage by use of structural rules similar to those Types for 0, 1 or many uses Torben. Mogensen DIKU Universitetsparken 1 DK-2100 Copenhagen O Denmark email: torbenm@diku.dk phone: (+45) 35321404 fax: (+45) 35321401 Abstract. This paper will present an

More information

The Essence of Compiling with Continuations

The Essence of Compiling with Continuations RETROSPECTIVE: The Essence of Compiling with Continuations Cormac Flanagan Amr Sabry Bruce F. Duba Matthias Felleisen Systems Research Center Compaq cormac.flanagan@compaq.com Dept. of Computer Science

More information

Typed Racket: Racket with Static Types

Typed Racket: Racket with Static Types Typed Racket: Racket with Static Types Version 5.0.2 Sam Tobin-Hochstadt November 6, 2010 Typed Racket is a family of languages, each of which enforce that programs written in the language obey a type

More information

CS 6110 S14 Lecture 1 Introduction 24 January 2014

CS 6110 S14 Lecture 1 Introduction 24 January 2014 CS 6110 S14 Lecture 1 Introduction 24 January 2014 1 Introduction What is a program? Is it just something that tells the computer what to do? Yes, but there is much more to it than that. The basic expressions

More information

Hutton, Graham and Bahr, Patrick (2016) Cutting out continuations. In: WadlerFest, April 2016, Edinburgh, Scotland.

Hutton, Graham and Bahr, Patrick (2016) Cutting out continuations. In: WadlerFest, April 2016, Edinburgh, Scotland. Hutton, Graham and Bahr, Patrick (2016) Cutting out continuations. In: WadlerFest, 11-12 April 2016, Edinburgh, Scotland. Access from the University of Nottingham repository: http://eprints.nottingham.ac.uk/32703/1/cutting.pdf

More information

An Approach to Polyvariant Binding Time Analysis for a Stack-Based Language

An Approach to Polyvariant Binding Time Analysis for a Stack-Based Language Supported by Russian Foundation for Basic Research project No. 06-01-00574-a and No. 08-07-00280-a, and Russian Federal Agency of Science and Innovation project No. 2007-4-1.4-18-02-064. An Approach to

More information

An Approach to Polyvariant Binding Time Analysis for a Stack-Based Language

An Approach to Polyvariant Binding Time Analysis for a Stack-Based Language An Approach to Polyvariant Binding Time Analysis for a Stack-Based Language Yuri A. Klimov Keldysh Institute of Applied Mathematics, Russian Academy of Sciences RU-125047 Moscow, Russia, yuklimov@keldysh.ru

More information

7. Introduction to Denotational Semantics. Oscar Nierstrasz

7. Introduction to Denotational Semantics. Oscar Nierstrasz 7. Introduction to Denotational Semantics Oscar Nierstrasz Roadmap > Syntax and Semantics > Semantics of Expressions > Semantics of Assignment > Other Issues References > D. A. Schmidt, Denotational Semantics,

More information

Parallel Rewriting of Graphs through the. Pullback Approach. Michel Bauderon 1. Laboratoire Bordelais de Recherche en Informatique

Parallel Rewriting of Graphs through the. Pullback Approach. Michel Bauderon 1. Laboratoire Bordelais de Recherche en Informatique URL: http://www.elsevier.nl/locate/entcs/volume.html 8 pages Parallel Rewriting of Graphs through the Pullback Approach Michel Bauderon Laboratoire Bordelais de Recherche en Informatique Universite Bordeaux

More information

Handout 10: Imperative programs and the Lambda Calculus

Handout 10: Imperative programs and the Lambda Calculus 06-02552 Princ of Progr Languages (and Extended ) The University of Birmingham Spring Semester 2016-17 School of Computer Science c Uday Reddy2016-17 Handout 10: Imperative programs and the Lambda Calculus

More information

CSCI-GA Scripting Languages

CSCI-GA Scripting Languages CSCI-GA.3033.003 Scripting Languages 12/02/2013 OCaml 1 Acknowledgement The material on these slides is based on notes provided by Dexter Kozen. 2 About OCaml A functional programming language All computation

More information

Extracting the Range of cps from Affine Typing

Extracting the Range of cps from Affine Typing Extracting the Range of cps from Affine Typing Extended Abstract Josh Berdine, Peter W. O Hearn Queen Mary, University of London {berdine, ohearn}@dcs.qmul.ac.uk Hayo Thielecke The University of Birmingham

More information

Conclusions and further reading

Conclusions and further reading Chapter 18 Conclusions and further reading We have not been exhaustive in the description of the Caml Light features. We only introduced general concepts in functional programming, and we have insisted

More information

Lecture 2 - Graph Theory Fundamentals - Reachability and Exploration 1

Lecture 2 - Graph Theory Fundamentals - Reachability and Exploration 1 CME 305: Discrete Mathematics and Algorithms Instructor: Professor Aaron Sidford (sidford@stanford.edu) January 11, 2018 Lecture 2 - Graph Theory Fundamentals - Reachability and Exploration 1 In this lecture

More information

Suppose a merchant wants to provide faster service to \big spenders" whose records indicate recent spending exceeding some threshold. Determining whet

Suppose a merchant wants to provide faster service to \big spenders whose records indicate recent spending exceeding some threshold. Determining whet Multi-Stage Specialization with Relative Binding Times Mark Leone Indiana University Peter Lee Carnegie Mellon University Technical Report #497 Computer Science Department, Indiana University November

More information

Once Upon a Polymorphic Type

Once Upon a Polymorphic Type Once Upon a Polymorphic Type Keith Wansbrough Computer Laboratory University of Cambridge kw217@cl.cam.ac.uk http://www.cl.cam.ac.uk/users/kw217/ Simon Peyton Jones Microsoft Research Cambridge 20 January,

More information

Programming Systems in Artificial Intelligence Functional Programming

Programming Systems in Artificial Intelligence Functional Programming Click to add Text Programming Systems in Artificial Intelligence Functional Programming Siegfried Nijssen 8/03/16 Discover thediscover world at the Leiden world University at Leiden University Overview

More information

Constrained Types and their Expressiveness

Constrained Types and their Expressiveness Constrained Types and their Expressiveness JENS PALSBERG Massachusetts Institute of Technology and SCOTT SMITH Johns Hopkins University A constrained type consists of both a standard type and a constraint

More information

proc {Produce State Out} local State2 Out2 in State2 = State + 1 Out = State Out2 {Produce State2 Out2}

proc {Produce State Out} local State2 Out2 in State2 = State + 1 Out = State Out2 {Produce State2 Out2} Laziness and Declarative Concurrency Raphael Collet Universite Catholique de Louvain, B-1348 Louvain-la-Neuve, Belgium raph@info.ucl.ac.be May 7, 2004 Abstract Concurrency and distribution in a programming

More information

A Small Interpreted Language

A Small Interpreted Language A Small Interpreted Language What would you need to build a small computing language based on mathematical principles? The language should be simple, Turing equivalent (i.e.: it can compute anything that

More information

Typed Scheme: Scheme with Static Types

Typed Scheme: Scheme with Static Types Typed Scheme: Scheme with Static Types Version 4.1.1 Sam Tobin-Hochstadt October 5, 2008 Typed Scheme is a Scheme-like language, with a type system that supports common Scheme programming idioms. Explicit

More information

Normalization Code in Standard ML. fun union n1 n2 = (* Make nodes `equal' *) let val (btl1,btl2) = (geteqr bt1,geteqr bt2)

Normalization Code in Standard ML. fun union n1 n2 = (* Make nodes `equal' *) let val (btl1,btl2) = (geteqr bt1,geteqr bt2) A Normalization Code in Standard ML The following Standard ML code can be used for solving constraint systems. The code assumes that phase 1 described earlier has been performed during constraint generation.

More information

Higher-Order Conditional Term Rewriting. In this paper, we extend the notions of rst-order conditional rewrite systems

Higher-Order Conditional Term Rewriting. In this paper, we extend the notions of rst-order conditional rewrite systems Higher-Order Conditional Term Rewriting in the L Logic Programming Language Preliminary Results Amy Felty AT&T Bell Laboratories 600 Mountain Avenue Murray Hill, NJ 07974 Abstract In this paper, we extend

More information

Lists. Michael P. Fourman. February 2, 2010

Lists. Michael P. Fourman. February 2, 2010 Lists Michael P. Fourman February 2, 2010 1 Introduction The list is a fundamental datatype in most functional languages. ML is no exception; list is a built-in ML type constructor. However, to introduce

More information

C311 Lab #3 Representation Independence: Representation Independent Interpreters

C311 Lab #3 Representation Independence: Representation Independent Interpreters C311 Lab #3 Representation Independence: Representation Independent Interpreters Will Byrd webyrd@indiana.edu February 5, 2005 (based on Professor Friedman s lecture on January 29, 2004) 1 Introduction

More information

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011 CS152: Programming Languages Lecture 11 STLC Extensions and Related Topics Dan Grossman Spring 2011 Review e ::= λx. e x e e c v ::= λx. e c τ ::= int τ τ Γ ::= Γ, x : τ (λx. e) v e[v/x] e 1 e 1 e 1 e

More information

The Typed Racket Guide

The Typed Racket Guide The Typed Racket Guide Version 5.3.6 Sam Tobin-Hochstadt and Vincent St-Amour August 9, 2013 Typed Racket is a family of languages, each of which enforce

More information

The design of a programming language for provably correct programs: success and failure

The design of a programming language for provably correct programs: success and failure The design of a programming language for provably correct programs: success and failure Don Sannella Laboratory for Foundations of Computer Science School of Informatics, University of Edinburgh http://homepages.inf.ed.ac.uk/dts

More information

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming Closures Mooly Sagiv Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming Summary 1. Predictive Parsing 2. Large Step Operational Semantics (Natural) 3. Small Step Operational Semantics

More information

The role of semantic analysis in a compiler

The role of semantic analysis in a compiler Semantic Analysis Outline The role of semantic analysis in a compiler A laundry list of tasks Scope Static vs. Dynamic scoping Implementation: symbol tables Types Static analyses that detect type errors

More information

Programming Languages Third Edition

Programming Languages Third Edition Programming Languages Third Edition Chapter 12 Formal Semantics Objectives Become familiar with a sample small language for the purpose of semantic specification Understand operational semantics Understand

More information

A Parallel Intermediate Representation based on. Lambda Expressions. Timothy A. Budd. Oregon State University. Corvallis, Oregon.

A Parallel Intermediate Representation based on. Lambda Expressions. Timothy A. Budd. Oregon State University. Corvallis, Oregon. A Parallel Intermediate Representation based on Lambda Expressions Timothy A. Budd Department of Computer Science Oregon State University Corvallis, Oregon 97331 budd@cs.orst.edu September 20, 1994 Abstract

More information

Semantic Analysis. Lecture 9. February 7, 2018

Semantic Analysis. Lecture 9. February 7, 2018 Semantic Analysis Lecture 9 February 7, 2018 Midterm 1 Compiler Stages 12 / 14 COOL Programming 10 / 12 Regular Languages 26 / 30 Context-free Languages 17 / 21 Parsing 20 / 23 Extra Credit 4 / 6 Average

More information

TYPE INFERENCE. François Pottier. The Programming Languages Mentoring ICFP August 30, 2015

TYPE INFERENCE. François Pottier. The Programming Languages Mentoring ICFP August 30, 2015 TYPE INFERENCE François Pottier The Programming Languages Mentoring Workshop @ ICFP August 30, 2015 What is type inference? What is the type of this OCaml function? let f verbose msg = if verbose then

More information

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes Chapter 13: Reference Why reference Typing Evaluation Store Typings Safety Notes References Computational Effects Also known as side effects. A function or expression is said to have a side effect if,

More information

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler so far

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler so far Outline Semantic Analysis The role of semantic analysis in a compiler A laundry list of tasks Scope Static vs. Dynamic scoping Implementation: symbol tables Types Statically vs. Dynamically typed languages

More information

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End Outline Semantic Analysis The role of semantic analysis in a compiler A laundry list of tasks Scope Static vs. Dynamic scoping Implementation: symbol tables Types Static analyses that detect type errors

More information

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics Recall Architecture of Compilers, Interpreters CMSC 330: Organization of Programming Languages Source Scanner Parser Static Analyzer Operational Semantics Intermediate Representation Front End Back End

More information

Operational Semantics

Operational Semantics 15-819K: Logic Programming Lecture 4 Operational Semantics Frank Pfenning September 7, 2006 In this lecture we begin in the quest to formally capture the operational semantics in order to prove properties

More information

SML Style Guide. Last Revised: 31st August 2011

SML Style Guide. Last Revised: 31st August 2011 SML Style Guide Last Revised: 31st August 2011 It is an old observation that the best writers sometimes disregard the rules of rhetoric. When they do so, however, the reader will usually find in the sentence

More information

Let us dene the basic notation and list some results. We will consider that stack eects (type signatures) form a polycyclic monoid (introduced in [NiP

Let us dene the basic notation and list some results. We will consider that stack eects (type signatures) form a polycyclic monoid (introduced in [NiP Validation of Stack Eects in Java Bytecode Jaanus Poial Institute of Computer Science University of Tartu, Estonia e-mail: jaanus@cs.ut.ee February 21, 1997 Abstract The Java language is widely used in

More information

6.001 Notes: Section 6.1

6.001 Notes: Section 6.1 6.001 Notes: Section 6.1 Slide 6.1.1 When we first starting talking about Scheme expressions, you may recall we said that (almost) every Scheme expression had three components, a syntax (legal ways of

More information

1 INTRODUCTION 2 Represent a multiset as an association list, where the rst argument of a pair is an item and the second argument is the multiplicity

1 INTRODUCTION 2 Represent a multiset as an association list, where the rst argument of a pair is an item and the second argument is the multiplicity Programming with Multisets J.W. Lloyd Department of Computer Science University of Bristol Bristol BS8 1UB, UK Abstract This paper proposes a novel way of introducing multisets into declarative programming

More information

Control Flow Analysis with SAT Solvers

Control Flow Analysis with SAT Solvers Control Flow Analysis with SAT Solvers Steven Lyde, Matthew Might University of Utah, Salt Lake City, Utah, USA Abstract. Control flow analyses statically determine the control flow of programs. This is

More information

A Boolean Expression. Reachability Analysis or Bisimulation. Equation Solver. Boolean. equations.

A Boolean Expression. Reachability Analysis or Bisimulation. Equation Solver. Boolean. equations. A Framework for Embedded Real-time System Design? Jin-Young Choi 1, Hee-Hwan Kwak 2, and Insup Lee 2 1 Department of Computer Science and Engineering, Korea Univerity choi@formal.korea.ac.kr 2 Department

More information

Introduction to Functional Programming: Lecture 7 2 Functions as innite data structures Ordinary ML data structures are always nite. We can, however,

Introduction to Functional Programming: Lecture 7 2 Functions as innite data structures Ordinary ML data structures are always nite. We can, however, Introduction to Functional Programming: Lecture 7 1 Introduction to Functional Programming John Harrison University of Cambridge Lecture 7 Innite data structures Topics covered: Functions as innite data

More information

(Refer Slide Time: 01:01)

(Refer Slide Time: 01:01) Principles of Programming Languages Dr. S. Arun Kumar Department of Computer Science & Engineering Indian Institute of Technology, Delhi Lecture - 32 Monomorphism Welcome to lecture 32. So today I will

More information

Lambda Calculus and Type Inference

Lambda Calculus and Type Inference Lambda Calculus and Type Inference Björn Lisper Dept. of Computer Science and Engineering Mälardalen University bjorn.lisper@mdh.se http://www.idt.mdh.se/ blr/ October 13, 2004 Lambda Calculus and Type

More information

Incremental Flow Analysis. Andreas Krall and Thomas Berger. Institut fur Computersprachen. Technische Universitat Wien. Argentinierstrae 8

Incremental Flow Analysis. Andreas Krall and Thomas Berger. Institut fur Computersprachen. Technische Universitat Wien. Argentinierstrae 8 Incremental Flow Analysis Andreas Krall and Thomas Berger Institut fur Computersprachen Technische Universitat Wien Argentinierstrae 8 A-1040 Wien fandi,tbg@mips.complang.tuwien.ac.at Abstract Abstract

More information

Data Abstraction. An Abstraction for Inductive Data Types. Philip W. L. Fong.

Data Abstraction. An Abstraction for Inductive Data Types. Philip W. L. Fong. Data Abstraction An Abstraction for Inductive Data Types Philip W. L. Fong pwlfong@cs.uregina.ca Department of Computer Science University of Regina Regina, Saskatchewan, Canada Introduction This lecture

More information

Induction and Semantics in Dafny

Induction and Semantics in Dafny 15-414 Lecture 11 1 Instructor: Matt Fredrikson Induction and Semantics in Dafny TA: Ryan Wagner Encoding the syntax of Imp Recall the abstract syntax of Imp: a AExp ::= n Z x Var a 1 + a 2 b BExp ::=

More information

CSE3322 Programming Languages and Implementation

CSE3322 Programming Languages and Implementation Monash University School of Computer Science & Software Engineering Sample Exam 2004 CSE3322 Programming Languages and Implementation Total Time Allowed: 3 Hours 1. Reading time is of 10 minutes duration.

More information

KeyNote: Trust Management for Public-Key. 180 Park Avenue. Florham Park, NJ USA.

KeyNote: Trust Management for Public-Key. 180 Park Avenue. Florham Park, NJ USA. KeyNote: Trust Management for Public-Key Infrastructures Matt Blaze 1 Joan Feigenbaum 1 Angelos D. Keromytis 2 1 AT&T Labs { Research 180 Park Avenue Florham Park, NJ 07932 USA fmab,jfg@research.att.com

More information

2 M. Sperber and P. Thiemann are traditionally implemented by recursive descent. The traditional model underlying LR parsing complicates understanding

2 M. Sperber and P. Thiemann are traditionally implemented by recursive descent. The traditional model underlying LR parsing complicates understanding Generation of LR Parsers by Partial Evaluation MICHAEL SPERBER Universitat Tubingen and PETER THIEMANN University of Nottingham Partial evaluation can turn a general parser into a parser generator. We

More information

More about Formatting. Olivier Danvy. Aarhus University. December Abstract

More about Formatting. Olivier Danvy. Aarhus University. December Abstract More about Formatting Olivier Danvy Computer Science Department Aarhus University (danvy@daimi.aau.dk) December 1993 Abstract This is an extension of the \format" example, in our POPL tutorial [2]. The

More information

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d) CMSC 330: Organization of Programming Languages Tail Calls A tail call is a function call that is the last thing a function does before it returns let add x y = x + y let f z = add z z (* tail call *)

More information

JOURNAL OF OBJECT TECHNOLOGY

JOURNAL OF OBJECT TECHNOLOGY JOURNAL OF OBJECT TECHNOLOGY Online at www.jot.fm. Published by ETH Zurich, Chair of Software Engineering JOT, 2002 Vol. 1, No. 2, July-August 2002 The Theory of Classification Part 2: The Scratch-Built

More information

Type Specialisation for Imperative Languages. 0. e 0 is the code part or dynamic part of the result of applying

Type Specialisation for Imperative Languages. 0. e 0 is the code part or dynamic part of the result of applying Type Specialisation for Imperative Languages Dirk Dussart John Hughes y Peter Thiemann z Abstract We extend type specialisation to a computational lambda calculus with rst-class references. The resulting

More information

SORT INFERENCE \coregular" signatures, they derive an algorithm for computing a most general typing for expressions e which is only slightly more comp

SORT INFERENCE \coregular signatures, they derive an algorithm for computing a most general typing for expressions e which is only slightly more comp Haskell Overloading is DEXPTIME{complete Helmut Seidl Fachbereich Informatik Universitat des Saarlandes Postfach 151150 D{66041 Saarbrucken Germany seidl@cs.uni-sb.de Febr., 1994 Keywords: Haskell type

More information

CS 11 Haskell track: lecture 1

CS 11 Haskell track: lecture 1 CS 11 Haskell track: lecture 1 This week: Introduction/motivation/pep talk Basics of Haskell Prerequisite Knowledge of basic functional programming e.g. Scheme, Ocaml, Erlang CS 1, CS 4 "permission of

More information

SAMOS: an Active Object{Oriented Database System. Stella Gatziu, Klaus R. Dittrich. Database Technology Research Group

SAMOS: an Active Object{Oriented Database System. Stella Gatziu, Klaus R. Dittrich. Database Technology Research Group SAMOS: an Active Object{Oriented Database System Stella Gatziu, Klaus R. Dittrich Database Technology Research Group Institut fur Informatik, Universitat Zurich fgatziu, dittrichg@ifi.unizh.ch to appear

More information

Proc. XVIII Conf. Latinoamericana de Informatica, PANEL'92, pages , August Timed automata have been proposed in [1, 8] to model nite-s

Proc. XVIII Conf. Latinoamericana de Informatica, PANEL'92, pages , August Timed automata have been proposed in [1, 8] to model nite-s Proc. XVIII Conf. Latinoamericana de Informatica, PANEL'92, pages 1243 1250, August 1992 1 Compiling Timed Algebras into Timed Automata Sergio Yovine VERIMAG Centre Equation, 2 Ave de Vignate, 38610 Gieres,

More information

A Functional Graph Library

A Functional Graph Library A Functional Graph Library Christian Doczkal Universität des Saarlandes Abstract. Algorithms on graphs are of great importance, both in teaching and in the implementation of specific problems. Martin Erwig

More information

Natural Semantics [14] within the Centaur system [6], and the Typol formalism [8] which provides us with executable specications. The outcome of such

Natural Semantics [14] within the Centaur system [6], and the Typol formalism [8] which provides us with executable specications. The outcome of such A Formal Executable Semantics for Java Isabelle Attali, Denis Caromel, Marjorie Russo INRIA Sophia Antipolis, CNRS - I3S - Univ. Nice Sophia Antipolis, BP 93, 06902 Sophia Antipolis Cedex - France tel:

More information

A Functional Evaluation Model

A Functional Evaluation Model A Functional Evaluation Model COS 326 Andrew W. Appel Princeton University slides copyright 2013-2015 David Walker and Andrew W. Appel A Functional Evaluation Model In order to be able to write a program,

More information

CS 360: Programming Languages Lecture 10: Introduction to Haskell

CS 360: Programming Languages Lecture 10: Introduction to Haskell CS 360: Programming Languages Lecture 10: Introduction to Haskell Geoffrey Mainland Drexel University Thursday, February 5, 2015 Adapted from Brent Yorgey s course Introduction to Haskell. Section 1 Administrivia

More information

Type and Eect Systems via Abstract Interpretation. Jer^ome Vouillon. Pierre Jouvelot. CRI, Ecole des Mines de Paris. Abstract

Type and Eect Systems via Abstract Interpretation. Jer^ome Vouillon. Pierre Jouvelot. CRI, Ecole des Mines de Paris. Abstract Type and Eect Systems via Abstract Interpretation Jer^ome Vouillon Pierre Jouvelot CRI, Ecole des Mines de Paris fvouillon, jouvelotg@cri.ensmp.fr July 12, 1995 Abstract Abstract interpretation and type

More information

Products and Records

Products and Records Products and Records Michael P. Fourman February 2, 2010 1 Simple structured types Tuples Given a value v 1 of type t 1 and a value v 2 of type t 2, we can form a pair, (v 1, v 2 ), containing these values.

More information

Compiler Theory. (Semantic Analysis and Run-Time Environments)

Compiler Theory. (Semantic Analysis and Run-Time Environments) Compiler Theory (Semantic Analysis and Run-Time Environments) 005 Semantic Actions A compiler must do more than recognise whether a sentence belongs to the language of a grammar it must do something useful

More information

CMSC330. Objects, Functional Programming, and lambda calculus

CMSC330. Objects, Functional Programming, and lambda calculus CMSC330 Objects, Functional Programming, and lambda calculus 1 OOP vs. FP Object-oriented programming (OOP) Computation as interactions between objects Objects encapsulate mutable data (state) Accessed

More information

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages Harvard School of Engineering and Applied Sciences CS 152: Programming Languages Lecture 18 Thursday, March 29, 2018 In abstract algebra, algebraic structures are defined by a set of elements and operations

More information

3. Functional Programming. Oscar Nierstrasz

3. Functional Programming. Oscar Nierstrasz 3. Functional Programming Oscar Nierstrasz Roadmap > Functional vs. Imperative Programming > Pattern Matching > Referential Transparency > Lazy Evaluation > Recursion > Higher Order and Curried Functions

More information

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between MITOCW Lecture 10A [MUSIC PLAYING] PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between all these high-level languages like Lisp and the query

More information

Data Types The ML Type System

Data Types The ML Type System 7 Data Types 7.2.4 The ML Type System The following is an ML version of the tail-recursive Fibonacci function introduced Fibonacci function in ML in Section 6.6.1: EXAMPLE 7.96 1. fun fib (n) = 2. let

More information

CS 415 Midterm Exam Spring 2002

CS 415 Midterm Exam Spring 2002 CS 415 Midterm Exam Spring 2002 Name KEY Email Address Student ID # Pledge: This exam is closed note, closed book. Good Luck! Score Fortran Algol 60 Compilation Names, Bindings, Scope Functional Programming

More information

Arbitrary-rank polymorphism in (GHC) Haskell

Arbitrary-rank polymorphism in (GHC) Haskell Arbitrary-rank polymorphism in (GHC) Haskell CAS 743 Stephen Forrest 20 March 2006 Damas-Milner Type System A Damas-Milner type system (also called Hindley-Milner) is a traditional type system for functional

More information

Lecture 3: Recursion; Structural Induction

Lecture 3: Recursion; Structural Induction 15-150 Lecture 3: Recursion; Structural Induction Lecture by Dan Licata January 24, 2012 Today, we are going to talk about one of the most important ideas in functional programming, structural recursion

More information

Comp 411 Principles of Programming Languages Lecture 3 Parsing. Corky Cartwright January 11, 2019

Comp 411 Principles of Programming Languages Lecture 3 Parsing. Corky Cartwright January 11, 2019 Comp 411 Principles of Programming Languages Lecture 3 Parsing Corky Cartwright January 11, 2019 Top Down Parsing What is a context-free grammar (CFG)? A recursive definition of a set of strings; it is

More information

Lecture Notes on Data Representation

Lecture Notes on Data Representation Lecture Notes on Data Representation 15-814: Types and Programming Languages Frank Pfenning Lecture 9 Tuesday, October 2, 2018 1 Introduction In this lecture we ll see our type system in action. In particular

More information