150 likes | 286 Views
This document provides an overview of programming languages, focusing on design, specification, and implementation aspects. Key readings include selected chapters from Gelernter and Jagannathan, as well as MIT Scheme documentation. The assignments involve tasks like converting lists to trees in Scheme and consolidating knowledge on FORTRAN's static structures. The material covers essential features of programming languages, including operator overloading, array dimensions, memory management, and advanced concepts like closures and dynamic storage. It serves as a crucial resource for understanding both traditional and modern programming paradigms.
E N D
Programming Languages:Design, Specification, and Implementation G22.2210-001 Rob Strom September 21, 2006
Administrative • Alternative mailing address for me: robstrom@us.ibm.com • Everyone should subscribe to the class mailing list: http://www.cs.nyu.edu/mailman/listinfo/g22_2110_001_fa06 • Readings: Remainder of chapter 3 of Gelernter and Jagannathan; chapter 7; MIT Scheme documentation • Gelernter textbook: we will notify about availability of photocopied notes • Homework due end of class 4 (Scheme): • Convert list of atoms to concrete tree according to the simple grammar • Convert concrete tree to abstract tree
Invariants 1 <= N BigA = max(A(1..1)) 1 <= N BIGA = A(1) 5 DO 20 I = 2, N 30 IF (BIGA-A(I)) 10,21,21 10 BIGA = A(I) 21 CONTINUE 20 CONTINUE PRINT … BigA = max(A(1..I-1)) I-1 <= N BigA = max(A(1..I-1)) I <= N BigA = max(A(1..I-1)) A(I) > BigA I <= N A(I) = max(1..I)) I <= N BigA = max(1..I)) I <= N BigA = max(A(1..I-1)) BigA >= A(I) I <= N BigA = max(1..I)) I <= N BigA = max(1..I-1)) I-1 <= N BigA = max(A(1..I-1)) I-1 <= N I > N BigA = max(A(1..N))
FORTRAN: Everything static • Dimensions of arrays (although not necessarily visible to subroutines) • Number of instances of storage blocks • All programs both static and global (except statement functions) • All I/O devices static and global
Introduces: Types with operator overloading Arrays Separate compilation 2 levels of name space: Global and Local Static name spaces Procedures and Functions: call by reference Specialized I/O Pragma (Frequency Statement) Differences w.r.t. modern languages: No Lexical level (tokens) No 1st class char/string No 1st class procedure No recursion No dynamic data No nesting No closures/objects Gotchas: Near unrestricted GOTO Name aliasing No checks for Type errors Overwriting constants Overwriting array bounds FORTRAN: Summary
Algol 60: Static and Runtime Naming; Scope PROCEDURE MAIN; … x := read(); BEGIN INTEGER ARRAY FOO[1:X]; … j := 20; blat(j, FOO(j)); … PROCEDURE blat(x,y); BEGIN x := 1000; y:= 1000 END … INTEGER PROCEDURE random; BEGIN OWN INTEGER seed; random := seed := some new value … END …
New features • Call by name • Dynamic array bounds • Recursive creation of local stack variables • Own variables • Nested declarations, scopes • Inner procedures
Call by name • Requires access to the caller’s environment from within the environment where the name is used • Equivalent to a “closure” with no parameters
Beyond: Algol 68; PL/I; C • Fully dynamic storage – e.g. PL/I’s storage classes: • STATIC – like FORTRAN (local & external) • AUTOMATIC – like Algol 60 non-own • CONTROLLED – dynamically allocated • X BASED(Y) – dynamically allocated with pointer • Exception checking and Exception Handlers
Memory Heap (PL/I) • DCL 1 ARecordTemplate BASED(P), • 2 AField FIXED, • 2 AnotherField FLOAT; • DCL Q Pointer; /* Untyped */ • ALLOCATE ARecordTemplate; • Q=P; • Q->AField = 2;
A: PROCEDURE (…) DCL X FIXED INIT(3); … AddX: PROCEDURE (Y) RETURNS(FIXED); DCL Y FIXED; RETURN(X+Y); END AddX; Z = AddX(5); CALL AFunc(AddX); … AFunc: PROCEDURE(F); DCL F ENTRY; DCL X FIXED INIT(4); DCL Z FIXED; … Z = F(5); … END AFunc; Closures (PL/I):
Closures • AddX is a closure, that is: • It is a function whose execution has access to an external environment (the variable X) • If invoked from AFunc, it uses: • AddX’s environment’s value of X (static binding) • Not the most recent value of X on the stack, the one defined inside AFunc (dynamic binding) • LISP was the earliest language to do closures, and it did them the other way (dynamic)
New things that can go wrong • Memory fills with unaccessible cells • Type-mismatches on references and entry variables • Dangling references via pointers • Dangling closures • For an amusing critique of C vs PL/I see: • http://www.uni-muenster.de/ZIV/Mitarbeiter/EberhardSturm/PL1andC.html
Scheme (define isort ( lambda (l) (letrec ( ; defines a list of bindings (here just 1) (insert ( ; inserts item x in sorted order to list l lambda (x l) (if (null? l) (list x) (if (<= x (car l)) (cons x l) (cons (car l) (insert x (cdr l)))) )))) ; the below is executed in the context of the bindings (if (null? l) nil (insert (car l) (isort (cdr l)))) ) ))
Essential features in Scheme • 1st class procedures • Dynamically created procedures • Based on lambda calculus over atoms and pairs; by convention, lists are pairs <head, rest> • Continuations • Automatic garbage collection • Applicative style: binding, no update, no side effects (but there are exceptions to this) • Static scoping, but no static typing! • Simple syntax • (afunction arg1 arg2 …) ; function application • Special forms, e.g. (if … )