Procedural Programming. It's Back? It Never Went

Similar documents
Lowering the Level of

Old Is the New

Software. Is

Software. Is

It Is Possible to Do Object-Oriented Programming in Java

G Programming Languages - Fall 2012


Type Hierarchy. Comp-303 : Programming Techniques Lecture 9. Alexandre Denault Computer Science McGill University Winter 2004

Refactoring to

CS 211 Programming Practicum Spring 2018

Summer Final Exam Review Session August 5, 2009

About the Final. Saturday, 7-10pm in Science Center 101. Closed book, closed notes. Not on the final: graphics, file I/O, vim, unix

CS 211 Programming Practicum Fall 2018

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

list<t>::const_iterator it1 = lst.begin(); // points to first element list<t>::const_iterator it2 = lst.begin(); // points to second element it2++;

COMP-520 GoLite Tutorial

Designing Robust Classes

Name CPTR246 Spring '17 (100 total points) Exam 3

G Programming Languages - Fall 2012

Short Notes of CS201

Copyright 2008 CS655 System Modeling and Analysis. Korea Advanced Institute of Science and Technology

CS201 - Introduction to Programming Glossary By

Will the Real OO Please Stand Up?

Go Forth and Code. Jonathan Gertig. CSC 415: Programing Languages. Dr. Lyle

COMP 202 Java in one week

Chapter 2 - Control Structures

Lecture 22: Java. Overall Structure. Classes & Objects. Every statement must end with ';' Carl Kingsford, , Fall 2015

2. List Implementations (a) Class Templates (b) Contiguous (c) Simply Linked (d) Simply Linked with Position Pointer (e) Doubly Linked

CS-141 Final Exam Review December 16, 2015 Presented by the RIT Computer Science Community

G Programming Languages Spring 2010 Lecture 8. Robert Grimm, New York University

Programming Languages and Techniques (CIS120)

CS 211 Programming Practicum Spring 2017

Midterm I Exam Principles of Imperative Computation Frank Pfenning. February 17, 2011

Hardware versus software

Lecture 24 Notes Search in Graphs

CS-141 Final Exam Review December 8, 2017 Presented by the RIT Computer Science Community

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #06 Loops: Operators

The Spin Model Checker : Part I/II

Programming Language Concepts, cs2104 Lecture 04 ( )

PROCESS DEVELOPMENT METHODOLOGY The development process of an API fits the most fundamental iterative code development

A lot of people make repeated mistakes of not calling their functions and getting errors. Make sure you're calling your functions.

Object-Oriented Design Lecture 13 CSU 370 Fall 2008 (Pucella) Friday, Oct 31, 2008

Lecture Notes on Memory Layout

GNU ccscript Scripting Guide IV

CS 6353 Compiler Construction Project Assignments

MITOCW watch?v=0jljzrnhwoi

(Provisional) Lecture 08: List recursion and recursive diagrams 10:00 AM, Sep 22, 2017

CS201 Some Important Definitions

/633 Introduction to Algorithms Lecturer: Michael Dinitz Topic: Priority Queues / Heaps Date: 9/27/17

M/s. Managing distributed workloads. Language Reference Manual. Miranda Li (mjl2206) Benjamin Hanser (bwh2124) Mengdi Lin (ml3567)

Lecture 24 Search in Graphs

CS-141 Final Exam Review May 16, 2015 Presented by the RIT Computer Science Community

Today s lecture. CS 314 fall 01 C++ 1, page 1

Stacks, Queues (cont d)

Questions: ECE551 PRACTICE Final

Programming Languages. Function-Closure Idioms. Adapted from Dan Grossman's PL class, U. of Washington

Python for Non-programmers

Lecture Notes on Priority Queues

The Power of Abstraction. Barbara Liskov May 2013 MIT CSAIL

CSC 1351: Quiz 6: Sort and Search

3/7/2018. Sometimes, Knowing Which Thing is Enough. ECE 220: Computer Systems & Programming. Often Want to Group Data Together Conceptually

PROBLEM 1 : (Vocabulary: 8 points) For each of the words/phrases below, circle the denition that is the best description as it pertains in the context

Complexity, General. Standard approach: count the number of primitive operations executed.

SPIN, PETERSON AND BAKERY LOCKS

x = 3 * y + 1; // x becomes 3 * y + 1 a = b = 0; // multiple assignment: a and b both get the value 0

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

The Design Recipe Fall 2017

EMBEDDED SYSTEMS PROGRAMMING Language Basics

A Transactional Model and Platform for Designing and Implementing Reactive Systems

Lecture 21: Relational Programming II. November 15th, 2011

Introduction to the Stack. Stacks and Queues. Stack Operations. Stack illustrated. elements of the same type. Week 9. Gaddis: Chapter 18

Programming Languages and Techniques (CIS120)

Introduction to C# Applications

BASIC COMPUTATION. public static void main(string [] args) Fundamentals of Computer Science I

Stacks and queues (chapters 6.6, 15.1, 15.5)

Racket: Modules, Contracts, Languages

CIS 1.5 Course Objectives. a. Understand the concept of a program (i.e., a computer following a series of instructions)

The Lorax Programming Language

ENGI 1020 Introduction to Computer Programming J U L Y 5, R E Z A S H A H I D I

D7020E. The dynamic evolution of a system Robust and Energy-Efficient Real-Time Systems. blocked Lecture 2: Components & the Timber language.

D7020E. Robust and Energy-Efficient Real-Time Systems D7020E. Lecture 2: Components & the Timber language

CSE 143. Programming is... Principles of Programming and Software Engineering. The Software Lifecycle. Software Lifecycle in HW

l Determine if a number is odd or even l Determine if a number/character is in a range - 1 to 10 (inclusive) - between a and z (inclusive)

Python I. Some material adapted from Upenn cmpe391 slides and other sources

ENGR 102 Engineering Lab I - Computation

Figure 1. A breadth-first traversal.

CSCI-1200 Data Structures Spring 2018 Lecture 14 Associative Containers (Maps), Part 1 (and Problem Solving Too)

CS193k, Stanford Handout #8. Threads 3

Lecture 8: September 30

Assertion. C++ Object Oriented Programming Pei-yih Ting NTOU CS

\n is used in a string to indicate the newline character. An expression produces data. The simplest expression

17. Assertions. Outline. Built-in tests. Built-in tests 3/29/11. Jelle Slowack, Bart Smets, Glenn Van Loon, Tom Verheyen

(Refer Slide Time: 01.26)

17. Assertions. Jelle Slowack, Bart Smets, Glenn Van Loon, Tom Verheyen

Programming Abstractions

Priority Queues. 1 Introduction. 2 Naïve Implementations. CSci 335 Software Design and Analysis III Chapter 6 Priority Queues. Prof.

CSE143 Notes for Monday, 4/25/11

The P ower Power o f of A bstraction Abstraction Barbara Liskov October 2009

Testing and Debugging

QUIZ. 1. Explain the meaning of the angle brackets in the declaration of v below:

Transcription:

Procedural Programming It's Back? It Never Went Away @KevlinHenney

procedural?

µονόλιθος

µservices

µservices

This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Doug McIlroy

1960s

1960s

The design process is an iterative one. Andy Kinslow

There are two classes of system designers. The first, if given five problems will solve them one at a time. Andy Kinslow

The second will come back and announce that these aren t the real problems, and will eventually propose a solution to the single problem which underlies the original five. Andy Kinslow

This is the system type who is great during the initial stages of a design project. However, you had better get rid of him after the first six months if you want to get a working system. Andy Kinslow

A software system can best be designed if the testing is interlaced with the designing instead of being used after the design. Alan Perlis

proc is leap year = (int year) bool: skip;

proc is leap year = (int year) bool: false; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", void: (assert (not is leap year (1967)))) );

mode proposition = struct (string name, proc void test);

proc is leap year = (int year) bool: false; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", void: (assert (not is leap year (1967)))) ); test (leap year spec)

mode proposition = struct (string name, proc void test); proc test = ([] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); test of spec [entry]; print (new line) od;

proc is leap year = (int year) bool: year mod 4 = 0; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", void: (assert (not is leap year (1967)))), ("Years divisible by 4 but not by 100 are leap years", void: (assert (is leap year (1968)))) ); test (leap year spec)

proc is leap year = (int year) bool: year mod 4 = 0 and year mod 100 /= 0; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", void: (assert (not is leap year (1967)))), ("Years divisible by 4 but not by 100 are leap years", void: (assert (is leap year (1968)))), ("Years divisible by 100 but not by 400 are not leap years", void: (assert (not is leap year (1900)))) ); test (leap year spec)

proc is leap year = (int year) bool: year mod 4 = 0 and year mod 100 /= 0 or year mod 400 = 0; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", void: (assert (not is leap year (1967)))), ("Years divisible by 4 but not by 100 are leap years", void: (assert (is leap year (1968)))), ("Years divisible by 100 but not by 400 are not leap years", void: (assert (not is leap year (1900)))), ("Years divisible by 400 are leap years", void: (assert (is leap year (2000)))) ); test (leap year spec)

proc is leap year = (int year) bool: year mod 4 = 0 and year mod 100 /= 0 or year mod 400 = 0; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", with (2017, 2001, 1967, 1), expect (false)), ("Years divisible by 4 but not by 100 are leap years", with (2016, 1984, 1968, 4), expect (true)), ("Years divisible by 100 but not by 400 are not leap years", with (2100, 1900, 100), expect (false)), ("Years divisible by 400 are leap years", with (2000, 1600, 400), expect (true)) ); test (is leap year, leap year spec)

mode expect = bool; mode with = flex [1:0] int; mode proposition = struct (string name, with inputs, expect result);

proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); od; string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi)

proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); od; string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi)

proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); od; string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi)

proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); od; string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi)

proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); od; string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi)

proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); od; string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi)

proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); od; string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print ((report = "" (new line) (new line, report, new line)))

We instituted a rigorous regression test for all of the features of AWK. Any of the three of us who put in a new feature into the language [...], first had to write a test for the new feature. Alfred Aho http://www.computerworld.com.au/article/216844/a-z_programming_languages_awk/

There is no such question as testing things after the fact with simulation models, but that in effect the testing and the replacement of simulations with modules that are deeper and more detailed goes on with the simulation model controlling, as it were, the place and order in which these things are done. Alan Perlis

class Stack(capacity); integer capacity; begin ref(book) array books(1:capacity);... procedure Push(top);... procedure Pop;... boolean procedure IsEmpty;... boolean procedure IsFull;... integer procedure Depth;... ref(book) procedure Top;...... end;

goto

/ WordFriday

snowclone, noun clichéd wording used as a template, typically originating in a single quote e.g., "X considered harmful", "These aren't the Xs you're looking for", "X is the new Y", "It's X, but not as we know it", "No X left behind", "It's Xs all the way down", "All your X are belong to us"

A goto completely invalidates the high-level structure of the code. Taligent's Guide to Designing Programs

send(to, from, count) register short *to, *from; register count; { register n=(count+7)/8; switch(count%8){ case 0: do{ *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; }while(--n>0); } }

send(to, from, count) register short *to, *from; register count; { register n=(count+7)/8; switch(count%8){ case 0: do{ *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; }while(--n>0); } } I feel a combination of pride and revulsion at this discovery. Tom Duff

send(to, from, count) register short *to, *from; register count; { register n=(count+7)/8; switch(count%8){ case 0: do{ *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; }while(--n>0); } } Many people have said that the worst feature of C is that switches don't break automatically before each case label. This code forms some sort of argument in that debate, but I'm not sure whether it's for or against. Tom Duff

One of the most powerful mechanisms for program structuring [...] is the block and procedure concept. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"

sequence selection iteration

Main Program and Subroutine The goal is to decompose a program into smaller pieces to help achieve modifiability. A program is decomposed hierarchically. Len Bass, Paul Clements & Rick Kazman Software Architecture in Practice

main subroutine subroutine subroutine subroutine subroutine subroutine subroutine subroutine afferent branch transform branch efferent branch

There is typically a single thread of control and each component in the hierarchy gets this control (optionally along with some data) from its parent and passes it along to its children. Len Bass, Paul Clements & Rick Kazman Software Architecture in Practice

main subroutine subroutine subroutine subroutine subroutine subroutine subroutine subroutine afferent branch transform branch efferent branch

main procedure procedure procedure procedure procedure procedure procedure procedure afferent branch transform branch efferent branch

main function function function function function function function function afferent branch transform branch efferent branch

main function function function function function function function function

You cannot teach beginners top-down programming, because they don't know which end is up. C A R Hoare

Everything should be built top-down, except the first time. Alan Perlis

Hamlet: To be, or not to be, that is the question.

Ophelia: 'Tis in my memory locked, and you yourself shall keep the key of it.

Hamlet: Yea, from the table of my memory I'll wipe away all trivial fond records.

A procedure which is capable of giving rise to block instances which survive its call will be known as a class; and the instances will be known as objects of that class. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"

const newstack = () => { const items = [] return { depth: () => items.length, top: () => items[0], pop: () => { items.shift() }, push: newtop => { items.unshift(newtop) }, } }

const newstack = () => { const items = [] return { depth: () => items.length, top: () => items[items.length - 1], pop: () => { items.pop() }, push: newtop => { items.push(newtop) }, } }

Concatenation is an operation defined between two classes A and B, or a class A and a block C, and results in the formation of a new class or block. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"

Concatenation consists in a merging of the attributes of both components, and the composition of their actions. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"

const stackable = base => { const items = [] return Object.assign(base, { depth: () => items.length, top: () => items[items.length - 1], pop: () => { items.pop() }, push: newtop => { items.push(newtop) }, }) }

const newstack = () => stackable({})

const clearable = base => { return Object.assign(base, { clear: () => { while (base.depth()) base.pop() }, }) }

const newstack = () => clearable(stackable({}))

const newstack = () => compose(clearable, stackable)({}) const compose = (...funcs) => arg => funcs.reduceright( (composed, func) => func(composed), arg)

Concept Hierarchies The construction principle involved is best called abstraction; we concentrate on features common to many phenomena, and we abstract away features too far removed from the conceptual level at which we are working. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"

A type hierarchy is composed of subtypes and supertypes. The intuitive idea of a subtype is one whose objects provide all the behavior of objects of another type (the supertype) plus something extra. Barbara Liskov "Data Abstraction and Hierarchy"

What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T. Barbara Liskov "Data Abstraction and Hierarchy"

const nonduplicatetop = base => { const push = base.push return Object.assign(base, { push: newtop => { if (base.top()!== newtop) push(newtop) }, }) }

tests = {... "A non-empty stack becomes deeper by retaining a pushed item as its top": () => { const stack = newstack() }... }, stack.push("build Stuff") stack.push("2017") stack.push("2017") assert(stack.depth() === 3) assert(stack.top() === "2017")

const newstack = () => compose(clearable, stackable)({}) tests = {... "A non-empty stack becomes deeper by retaining a pushed item as its top": () => { const stack = newstack() }... }, stack.push("build Stuff") stack.push("2017") stack.push("2017") assert(stack.depth() === 3) assert(stack.top() === "2017")

const newstack = () => compose(nonduplicatetop, clearable, stackable)({}) tests = {... "A non-empty stack becomes deeper by retaining a pushed item as its top": () => { const stack = newstack() }... }, stack.push("build Stuff") stack.push("2017") stack.push("2017") assert(stack.depth() === 3) assert(stack.top() === "2017")

What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T. Barbara Liskov "Data Abstraction and Hierarchy"

The makefile language is similar to declarative programming. This class of language, in which necessary end conditions are described but the order in which actions are to be taken is not important, is sometimes confusing to programmers used to imperative programming. http://en.wikipedia.org/wiki/make_(software)

Unshared mutable data needs no synchronisation Unshared Mutable Shared mutable data needs synchronisation Shared Unshared immutable data needs no synchronisation Immutable Shared immutable data needs no synchronisation

Mutable The Synchronisation Quadrant Unshared mutable data needs no synchronisation Unshared Shared mutable data needs synchronisation Shared Unshared immutable data needs no synchronisation Immutable Shared immutable data needs no synchronisation

I've often joked that instead of picking up Dijkstra's cute acronym we should have called the basic synchronization object "the bottleneck". David Butenhof comp.programming.threads

N bounded buffered asynchronous

N = unbounded buffered asynchronous

future N = 1 bounded buffered asynchronous

N = 0 bounded unbuffered synchronous

I believe that the current state of the art of computer programming reflects inadequacies in our stock of paradigms, in our knowledge of existing paradigms, in the way we teach programming paradigms, and in the way our programming languages support, or fail to support, the paradigms of their user communities.