Learniverse

Procedural Programming: Alive or Dead? - Kevlin Henney (ACCU 2018)

00:00

Good afternoon, so, apparently, they don't have any clip on Mike, so I'm left with the

00:15

problem of, yeah, okay, so I speak with Mike.

00:21

So, and both hands are taken, okay, this is going to be very strange, and apparently

00:27

there is a new device that they've got that tracks the camera, tracks you based

00:34

on a remote control.

00:35

We will be load testing this in the next 90 minutes.

00:38

Okay, so, procedural programming, this is one of those things, it kind of half came out of

00:49

a joke, the idea of doing a talk on procedural programming, because a few years ago I found myself

00:55

giving talks on, this is what we really meant by objects and, you know, this is

01:00

functional stuff and this is how to think about it and stuff like that, and then I ended

01:05

up with a very broad paradigms talk a couple of years ago, I started thinking, the one

01:13

thing that's not getting any love here is procedural programming, and a lot of people

01:18

go, oh, procedural, that's just another word for bad, yeah, and indeed for many people

01:24

that's how they think about it, so I want to try and reconstitute that, because we have

01:28

a very, yes, we do work with software and yes, it is all ones and zeros, but we do have

01:33

a very ones and zeros approach to looking at things, we say, oh, this is new paradigm,

01:37

it equals good, so when I use this word it is equivalent to good, and, you know, you pick

01:42

a decade, you substitute the appropriate thing, you expand whether it is objects, whether

01:46

it is agile, whether it is microservices, whatever, this is now equal to good and therefore

01:51

other thing is now equal to bad, yeah, okay, it's a nice simple way of trying to deal

01:56

with the universe, but the universe tends out to be a little more sophisticated, so let's

02:01

have a look at this, some people go, oh, it's back, no, you never went away, it's always

02:06

been there, so I want to reconstitute it and also take a little bit of a journey, now

02:11

we're going to start a journey here in Bristol, here we go, a photograph, why don't I take

02:16

this, that's a few months ago, just a quick question, who actually lives in Bristol,

02:23

oh, not bad, right, good, so obviously as denizens of Bristol, you'll know that the original

02:31

Saxon name was Bridgesto, and you think English spelling is bad now, okay, the CG is

02:39

sure, obviously, and obviously there was no standard orthography, so it's variously spelled

02:44

Bridgesto, Bridgesto, and all the rest of it, and so this means place of the bridge, so Bristol

02:50

Bridge is the bridge, the place of the bridge, over the river Avon, Avon is Welsh for

02:57

River, over the River River, you know, used a lot of just software people who had a hard

03:03

time with naming, so yeah, so this got variously shortened, and by around the 1200s, people

03:11

were pretty much calling it Bridgesto, or were they, they were if they weren't from round

03:17

here, they were calling it Bridgesto, but the Bristol dialect and accent has a habit of putting

03:25

an L on the end of everything, okay, so you know, if you're proper Bristolian, you don't

03:31

have good ideas, you have good ideals, so Bristol, Bristol got the same treatment, and

03:39

why am I telling you all of this, because when I was talking about this talk to Hubert

03:44

Matthews yesterday, he made the same observation, procedure, procedural, there you go, everyone

03:52

else, procedure programming, but here in Bristol we claimed it, okay, procedural, that's

03:57

how it, that's how we're calling it, okay, okay, so really the question is, why am I talking

04:03

about procedural, so when people want me to think of procedural, they think, oh, legacy,

04:10

they think monolithic coat, okay, this is what they're thinking, monolithic, one big stone,

04:18

one big sodding stone, and so, yeah, I took this picture just over a year ago on Valentine's

04:25

Day, that's how romantic my wife and I are, let's go see some really big old stones,

04:31

that's pretty cool, so we took the kids and they were impressed by the size of them, just

04:37

as you would be when you join a new company, you go in there and it's a case of like this

04:43

code base, this monolithic coat, what does it mean, how did they move these pieces of

04:51

code, what do they do, what is the significance we don't know, but every twice a year it

04:56

lines up and gives the right results, just, so, you know, so we're going to talk about stones,

05:03

this is what you want, this is my younger son, he did about seven years ago, he was five,

05:10

I love, it just arranged some stones, and this is what you want, you're thinking like

05:14

elegantly arranged, with intention, and a mild Japanese aesthetic of seaweed on the top,

05:20

and you know, this is how we want to think about it, but obviously this is not a new

05:25

idea, Doug McElroy pointed out in the 70s that this is the Unix philosophy, right programs

05:34

that do one thing well and do it well, right programs to work together, this is a kind

05:38

of an articulation, there's been mangled into various different forms, we talk about cohesion,

05:43

we talk about single responsibility principle, and we talk about these rather elegant little

05:48

stones, these days whenever I put that slide up, lots of people go, oh, you're talking

05:52

good aren't you, current word, for good microservices, so you're talking about microservices

05:57

and I always say, if that helps you, yes, I am, absolutely that's what I'm talking

06:01

about, no, I'm talking about something much bigger here, about sort of a sort of a principle

06:07

about how we structure things that is surprisingly old, and it dates back to procedural

06:14

programming, all this cohesion stuff, this is not an object oriented thing at all, it's

06:19

procedural programming, that's where the terminology comes from, as John Cook points out,

06:25

he says in McElroy's summary, the hard part is his second sentence, right programs

06:33

to work together, it's not really the do one thing well, although that does tend to

06:38

floor as a little bit, finding out what that one thing is is nontrivial, but this

06:44

is the hard bit, and unfortunately our languages are still not much better than they used

06:50

to be, they focus on the entity to be used for the composition, but the composition is

06:56

a little bit vague, it sort of sits in the background, and so what you end up with is this

07:01

kind of arrangement of stones, rather than that elegant arrangement, and this kind of allows

07:06

us to refer to Alan Perlis, one of his one of my favourite quotes on software architecture,

07:12

and the long run every program becomes Rococo, if you're not sure what Rococo is, it makes

07:16

Baroque look minimal, then rubble, now Alan Perlis was the recipient of the, he was the first

07:28

recipient of the Turing Award, which is kind of relevant, because that was the 1960s, and

07:33

that's where I want to take you back, we're going to go back to the 1960s, intentional

07:37

use, 1960s is a font that was used extensively, gives us a sense of the 1960s, gill

07:44

souls, although technically it's 1928, the font was created, but when people think

07:51

the 60s, there's this kind of tension, there's these two views of the 60s, there's this

07:56

one, there's this one, okay, and if we go back to the 1960s, there are a few things that

08:01

are still with us, okay, there's a clearly procedural program, there's the Rolling Stones,

08:08

there's the imminent threat of nuclear holocaust, which I think is nice, because growing

08:13

up during the Cold War, that's an experience that's very difficult to describe, I can now

08:18

pass that onto my children, so thanks, you know that kind of sense, and there's me, okay,

08:31

yeah, so I was around in the 60s, in fact I predated the following slide, 1968, soft

08:40

engineering, this actually, the original uses gill songs, by the way, but it was rendered

08:46

in Futura, so there's a slight typeface mistake when they transcribe it to PDF, if you

08:52

don't know, I do care about typefaces, this is important, because this, there's an awful

08:59

awful lot of stuff that happened in the 60s, which we are not very aware of, and there

09:04

are a number of things still with us, this term software engineering, a number of people

09:07

sort of blame this conference for propagating this term, actually the person we have to

09:12

thank, is this woman here, Margaret Hamilton, she went to work for NASA, she was at MIT and

09:17

she went to work for NASA early mid 60s, and was kind of responsible for the whole moon landing

09:25

thing at one level, because she wrote a nice little piece of fault tolerance software,

09:29

without which the moon landing would not have happened, and she said, I began to use the term

09:33

software engineering to distinguish it from hardware and other kinds of engineering, yet to treat

09:37

each type of engineering as part of the overall systems engineering process, now we have

09:42

a number of kind of spaceflight, that's her in a mock-up of the command module, the Apollo,

09:49

today is the 12th of April, which means it is the anniversary of Yuri Gagarin, his little

09:57

space hop in 1961, and also the launch of the first space shuttle in 1981, and this is 1968,

10:04

which was also the year of release of 2001, a space obviously, which also uses the Gil

10:07

Songs font by an amazing coincidence, and predates the lunar landing by one year, yet shows

10:11

a beautiful example of how one would land on the moon. However, you're here for the

10:17

software, aren't you? Disappointing. Okay, let's find out. Let's find out what they thought about

10:22

things like microservices back in 1968. This is from EE, David. Define a subset of the system,

10:28

which is small enough to bring to an operational state, then build on that subsystem. Now,

10:32

notice he's not just saying, build a small bit of the system, he's saying, bring to an operational state,

10:37

that was the thing that when I read the whole of the proceedings, and I've done this so you don't have to,

10:42

but it's a real eye opener. They weren't thinking what we think they were thinking. There was a

10:47

diversity of thought that it reflects, well, pretty much what we do now. We don't have one mindset

10:55

as to how we should develop software, and we see that that was also true 50 years ago.

11:00

But there's a very specific thing here, and of course the nature of the systems they were

11:04

talking about are quite different, and yet the conclusions and principles they were drawing.

11:08

The strategy requires the system be designed in modules, which can be realized tested and

11:13

modified independently apart from the conventions for inter-module communication. John Lakeos was

11:18

in here doing a talk about modules. I mean, I was in the room, but whatever he said,

11:22

I'm going to go back to the 1960s. That's where the term originates. I had originally thought that

11:27

the term was about 1970 onwards, but it was in current use in 1968. As indeed, we're phrases

11:33

like unit testing, middleware, and a number of other surprising phrases that you can find in

11:38

the document. Other wisdom, the design process is an iterative one from Andy Kinzler.

11:46

Yeah, a lot of people blame the software engineering conference for

11:51

ratifying the waterfall process, because it's filled with observations like this.

11:57

Kinzler was pretty sharp, actually. There's some other brilliant observations. There are two

12:02

classes, assistant designers. The first, if given five problems, will solve them one at a time.

12:07

The second, we'll come back and announce that these are the real problems. I'm going to eventually

12:11

propose a solution to the single problem which underlies the original five.

12:15

This is the system type. Who's great during the initial stages of a design project? However,

12:19

you'd better get rid of him after the first six months if you want to get a working system.

12:23

So it turns out, they had C++ programs in the 1960s as well. Who knew? So slightly more seriously,

12:34

back to Alan Pearlis. A software system can best be designed if the testing is interlaced

12:38

with the designing instead of being used after the design. Oh, man, this waterfall is too much for

12:42

me. Here, he's actually describing and we'll come back to an approach described by Brian Randall

12:50

of University of Newcastle. So what I'm going to do is I'm going to put together a little piece

12:56

of code. One of my favourite little coding artists determined when a year is a leap year,

13:03

and given that we're talking 1968, I'm going to do this in our 1968. And this is my copy of

13:09

the revised report, which was 1974. And again, glorious use of fontage. Everybody was

13:17

Helvetica back then. 1970s was the Helvetica era when it came to writing programming

13:23

language manuals. And a lot of people say, how got 68? Yeah, that's a language I've either

13:28

never heard of or certainly never used. It's the most influential language you've never heard of

13:32

or never used. If you ever wonder where certain keywords came from, this is where those

13:40

keywords came from. They didn't come from anywhere else. Everybody else was at that time happy

13:45

to go integer. But no, Algos 68 is just like, we don't have time for that.

13:53

Yeah. Everybody else is calling these things records, structs. This is a whole load of stuff

14:02

here, which is really rather surprising, long, short, all the rest of it. So, yeah, let's go

14:07

back to this. And so procedure is leap year. Yes, you could put spaces in your identifiers.

14:14

Those didn't count, so I could actually take those out. They were not significant.

14:19

There's an argument. There's bull. This is defined as procedure. The whole thing evaluates to false.

14:26

So this is kind of interesting. What I'm going to do here is I'm going to create a testing framework.

14:30

So we can explore the language a little bit and get a feeling for what procedural programming,

14:34

because Algos 68 was the quintessential procedural programming language. It was the epitome of

14:40

procedural programming. It took all of the experience up until that point to try and distill.

14:45

This is what procedural programming is. So it's worth finding out what it is before we dis it.

14:50

So what we've got here is an array of propositions. That's a type we'll define. We'll look at that.

14:54

Allepeus back. Yes, I am using BDD terminology. Years not divisible by four are not leap years.

14:59

No, I'm not using BDD terminology. Well, that should nonsense is nonsense. You shouldn't use it,

15:04

but if you feel that you should come and talk to me. Years not divisible by four are not leap years.

15:09

So I've got a statement there of a simple aspect that must pass.

15:15

Void assert, if you have one where assert comes from Algos 68, not is leap year 1967.

15:22

What is this thing here? It is an anonymous procedure.

15:28

If you like to call it a Lambda, let's go for it. So 1968, people got very excited when C++ got them

15:36

in 2011. Java programs got excited in 2014. JavaScript programs had no idea what they were doing

15:45

in the mid-90s, so they didn't even know to be excited. Let's go and have a look at the

15:55

types. No. Well, yeah, it turns out that Allepeus 68 reinvented a whole load of terminology. That

16:00

makes the report almost unreadable. It is just like, yeah, you see all of that computer science

16:07

terminology that people have been establishing. This is the 1960s. We're going to reinvent everything.

16:11

IO, no. We call it transport. Yeah, input output. Transport. It's kind of logical.

16:19

So we're not going to talk about types. We're going to talk about modes.

16:24

Proposition equals a struct. Oh, yeah, it had strings. So when people sort of lament

16:30

all procedural languages don't do string handling unless they're proper procedural languages.

16:34

Yeah, there you go. Strings, you can do plus to concatenate as well. We'll see that.

16:39

Take a pointer to a procedure. Oh, void. There we go. That returns void. It returns nothing

16:46

and takes nothing. And so we can see that back here. Now I'm going to run it. Nothing surprising

16:52

about that. Okay, now we're going to explore. This is how we would iterate through the proposition

16:58

array. I've got a for loop. There's nothing particularly exciting there.

17:04

And so we're now what we're going to do is we're going to test drive it. Yes, it uses single

17:09

equals for equality. And as you can see, single equals for definition. Just just avoid confusion.

17:15

Yeah. And so we're going to put this one here used by four, but not by 100 R leap years.

17:21

And so now this one's going to pass this. So we got that. So 1968. We're going to build that up

17:26

used by 100, but not by 400 and not leap years. So we build this up progressively.

17:31

And we've got a nice little definition there. Now the thing here is that you will notice that this

17:36

there's a lot of parentheses. Okay. It's just like, yeah, the influence of LISP was strong.

17:43

But also keyboards have not been standardized to the level that they are now.

17:48

Curly brackets, you know, where do you find those? If you want to recreate the 1960s experience,

17:55

go to Scandinavia. They still have no idea where the curly brackets are. You have to kind of

17:59

of like, you have to kind of spatically e-max mode to try and find them. So it's that kind of

18:05

notion like we're going to use parentheses for everything. So let's do something slightly different

18:12

here. I'm going to create a mini DSL. What I'm going to do is I'm going to data drive this

18:18

with multiple items of data. And I'm going to write an expectation in there.

18:22

A year is not a visit by four and not leap years. So it's like 2018, 2001, 1967, one,

18:27

expect false with 2016, 1984, 1968 and four expect true and so on. And there's a little more

18:36

here. I've got to create these types. We can see these helpful constructor type things.

18:42

And this is the test driver. It's a little more complex. But there are a few things I'd like to

18:45

walk you through. Just so we can kind of sense the history and a few changes that have happened

18:51

since then. Nothing too exciting here. Dot notation was not universally accepted at that point.

18:57

So of was used. And there's a sort of, it's quite nice. The name of spec entry rather than spec

19:03

entry dot name. Then we have here, we can see that initialization at declaration. Yep, no problem

19:10

with that. Very, very subtle though. Colon equals means assign, it means this is declared as a

19:18

variable. This one means this is const. So a very subtle distinction. Like I said, these are

19:28

our 68 programmers. We don't have time to spell integer. We don't have time to spell const.

19:32

Let alone const it. We will symbolize it by the absence of a colon at initialization.

19:38

Very subtle distinction. Not one I'm sad that we got rid of. Oh, yes, if you've ever wondered

19:45

where bash and ultimately born shell comes from. Steven born, who wrote the original born shell,

19:52

was very taken with our goal 68. So he wrote the whole of the born shell using our goal 68

20:01

like notation. He used macros to make his sea look like our goal 68. And it is that code base

20:07

inspired the international obfuscated sea coding contest. Because if you opened up a sea file,

20:14

you expected to see sea. You did not expect to see some perverse reinterpretation of our

20:20

goal 68. And he was very taken with it. So he was on the inside of the shell and on the outside.

20:27

So this is where all of this stuff came from. Then we've got this. What you see within this if

20:34

statement is that there is a declaration. And then there is a call. Recently C++ programs

20:40

got terribly excited by this feature. Oh, look, we're being really modern. Go programmers are going

20:45

around. Yeah, we've had that for a few years. I've got 68s in the corner going. Yeah.

20:53

Plus equals. If you ever wondered where that came from. Yeah. So if you really want to

20:58

understand C and C++ and all of those languages, it's worth looking at our goal 68. People ripped

21:04

off fairly shamelessly. Now, here's an interesting thing. This is procedural. It turns out that

21:13

our goal 68 viewed a viewed things in terms of expressions. It did not view them in terms of

21:20

statements. It was an expression oriented language. It basically said that all of these constructs,

21:26

you can use them anywhere. It's the language that inspired people to use terms like

21:30

or fog andality in language design. There's a sort of deep irony that people originally said,

21:35

our goal 68 is too big to be implemented. It's unimplemented. It's too large a language.

21:40

It's actually smaller than C. Yeah. Well, our expectations of what defines big of change. Quite

21:45

a lot. It's a tiny language by comparison to modern standards. But the point here is that there's no

21:51

separate construct for how do I do an if else on a for values. Every language that doesn't get this

21:59

right has to introduce an alternative notation or syntax. Whether it's the Elvis operator,

22:08

whether it is Python doesn't get this right either, it says, well, we recycle the key words,

22:13

but we'll have if and else and they will actually serve a different purpose in expression.

22:17

Our goal 68 said, yeah, one idea. The body of a procedure results in a value. That's why there's

22:23

no return statement. And this results in a value. However, those are our 68 programmers.

22:30

That's a lot to type, isn't it? They all provided alternative notation forms. Love it. Don't do

22:38

this. Okay. Of course, I am using a test-driven style to explore this. And that definitely wasn't

22:45

1960s. You had to wait for the 1970s for that. Alfred A. Ho talking about Ook, which is A. Ho,

22:51

Weinberger, Kernegan, one of my favorite little languages. We issued a rigorous regression test

22:58

for all the features of Ook, any of the three of us who put in a new feature into the language

23:01

first had to write a test for the new feature. So test-driven development, that's 1970s. So yeah,

23:07

I've really old. Much, much later than the 1960s. They had to do something. I mean,

23:13

haven't said, people were wearing flares and dancing to disco. So this was a good diversion.

23:18

Okay, now back to Alan Pearlis. Let's talk a little bit about the testing thing. There is no

23:21

such question as testing things after the fact with simulation models. But that in effect,

23:26

the testing and the replacement simulations with modules that are deeper and more detail goes

23:30

on with the simulation. What on earth are you talking about now? A design work progresses,

23:35

as design work progresses, this simulation will gradually evolve into the real system to have

23:39

Pinkerton. What they're doing is they are describing without realizing it mock objects.

23:43

Another great idea from the world of procedural programming.

23:47

Simulation is the design. Okay, it took a while to be rediscovered. So what is the organizing

23:54

discipline for the set of thoughts, the set of ideas, this unruly school of how do we build

24:00

systems? People came up with a name for it. It's called structured programming. And structured

24:05

programming. This book is a collection of essays from Ullie O'Handale. Let's get dice to

24:13

an attorney hall. It was published in 74, but actually the papers date from the late 60s onwards.

24:20

Now, when most people these days hear about structured programming,

24:26

their immediate response. In fact, not just these days, to be honest,

24:30

when I started programming professionally in the 1980s, people were going like,

24:33

oh, structured programming. You mean programming without go to? If it was utterly obsessed.

24:37

You know the way we oversimplify things, ones and zeroes. What structured programming about

24:41

is programming without go to? Yeah, not really. That's not what it's about. But nonetheless,

24:49

we are kind of charged with this excitement that we have this go-to statement considered harmful

24:57

1968. Wow, that was a hell of a year, wasn't it? 50 years ago, this year.

25:02

Etzka Dijkstra, go to statement considered harmful, published in communications to the

25:06

SCM. Now, this is interesting because this phrase, this is the first outing of this phrase,

25:15

something considered harmful. And basically, we've been copying it ever since. People have

25:19

used this. There's actually a term for this. I have a Facebook page, a word Friday,

25:29

where I explore an interesting word every Friday. And one of the ones I explored a few

25:34

years ago was SnowClone. Feel free to drop this into a conversation casually.

25:39

Clieshade wording used as a template, typically originating in a single quote. And, for example,

25:44

X considered harmful. These aren't the Xs you're looking for, Xs and UI. It's X, but not

25:49

as we know it. Now it's left behind. It's Xs all the way down. All your Xs are belong to us. So,

25:53

these are examples of SnowClones that people substitute. And that is the first outing of go-to

25:58

statement considered harmful, except for one small problem. It was not Dijkstra. Dijkstra gets

26:03

the credit to all the blame for the title. He didn't do it. This is his original pay. This is

26:08

original writing. The slightly more moderate, a case against the go-to statement. Go-to statement

26:14

considered harmful was put in by the editor. At the time was Nicholas Birth, who invented Pascal,

26:21

a modular two. We'll be coming back to them later. This is clickbait 1960 style. X considered harmful.

26:30

Go-to statement considered harmful. I'm making a moderate case, but it's been escalated. You'll

26:36

never believe what happened to the codebase when he used this go-to. It's just click-through,

26:40

click-through. I need to see the penguins, the cats, and the go-to's. What was my first,

26:49

okay, this is confession time, okay. So, I'm amongst friends and whoever's out in the internet.

26:59

I did program Fortran. That was one of my first job out of Unity. It did involve programming

27:10

Fortran. I got to see some code like this. I think it's really good that people should have

27:16

to look at this stuff until their eyes start melting because you don't really understand

27:22

why people got terribly upset and I've typed about the go-to until you see quality code written

27:26

as a go-to. So, here we go. This is how we do is leap year in Fortran 66 or Fortran 4. No,

27:34

they're equivalent. First of all, six characters, that's your law, okay. Six characters. Why would

27:41

anybody want any more letters for their names? Good grief, you know. Apparently, it's logical.

27:50

They don't have Booleans. They have Logicals. You have to declare everything. Otherwise, the

27:54

compile will come along and just make stuff up for you because by default, is leap will be an

28:00

integer because it begins with I. Yeah. The letters, anything beginning with letters I through N

28:06

was automatic in the integer. Everything else would be a real number. So, year would not be an

28:11

integer would be a real number. Hence, giving rise to the Fortran joke, God is real unless declared

28:16

otherwise. Whether you've spent time in a Fortran code base, you might become

28:24

atheist, okay. You know, you're definitely in a Nietzsche moment, they go, God is dead. Look at this

28:31

code, okay. So, this is how we do the leap year thing in Fortran. If Mod Year, Fortran equals zero, go

28:39

to 20. Oh, good grief, there we are, okay. Easily, we assign to the name of the function. Go to 10,

28:49

is leap false. Now, we return. Go to 20, okay. Right. Yeah. Easy. Now, the thing is that

28:55

Fortran program is love rituals. Pointless, utterly pointless rituals. So, often they say, oh, no,

29:01

no, no, we need to make this more symmetric. So, we'll put a return in there as well.

29:05

Even though you actually fall off. And this also gave rise to all kinds of wonderful myths. Certainly

29:09

present where I first worked. Oh, if you don't put a return on, some compilers don't do it. No,

29:17

they all do. Really, from 1957 onwards, they all did. This is a story you tell your children,

29:23

okay? Okay. You just scare them with that. No, really, they would be somewhat remiss if they

29:28

didn't actually realize, I've reached the end. What shall I do now? You laugh, yeah. Now, this is real.

29:42

It's because, I don't know, we're going to have a regular, because you've got to go there,

29:46

because otherwise you don't know that you've gone, you know, you can't guarantee the compilers

29:51

get it right twice. Good God. There you go. Go to. You can trust to go to. And sometimes, yes,

29:56

Jason. No, I haven't, but I think they're all cut from the same DNA ultimately.

30:07

But no, I haven't finished this yet. Oh, good God, no.

30:09

So I haven't finished. Continue is a no op. You think I'm kidding with this stuff. It's like,

30:28

look, look at all of this ritual. It's just like we've got this color. You must jump to a

30:32

no op statement and then you can return and then you end. Are we done yet? I mean, this is,

30:38

it's just, wow. It's kind of like watching the end of the Lord of the Rings, because you

30:43

know, you keep thinking that the return, the return, okay, it's going to finish now. I was going

30:47

to finish again. Oh, no, they're at the harbor. They're going to finish once more. Oh, no, there's still

30:51

more. Okay. So, yeah, this is what we had to put up with. Then 47 came along and

30:58

actually relievers from quite a lot of this. But I actually programmed in 47, extended

31:05

47, but we had to deal with code that was written like this. I will keep the names, even though

31:10

47 loosened up a bit. I will keep the names for, oh, my goodness. And if else, construct, wow,

31:18

this is revolutionary. Now, I just want to clarify why I'm doing this for you. What I want to

31:22

scare you with, this is why people hate the go-to. But also, this is for a lot of people what

31:28

they thought procedural programming was. It turns out that with any paradigm, any paradigms,

31:33

very broad landscape. You can't see one side of it from the other. If you're a fortune programmer,

31:39

you don't even know what our goal is. You might have heard of Agal 60. You certainly would have heard

31:44

of Agal 68. And so, therefore, for a lot of people, this came to be what procedural programming was.

31:50

We get the same problem now with object orientation. A lot of people think to create an object

31:55

or into program, you need to use singletons and manager objects, okay? No, that's the equivalent

32:00

of this stuff. That's the failure mode. That's not the sort of the exemplar. So,

32:09

we end up with this. Now, it's a really interesting thing going on here. And I'm going to put

32:14

indentation in. Most of us, the first company I worked out, were pretty good on indentation,

32:20

except for my boss. He didn't believe in it. I don't believe in Father Christmas,

32:26

but that does not have code-level consequences. He didn't believe in it. And I remember

32:32

indenting his code and discovering so many bugs. It was astonishing. We do this. We do this

32:39

because we are creatures. We are visual creatures. Ultimately, at one level, we can treat this as

32:44

a linear sequence of characters. But we are visual creatures. This is why we do things. We do

32:50

things to highlight the structure of code, the logical structure, okay? We see that there is branching

32:56

here. So, why do people get upset about all those violations of this stuff? It's actually a very

33:00

simple thing. A go-to completely invalidates the high level structure of the code, okay? It's

33:05

a challenging guy to designing programs. 1995, you can find a version of it online. It's a

33:10

little harsh in places, but on the whole, it's pretty good with this one. And it's a very accurate

33:15

observation. That's the problem. It just doesn't look like it. You can pair that. It's just like,

33:21

no, I don't see what's going on. Whereas in the previous example, you can see, you can kind of

33:25

of squinted it and get a sense of the shape of it. You can sense it's form. You also have a choice

33:30

of the level of interest that you wish to direct yourself to. Now, a lot of people go, oh, well,

33:34

you know, we don't use go-to in our code. Maybe you don't have it in your language. And then

33:40

sometimes people say, well, there are other things that are like go-to, but they're not spot go-to.

33:46

And when we talk about go-to, we talk about structure programming, people often talk about the

33:50

single entry single exit discipline. And people often spend their time focusing over multiple

33:56

exits, but they never focus on multiple entry points. And you might think, how do you know, how

34:00

do I do a multiple entry point? Like this. Duff's device, which is, well, I'm going to pick on what

34:11

Tom Duff said about this one. I feel a combination of pride and revulsion that it's discovery.

34:15

I mean, it's, it's loop unrolling. Don't do this. Your compiler does it way better than you.

34:24

But this is way, way, way back. You know, this is K&RC. And what we've got here is we are trying to do

34:31

basically copying a whole load of bytes. And it turns out that copying eight bytes at a time is

34:36

really rather convenient unless, unless the thing that you're passing in is not divisible by

34:42

eight. What do you do with that little rounded bit? Well, what you do is you jump in. A case is nothing

34:46

more than a glorified label. That's it. That's all it is. So it turns out that what we've got here

34:53

is effectively, if you've ever wondered watching, watching something like Star Trek, what happens

34:58

when you teleport into the middle of something? But this is what happens. What we've done is we've

35:02

taken a switch state and we've taken a do-while state and we've teleported them to the same location.

35:07

Okay, they are interlaced and interposed and weirdly bonded to one another. This is not the

35:13

kind of relationship you want your code to have. But nonetheless, this is how you do multiple entry

35:19

points. It's trivial and see. And as Duff notes, many people have said that the worst feature

35:26

of C is that switches don't break automatically before each case label. This code forms some sort

35:31

of argument in that debate, but I'm not sure whether it's for or against. Now, obviously, he's

35:38

focusing on break. And it's the uncommon use of break. Break is more often associated. Most of the

35:45

languages that people use in this room. Break is more often associated with breaking out of a loop.

35:51

Obviously, it doesn't have to be spelled break. Now, something interesting about this talk is I

35:56

have finished this talk so many times this week. Now, normally, I'm known for finishing at the

36:01

last minute, and I did, I was indeed editing slides at the end of the end of John Laker's talk.

36:07

But I finished it this morning as well. I finished it three times yesterday, twice the day before

36:11

and once the day before that. I have not finished a talk this many times for quite a while.

36:16

What I was doing in John's talk, apart from listening to John, 100% attention, undivided,

36:20

absolutely. We'll talk about concurrency later, was I polled yesterday. Somebody give me some

36:29

suggestions for other languages. I counted up the languages I've used in this talk. It was nine

36:32

yesterday. I came up with tenth, and I thought nobody was going to come up with anything. People

36:37

coming up with all kinds of ideas that didn't fit the procedural aspect of this talk.

36:43

Now, Price tweeted at me around lunchtime, and he made a suggestion. Plan Calcool, which is

36:56

a language that was never really implemented at the time. It's a procedural language, 1948,

37:00

developed by Conrad Sussa, who invented the first electromechanical computer.

37:06

The good fortune to me, when a Conrad Sussa's son's horse a few years ago. This was a notation

37:16

that he developed, only single letter variable names. For those of you who use home computers

37:20

in the 1980s, you should feel comfortable with this. But notice he had a two-dimensional approach.

37:25

It has been implemented. Some came up with a one-dimensional approach here. But notice the nesting,

37:31

my goodness, the nesting. This is what it's all about. This is structured programming.

37:36

This is a wild loop, W. It doesn't stand for a while, via the whole loop. Again, repeat.

37:43

This is a sort routine, odd, odd, and obviously sticking with German.

37:50

Oh, okay. That's the French. Fun. That's break. That's how you break out of a wild loop.

37:58

This is a conditional expression. That's the arrow. The other arrow is that's assignment.

38:05

That's a declaration up there. What's a Randell's talk? It's a declaration up there,

38:13

which basically says this takes a raise of M items and returns a raise of M items.

38:19

I've looked at the complexity of this. It looks like an ON squared, but hey, it's 1948.

38:24

I'm prepared to take bubble saw exchange saw whatever you're offering me, because this is really

38:28

cool, because he visualized programming. Literally, we talk about nesting. He's doing nesting.

38:34

This is a proper representation. It's a procedural programming language. It doesn't support

38:38

recursion, has no go-to. Everything is passed by value, including a raise. It's kind of cool.

38:46

I didn't think I was going to put it in, but I only had an hour to figure out what it meant.

38:51

It finds some good examples. Anyway, it seems to be with us. I don't have a

38:59

break, it's a bit of a pain. Continue. If you're using continue in your code, except for

39:03

Fortran where it means something completely different. If you're using continue in your code,

39:08

I have a very simple suggestion. If, try it, it's awesome. It's a great construct.

39:15

Then we get return. This is the issue. People refer to multiple return points. This is often

39:22

misunderstood. It's partly because we've ended up with return statements in most of the languages

39:27

that we use. Most of the perceived or imperative languages that we use that have two jobs. People

39:35

often have got so used to this that they don't even think about it. Fortran is one of the only

39:40

languages I know that actually separates the two jobs. There is return as control flow. I wish

39:46

to return from this procedure or function or subroutine. There is the value that is being returned.

39:54

These are two separate concepts. Most languages fail the single responsibility principle in their

39:59

design. Return does two things in those languages. Why is that important? It's important because

40:06

it helps you understand that the way to work out the number of return points is not to

40:12

grab the instances of return. This is a deep misunderstanding. Let's have a look at what's going on

40:17

here. This is groovy. I chose groovy because it has a return keyword. Here is how to calculate

40:24

elite, whether or not a year is elite, according to Gregorian calendar, or strictly speaking the

40:29

groovy calendar. I can get rid of return keyword. Now it's the last value. It yields the value

40:38

of the last expression. I can play as it were both sides of this and see what that looks like.

40:46

Here is another way of writing it. I run a number of workshops. Some people are happy with this

40:53

and some people are happy with this. I'm going to explore this because it's got things like if

41:00

and return of it and that's kind of the point of what I want to talk about. Here is one way of doing it

41:08

and here is another way of doing it. This one is surprisingly common. Only one of these is

41:17

qualifies as structured programming. Anybody want to guess? It's the one on the left. How can I

41:25

demonstrate this? First of all, let's just take away the returns. It's directly equivalent. There

41:31

is no difference. In other words, a tail return, you can eliminate the return. What I've done is I've got

41:38

rid of its return aspect and I've separated return from value yield. If I try and do the same thing

41:44

on the right, I can do it with the last one. There, we're relying very much on disrupt the control

41:50

flow. There's no disruption here. Although you might count here, there are four returns. We're

41:59

looking at the structured programming perspective. There's only one. On the other hand, over there,

42:04

we've got a whole bunch. Let's put that back in for consistency. There is this idea of emphasizing

42:11

and these days with folding editors and it makes it easier to emphasize this idea.

42:17

If you're looking at the form of the code, why do we indent this stuff? Why does it make it

42:21

visually easier? Because what I'm trying to do is tell you what's important and what's not. These

42:26

things are at the same level. Here we see the backbone, the spine, the shape of this thing. Over

42:35

here, we see a completely different story. If I fold this stuff away, I actually have no idea

42:39

what's going on here. Because if this does or does not return, obviously it's a single statement

42:44

and I can see what's going on. But with larger blocks and particularly folded away,

42:49

you have to, the only way you can understand all of this is to understand all of it.

42:54

In other words, the reason that structured programming makes cognitive sense is because you don't

42:59

have to know everything in order to understand the top level. What is going on here? I don't have to

43:04

know whether or not this has a return in it or not because it doesn't matter. On the right hand side,

43:10

I have to because it makes a difference. And the way that this is structured makes this look like a

43:14

series of guard clauses. People say, oh, I like the guard clause, idiom, I remember people telling you

43:21

that. It's like, yeah, but that's not a guard clause. Guard clause is, oh no, it's terrible, bad things

43:26

have happened. Get me out of here. Oh my goodness, the years divisible by 400, that's shocking.

43:30

Get me out of here. No, that's part of your job. It's a fundamental part of the definition.

43:35

There's nothing weird about it. So let's get rid of that nonsense. If you want to do

43:39

structured programming, this is how you do. Let's go back to our level 68. You have no choice.

43:44

There was no return. So the idea of single return point didn't make sense. It did have a go to,

43:49

though, just for those moments when you felt like going completely wild, you know, it kind of

43:54

constrained you and then said, yeah, go, let it go. And here's one of the other things. Sometimes

44:02

people say, oh, well, you know, it's a structured programming thing. We don't need that anymore, do we?

44:08

Could you go do some functional programming and then come back and tell me how you feel?

44:12

Because functional programming actually follows a very similar principle. So here's the Haskell.

44:17

And then here, indeed, is the Pascal, a game reminding us of the fact that here's a language

44:23

that did not have a return statement, but did have a way of binding a result. This is the thing

44:30

that people often miss. They forget the translation thing. The guideline multiple exit points

44:37

was related to languages like this, like Fortran, that had this concept. And then what they do is

44:43

they end up wrapping returns and counting. You've got more than one return there. Look at where

44:46

the returns are. It's a little bit like don't translate poetry literally from one language to

44:52

another. I mean, actually, no, do. It's very funny. Okay. But the point here is that the guideline

44:57

is clearly more sensitive to language than people have appreciated. So let's go back to structured

45:02

programming. What's the fundamental idea here? One of the most powerful mechanisms for program

45:09

structuring is the block and procedure concept. It is this idea of these are the things that we group.

45:14

We encapsulate things in chunks. And then we organize them with a very simple model of arrangement.

45:21

Organize them. We organize these blocks in sequence. We organize by selection. If

45:28

we're organized by iteration, while. And we can elaborate. We can have different kinds of selection,

45:35

pattern matching and all the rest of iteration for loops and so on. But these are the fundamental

45:40

constructs. And selection is the fundamental in the sense that this is the original use of the

45:45

semi-colon operator. Because it was and why old languages used to have as a separator. But we

45:51

invented up for consistency, having an as a terminator in most languages. Because what you're doing

45:56

is you're saying a semi-colon, b, do the statement a, compose in sequence with statement b.

46:01

And so you have this nice idea of sequence there. And the idea is you can build anything out of

46:06

this stuff. And there was even a way of describing this architecturally. Although for some reason,

46:14

the software architecture movement from Carnegie Mellon decided not to call it procedural

46:18

programming. They decided to call it main program and subroutine. Hence, names like Bristol and

46:25

the River Haven. Okay. What do you see before you? Well, that looks like a bridge. That looks like

46:30

a river. That's a main program. And it's got subroutines. What should we call this paradigm? Main

46:36

program and subroutine. Okay. And what is the goal of this paradigm? The goal is to decompose a

46:43

program into smaller pieces to help achieve modifiability. This is one of those. It's not content-free,

46:48

but it is, I'm not really aware of any paradigms that are not done as enterprise jokes or a

46:55

enterprise programming effect. I'm not really aware of any paradigms that do not have this as their

46:59

objective. You know? Hey, guess what? I'm going to teach you new paradigms. Oh, what can we do

47:05

with these new paradigms? Well, our goal is to not decompose a program. We're going to try and

47:11

keep it all in one big piece and really mess up your modifiability. No, all of them. They just

47:16

have different views. They take a different worldview. And the procedural worldview very much is

47:22

organized around as its name suggests, procedures. A program is decomposed hierarchy. Ah,

47:26

now we're getting something useful. This is constructive information. Okay. If I use a relational model,

47:33

that decomposes things. If I put it into third normal form, that is a discipline of decomposition

47:37

that is aimed at achieving modifiability. And that's really good, but it's not hierarchical. So here,

47:44

we're actually getting some useful information. And we end up with stuff that looks like this.

47:49

Okay. So here's our hierarchical view. And it turns out that there was actually a

47:56

a set of terminology that turns out quite useful. Afferent, transform and efferent branches.

48:03

This is the kind of terminology you use to alienate your colleagues or just sound smarter than them.

48:11

Afferent branched out with input, transformed out with process, efferent branched out without put.

48:16

You can see that this actually does solve a particular class of problems particularly well.

48:21

It doesn't necessarily solve event driven problems, but it does solve certain classes of problem

48:26

very well. We obviously have different terminology and different areas of interest. One of the

48:31

things we find is it's characterized in terms of a single thread of control. Each component in the

48:36

hierarchy gets this control, optioning with some data from its parent and passes it along to its

48:41

children. So it's a synchronous model. It's a stack oriented model. And here is how we think about it.

48:48

So therefore, the procedural worldview is very much that we organize the universe in terms of

48:56

a single goal and activity that can be decomposed progressively. Okay. And there is value in this.

49:05

But where do we get problems? Well, first of all, let's just start messing about with the names.

49:10

There you go. This procedure is the same thing. Functions. Interesting enough,

49:15

this is also the shape of many functional programs. It turns out that you can slide from one

49:22

paradigm into another by just tweaking the dials a little bit. It turns out that what distinguishes

49:31

at this level, functional programming from procedural programming is side effects. It is not

49:38

structure. It is not large-scale structure. Functional programming is often based on this idea of

49:43

decomposition. This top-down pull-out functions. And so there is also a bottom-up

49:48

composition approach, which I'm not covering here, which is different. But I'm not going to cover

49:52

that here. However, the world is not organized into trees. This is far too convenient. You find it

49:57

in books, but the real world looks messy. It has recursion and mixing of levels and so on,

50:05

which is by attorney hall to make the observation. You cannot teach beginners top-down programming

50:11

because they don't know which end is up. Back to Alan Pearlis. Everything should be built top-down

50:17

except the first time. Which I thought was a lovely way of looking at it, because what he's doing,

50:21

is he's saying top-down is a really good way of organizing your thoughts and presenting something.

50:28

That doesn't mean it's the same as the way that you built it. But when you come to describe it

50:33

to somebody else, you don't have to give them the same war stories. You can actually say,

50:37

rationally speaking in post hoc rationality, which programs are really good at.

50:43

Let's imagine that it's like this. But there's this idea of top-down is a great way of describing

50:48

not necessarily a great way of constructing. So that does leave us with a question of how do we

50:52

construct. Was this the only thing that was going on in the procedural space? Well, no,

50:57

come in 1972, we have a whole load of discussion on the criteria to be used in decomposing a

51:02

system into modules. David Parnas really with one of those classic computer science papers

51:07

and computer science titles. These days, nobody publishes papers with these kinds of titles.

51:12

It's much more modules distilled, modules in five minutes, whatever it is.

51:18

You won't believe what happened to these modules when we decompose them using these criteria.

51:21

That kind of thing. What we're looking at here, we've posed the one

51:27

begins with a list of difficult design decisions or decisions which are likely to change

51:31

immediately embracing this idea of you cannot know everything in advance.

51:35

Let us try and embrace the volatility and try and contain it a bit. You know, hug it a little

51:39

bit closer to you. Each module is then designed to hide such a decision from the others.

51:44

And one of the most common ones, we're going to characterize Barbara Liskoff.

51:50

She was awarded the chairing award in 2009, maybe 2008. A lot of people know Barbara Liskoff

51:59

for the Liskoff substitution principle. That's her. But actually, the reason that came about

52:06

was because of her work with abstract data types. It was nothing to do with object orientation.

52:09

She also did some really good work on distributed systems. But she notes here,

52:14

earlier 70s, abstract data types defines a class of abstract objects which is completely

52:18

characterized by the operations available in those objects. A program is concerned only with

52:22

the behavior which that object exhibits but not with any details of how that behavior is achieved

52:27

by any means of implementation. So, everybody likes to use stacks. So, I'll use a stack of books

52:33

here. Stacker books about objects as it happens. And I was molly over, yeah. Let's try another

52:42

language. What language? It's really modular. Oh, I know. Modular. Modular too, in fact.

52:50

Which is actually a really, it's kind of the forgotten cousin of Pascal, better designed in many

52:56

senses. Very strong on modularity as one would hope from a language that's called modular.

53:04

Has a proper idea of modules? Separate, has the idea of modules separated into two parts.

53:08

Or there are three kinds of modules. There's the main module. There's a definition module,

53:12

which is an interface. And there is an implementation module which fulfills that. I think it's kind of

53:18

nice that languages like C++ have decided a few decades later that this is a really new and

53:23

interesting idea. And also, he had a very simple, occasionally people wonder about, should I put

53:31

things in up a case? And Nicholas Burt decided, you know what? Up a case for keywords. If you're

53:37

going to shout something, you might as well shout something that is the core language. Everything else

53:40

you whisper. So, here's a definition module. Here is an example of an abstract data type.

53:47

I have simply forward declared stack. There's nothing in the definition that tells you what it

53:51

looks like on the inside. On the implementation, this is going to be a pointer to something. But

53:55

out here, there's no indication. So, I can define, compile, use, and all the rest of it, and link

54:01

the whole system without any kind of interruption. I'm going to create, I'm going to be able to

54:05

create these, delete these, push, pop, find the depth, get the top. I've used, I've used self

54:12

here. That's more of a modular three convention. Just to make you feel comfortable and see

54:20

a ray of char. Yes, it's null terminated. That's a string. So, you have this very simple idea.

54:27

And it's a ruthlessly procedural language to the point of tedium in some places. I must confess,

54:31

but it's some really nice ideas. So, let's switch that to something that some people will be

54:36

more familiar with. Let's, we can do this in C. C has no proper module concept. In other words,

54:43

it doesn't have a name that, you know, if you have in, if you look at Python,

54:50

Python's modules are very similar in vision to modular twos in the sense of the,

54:56

you import everything using import, and you have to namespace qualify, stacks.new, stacks.delete,

55:03

or you can import from, or rather from, stacks import specific names. But here we are in C,

55:09

and I've got a way of kind of structuring this and, because I'm writing clean C, it should be

55:13

accessible to C++ programs. And I've got a choice about how I implement this. So, here's one

55:19

implementation. Hopefully, that's a font that you can read and examine, and yeah, good, yes, good,

55:24

excellent. And here's another implementation. Now, what's the difference between these? Well,

55:28

this one is C, this one is C++. They are linked on compatible, and that's a sort of good example

55:34

how we have the separation. This is what we mean. We don't mean a private section that you then

55:39

touch and everything rebuilds. That was a misunderstanding. The abstract data types really were very

55:44

much, and modules were very much link time substitution. This is what it's all about. So, I can

55:51

switch implementations easily. Now, of course, because we're talking about C and C++,

55:55

this does give us the question of memory management. And I did a lightning tool last year about

56:04

how Shakespeare was a programmer, and as it happens, my oldest son went to see a film production of

56:13

Best Last Night for his GCSE. I'm not going to focus on with Best. It's kind of like, yeah, it's

56:19

all deadly and stuff like that. Now, we're going to go for different kind of deaths. We're going to go

56:24

for Hamlet. So, what was Hamlet all about? Hamlet was all about memory management. The whole play.

56:35

Four hundred years ago, so Shakespeare did not have available the facilities we have for

56:42

exploring programs. So, the best he could do was use an actor-based model.

56:46

And here, he's exploring creation and not. And this is a question. And again,

56:55

people's influences in terms of their background. If you come through a C background,

57:01

again, people often go, they go on C and then they've ended up in Ruby. They've got C++,

57:05

and they ended up in Ruby. Then they're going to walk away thinking our procedural

57:10

languages or language with the strong procedural history. That means we're signing with a

57:17

failure on this one. Because a failure, a failure was quite keen on explicit memory management.

57:24

Just in my memory, locked in you yourself should keep the key of it, which is basically,

57:28

you mallet, you free. You did, and you, you do a delete. So, a lot of people think, oh,

57:35

okay, procedural languages, they're all like this. There's Hamlets, you know, garbage collection,

57:40

man, from the table of my memory, I'll wipe away all trivial phone records. Okay, that's what

57:44

the whole play is about. I'm sure I've convinced you in three quotes. However, history doesn't look

57:52

like that. Well, I'm not talking about my retcon of Shakespeare into the canon. Let's understand a

57:58

little bit more about what's going on here. Because I want to talk about a couple of other languages,

58:03

we'll bring in the garbage collection. Oh, actually, I can bring in the garbage collection already.

58:07

We've already seen Algos 68, hand garbage collection. So that would be 68. So in other words,

58:13

people say, oh, well, this pad garbage collection, yeah, but that's a different paradigm. Algos

58:18

had garbage collection, Algos 68. So let's look at it from a different point of view.

58:24

Earlier, Handal, Antonio Hall, earlier Handal, he was the guy, he wanted the guys, him and Kristen

58:33

Neegard, who basically came up with Simula, Simula 67. Again, the clues and the clue to the years

58:39

in the name. First object oriented language, and it was very influential. It was an extension

58:44

of Algos 60. And it too had garbage collection. So Simula 67, that's for object oriented stuff, isn't it?

58:55

Oh, that's completely different paradigm. Wait a minute, it's in the book. This is where I got

58:59

that quote from, hierarchical program structures. It turns out that the view, the view from back then

59:08

was that all of this stuff, this organizing around data types, this object orientation,

59:16

was part of structured programming. Because it's not unstructured. They called it structured for

59:21

a reason. It poses structure on your ones and zeros, your disorder, your fortune or whatever.

59:26

It's a discipline. The problem is that people only remember the control flow, because that's

59:30

what they were battling with on a day-to-day level. But also, because that was the easiest thing

59:36

to translate those languages. If you're working in Kobo, or you're working in Fortran,

59:40

or you're working in Basic, or any of these languages, this is the hardest part of the book to apply.

59:46

Not that people use this as a book, but certainly it was the last section. A lot of people

59:49

are, yeah, I don't know what, I don't understand that. All the stuff on control flow, that's much

59:55

more important. That's how we get obsessed with it. If we look here and we organize our books

01:00:01

accordingly as a block, here's a reference. An array of books, it's a reference. It's going to hold

01:00:09

references of books up to some given capacity. Count is how many we're going to track. We're going to

01:00:16

initialize that to zero. We can also nest our procedures inside our blocks. It's a proper block

01:00:22

structured language. We've got these features. That's pretty cool. But why am I showing you this?

01:00:29

We've already seen blocks and stuff. The only thing interesting here is the word procedure.

01:00:35

This is the bit that's interesting. A procedure which is capable of giving rise to block instances

01:00:39

which survive its call will be known as a class, and the instances will be known as objects

01:00:43

of that class. We take that, we add that, boom, that's how classes are invented. That's where

01:00:48

they come from. They are just blocks that happen to live a little bit longer. They don't follow a

01:00:53

stack discipline, although it is a stack. They don't follow a stack discipline. It's just like

01:00:56

here's a block, it's got data inside it, your variables, it's got procedures, and then you can return

01:01:01

the whole block. It will live longer than just your call stack. That's the whole concept. In other

01:01:07

words, objects are apart, they are an extension of the procedure model. They are part of the

01:01:11

procedure model. That's why they were included in this book. We can actually take this idea much

01:01:17

more literally because I'm sensitive to the varied age of people in the room. Here's some

01:01:23

JavaScript. I like the fact that most people who were programming JavaScript wouldn't

01:01:31

actually born after it was invented. Do I like that? No, it intrigues me. I've got a stack here. This

01:01:39

idea of let's do this without classes. Let's understand the raw materials, a block of stuff with

01:01:48

names that are bound to procedural or functional elements. I've got a function here called new stack.

01:01:54

It takes no arguments and it returns a bunch of operations in a table effectively against some

01:02:04

data that is truly private. It doesn't need the private keyword. It's so private you can't even

01:02:08

see it from outside. It's hidden inside a block. That's how private it is. We've got that. We can,

01:02:14

that's an implementation. We can change our implementation and nobody outside is any of the wiser,

01:02:20

so fully encapsulated. Then let's explore something else that was part of this paradigm.

01:02:27

Catination is an operation defined between two classes, A and B, or a class A and a block B,

01:02:33

or a block C, and results in the formation of a new class or block. These days we call that

01:02:39

inheritance. Notice this was so generalized you can actually have a block inherit from a class,

01:02:45

just a block of code. concatenation consists of merging of the attributes of both components

01:02:51

and the composition of their actions. Let's try that with this, but I'm going to do an object

01:02:55

level rather than a class level. What I'm going to do is rather than thinking in terms of stacks,

01:02:59

I'm going to say stackability is a property. Then you can pass in a base and then what you'll

01:03:04

do is you can then take whatever the base had and then add in these extra features, which will

01:03:11

also have the effect of overriding things. Now a new stack is a stackable of something

01:03:18

simply that is empty. It has nothing else. It's just purely stackable. That's quite nice.

01:03:23

Then we can reinvent what's known as a mix-in model. We can have something that is

01:03:27

clearable. Take the base, add in other things. Now I can have a new stack that is clearable

01:03:34

and stackable. It's a very simple composition model and I can actually linearize that,

01:03:40

make that a little simpler and do all this kind of nonsense. How would we use such a thing?

01:03:46

Well, here's the advice. You create a hierarchy of concepts. Do not be distracted by

01:03:53

concepts in C++. C++ committee has spent a decade and a half being distracted by them.

01:03:59

Fine work. I wasn't originally convinced by the idea of putting Haskell into the compile time,

01:04:04

but there's some interesting ideas there. Finally, I think it's time has come.

01:04:10

Yeah, I know. Shoot me afterwards. The construction principle involved is best called abstraction.

01:04:15

Wow, that's a radical idea. We concentrate on features common to many phenomena. We abstract

01:04:20

away features too far a move from the conceptual level at which we are working. Interesting.

01:04:25

I wonder if that'll catch on. So I'll risk off. What does she have to say? Well, here I'm going

01:04:33

to project you way forward into the 1980s. Let's talk about the list of substitution principle.

01:04:38

A type hierarchy is composed of subtypes, supertypes. The intuitive idea of a subtype is one

01:04:42

whose objects provide all the behavior of objects of another type, the supertype plus something extra.

01:04:47

Okay. And then she gives us a more formal definition. If for each object,

01:04:52

oh, one of type S1 there is there, etc., etc., such that for all programs P, they are like,

01:04:56

okay, great. How can we demonstrate this? Well, let's let's throw in an additional feature,

01:05:01

an additional mix in. I have a non-duplicate top. The idea is that if you try and push something,

01:05:10

if you try and push something onto a stack and it's already on the top, then we're going to ignore it.

01:05:15

Okay. Right. So now what I'm going to do here is I'm going to create a set of tests

01:05:21

and just I'm going to use an object or basically a dictionary. A name and then a lambda, a block,

01:05:28

an anonymous procedure. We can call it what we like. We're going to create a new stack and we're

01:05:33

going to push. ACCU push 2018, push 2018. The depth should be three. If you're not familiar with

01:05:40

JavaScript, you really, really have to want equality. Okay. It's hard enough in the real world

01:05:45

but Dan, you've got a political fight on your hands and code. How do you know two things are really

01:05:50

equal? Just keep your finger down on the equals key. It'll eventually be right.

01:05:56

So the depth should be three and the top one should be 2018. Okay. Right. So when we run this

01:06:00

against our composition of a clearable stackable, then it passes. It's green. But when we

01:06:06

combine it with non-duplicate and non-duplicate top, then it fails. The depth is no longer three,

01:06:12

because we are ignoring non-duplicate tops. In other words, risk or substitution principle is

01:06:16

something you can demonstrate through tests. It's a trivial thing. It's not a type theory thing. You

01:06:19

can actually walk tests through. You can actually say this test failed because of a violation of

01:06:24

risk or substitution principle. It's not something fluffy like single responsibility principle.

01:06:28

Although you can use code analytics to try and get a handle on that. It's not completely

01:06:33

incorrect like the open close principle. So this is actually something that is much more tangible

01:06:40

and identifiable and gets us focused on the important aspect here. Now here's an interesting thought.

01:06:49

One of the challenges that we have is these procedural bits. We've seen that they're all about

01:06:57

single-threaded code. Little bits of single-threaded code that have these nice little hierarchies.

01:07:02

And we know that hierarchies, well, hierarchical-like things, they work up to a point. And these

01:07:08

hierarchies are control flow. But how am I going to build a big system out of this? And this is

01:07:12

where we hadn't already had the go-to problems. This is where procedural fails to scale.

01:07:19

In other words, this is where it starts struggling, big code basis. Now, I would like to point out

01:07:24

that most code bases that are big don't need to be as big as they are. Okay? They are too big.

01:07:30

If you say, our code base is this big. This will never work. Your code base is probably too large

01:07:34

already. But that's a separate talk. The key point is that even if we do pair certain systems down,

01:07:41

there are ideas that are not comfortably described by these, that modules get kind of close

01:07:45

and they come out of the procedural paradigm. But we're still missing. That's a code organization

01:07:51

discipline. But that's not going to allow us to run things fast, faster, take advantage of

01:07:56

course. It's not necessarily going to allow us to do meaningful things at a link time and runtime.

01:08:03

There's something missing and procedural does not directly offer it. But the answer has been there

01:08:07

for a while. There's a different way of looking at this stuff. David Glande in the early 90s

01:08:18

was exploring a distributed and concurrent model called Linda, which has kind of got shoved slightly

01:08:27

to one side. And if any of those, he was in late 80s because I learned about the beginning of 90s.

01:08:31

So, but it kind of got shoved to the side a little bit. But there's some really interesting

01:08:36

stuff there. People tended to focus on the Linda model rather than there's a deeper message here.

01:08:42

Coordination languages and their significance. We can build a complete programming model out of

01:08:46

two separate pieces, the computation model and the coordination model.

01:08:52

So, Nicholas wrote this book Algorithms Plus Data Structures Equals Programs, which gave you kind

01:08:58

of like a ruthlessly hardcore top-down view of the world. Perhaps what we need is something

01:09:06

slightly different. Perhaps bigger programs would be better. But coordination plus computation.

01:09:12

Let's try and look at the world like that. Do we have examples of this? Well, yes, it turns out

01:09:17

one of the oldest examples. In fact, we'd actually say any shell is an example. I'll come to that

01:09:22

in a moment. But make is a really good example of this because what you have is make is a

01:09:27

coordination language. It is quite different to the language that it has. Make is structured in

01:09:33

terms of goals. It's declarative. And then it has procedural bits inside it. In other words, it

01:09:39

organizes bits of procedure with respect to high level goals. In other words, it's not the top level

01:09:43

of organization. The answer to how do you scale procedural code was always there, but perhaps

01:09:49

neglected. It's the idea of you use a coordination language. It turns out procedural is really good

01:09:53

for kind of small things, but really bad for really large things. And oh, don't get me started

01:09:57

on threading. In fact, do because we're going to do that. The problem with threading is stopping.

01:10:05

Okay. So this is, I did a talk last year thinking outside the synchronization quadrant. So I want

01:10:10

to revisit that just to clarify a few things. And actually Williams had some really good stuff on

01:10:17

this yesterday. And in his talk in terms of talking about how do you scale stuff? But it's

01:10:23

kind of convenient to divide the universe into four. That is the purpose of any quadrant diagram.

01:10:28

And we're going to do so along simple axes. Mutable versus immutable. That's our state, pieces of

01:10:36

data. And they whether or not they are shared or unshared between threads at a given point in time.

01:10:42

It was perfectly okay to say, here, I have a piece of code and now I'm going to pass it to

01:10:46

another thread of execution. If we are not sharing it, then then we're fine. Okay. So it turns

01:10:54

out that if you're not sharing stuff, life is easy. It turns out if you're not changing stuff,

01:10:59

life is also easy. In fact, let's encode this. So we're absolutely sure which is the bad quadrant

01:11:05

because every, every diagram has one. Red nature's color for danger. The color of the blood on the

01:11:15

floor from the people who program in this quadrant. Oh, yes, I know. We're going to have mutable shared

01:11:22

states. Brilliant. Shared between threads. Excellent. Red is also in the far east color of celebration.

01:11:29

And that is the, that is how we associate it with consultants who then have to deal with such code.

01:11:35

So, so what we're looking at here, so this is the synchronization quadrant. There is one quadrant

01:11:41

out of four in which you will experience pain. Yes, go there. Why is everybody in there? Oh,

01:11:49

God, it's so many people say, oh, well, okay, we need to worry about this, that and the other.

01:11:52

It's like, no, really. Look, look at over there. No, I can't see that.

01:11:57

Let's just be very clear. Now that we've gone through what's involved in, see, where is

01:12:02

procedural code comfortable? Where is it defined? What is it's history? Whether it is the ugly go-to

01:12:08

history or the slightly more elegant block structured history. It's over here. Yes, it does say

01:12:14

mutable data is okay. Okay, so we might say that that's slightly at odds with a functional worldview,

01:12:19

but let us understand why it was able to get away with that because first of all, it was relatively

01:12:24

close to the machine. Machines that did not have enough memory for you to fritter around in terms of

01:12:29

memory and copying and garbage collection as people often characterize it. We've got this idea of

01:12:35

side effects, but they are contained because we're not really sharing anything. We're not going

01:12:42

too big either, and you should be using a coordination language to glue these things together.

01:12:48

In other words, keep on not sharing. The idea of a shared nothing model. The idea is,

01:12:52

this works. Keep on not sharing. And so unfortunately, because you see historically, there was

01:12:57

never an issue with threading because all code used to be in the top left-hand quadrant.

01:13:02

Yeah. I mean, you know, you can talk about this program, and indeed people did. They never

01:13:07

actually met any because they weren't very many around. Okay, that's the point is that all programming

01:13:13

traditional programming was done in the top left-hand quadrant. And there was no question of

01:13:17

sharing between threads because there were no threads. It's a very simple kind of reduction.

01:13:22

Now, when people started getting threads and threads proceeded course,

01:13:26

we moved over here. One problem, procedural discomfort zone. This is outside the comfort zone of

01:13:34

that paradigm. It doesn't want to be there. That's not where you want to be with this paradigm.

01:13:38

It's actually very well defined over here on the top left-hand corner. So people go over there,

01:13:44

and then they build other language models on them and then start wondering why they get pain.

01:13:48

C++, hello. That C++ wants to fill out all four quadrants. You know, if it's like Bingo,

01:13:55

it's like Bingo. Yes. House. Yeah. Unfortunately, too many languages want to do that. We see

01:14:01

that with Java. We see that. We'll see that. And it's just like, yeah, we're going to get a

01:14:04

multi-paradigm. We do all the quadrants. We do pain. We do comfort. You know, what is your pleasure, sir?

01:14:13

So it's a wonderful talk. People kind of convincing me to watch it.

01:14:18

You know, Kevin, you're interested in programming paradigms and different ways of doing

01:14:21

threading and stuff like that in concurrency. Yeah. Have you seen Brett Victor's talk,

01:14:25

the future programming? No. And then finally, I got around to watching it.

01:14:30

Absolute genius. Cheer, bloody genius. It was recorded in 2013. And Brett Victor basically

01:14:38

presents himself as if it's 1973. So he's kind of doing the 1968 thing, but five years later,

01:14:44

half a decade. Wow. A lot of things happened then. Crazy ideas like the actor model and stuff like that.

01:14:50

And so he explores a much broader palette. In fact, I think one of the best bits is he walks

01:14:56

on wearing kind of like white shirt with pens on the top hand. You know, this is a much more

01:15:01

casually addressed conference in 2013. You can tell from pictures of the audience. And it's just

01:15:07

like, why is he dressed like that? It's very, oh, he's being an engineer from 1973. I get it. Very

01:15:12

funny. Not as funny as the talk there. There's some really good insights. I love that he puts

01:15:18

his threads and locks. They're kind of a dead end, right? So I think we're still using threads

01:15:23

and locks in 40 years time, which just like pack up and go home because we clearly failed as an

01:15:28

engineering field. Yeah, you know what? He's right. And that was in 2013. He is more right now in

01:15:34

2018. He's not that wrong. So let's go back. That comfort zone. Let's explore that.

01:15:41

Proceed. The idea is that the danger with any paradigm and where it starts getting a bad name

01:15:47

is when people apply it outside of its comfort zone. And our temptation is because we like

01:15:51

our ones and zeros because we like simple answers because we want to say, I have the one true hammer.

01:15:57

Show me the one true thumb. You know, I have the one true hammer. Therefore, I'm going to

01:16:04

apply it everywhere. Even when I shouldn't be, okay, there's this idea that we under we fail to

01:16:09

understand the applicability and then say, and now we stop. This is no longer where this approach is

01:16:15

comfortable. This language, this framework, this whatever. And we already had the answer. It was

01:16:20

back in the coordination model. Computational model allows programs to build a single computation

01:16:26

activity, a single threaded step at a time computation. Okay, nice and comfortable. Sit there,

01:16:31

you can do your module, you can do your C, you can do whatever. The coordination model is the glue

01:16:36

that binds the separate activities into an ensemble. Okay, so an architect, always like an architecture

01:16:40

definition language, but the idea is that you have something that glue stuff together.

01:16:44

So your ultimate architecture ends up looking a bit like this. Everything looks single threaded,

01:16:49

wherever you are, it feels single threaded. Okay, you're not aware of threads of activity or any

01:16:55

concurrency. You have a very simple worldview and everything is lovely and local. Okay, there's no

01:17:01

real problems. And that's what everything looks like. There's no shared anything. And then we

01:17:07

impose a coordination model on it. And there are lots of different coordination models. I gave you a

01:17:11

very simple example of make file, but one of the classic ones, let's go back to the 60s,

01:17:16

1964. I like using this one, a lot, Doug McElroy. To put my strongest in service and nutshell,

01:17:23

we should have some ways of coupling programs like garden hoses. Screw in another segment

01:17:28

when it becomes necessary to massage the data in another way. This is the way of I also.

01:17:32

This is the invention of pipes. It took another six years before they were able to find a

01:17:37

a character on the keyboard that would do the job. That's only half joking. It was actually Ken Thompson

01:17:47

who sort of said, oh, let's use this symbol. And that was it. It was in. But this is the whole

01:17:55

point is that that pipes and filters model is a coordination model. Again, pipes and filters does not

01:18:00

solve every single problem in the universe, but it is a coordination model. And so this is the idea

01:18:07

you glue together. These little bits of procedural C using something else. And that composition

01:18:12

model becomes very powerful. I did mention I might say something about composition and

01:18:16

and functional, but there it is. So you end up with the world looking a little bit like this.

01:18:20

The very simple kind of view. Everything ends up with pipes and you can chain this.

01:18:27

You can have it's finite size, so therefore it's bounded. The question is whether you can control

01:18:34

is it the operating system? Is it you? But this channel, this kind of like pipeline architecture,

01:18:39

this message queue architecture, these are all the ideas. It's got buffering, so therefore it's

01:18:43

implicit the asynchronous. So you've got that. And then you can start playing around with things,

01:18:48

just see how things go. People often mend up with n equals infinity, which I would suggest is

01:18:54

great for prototypes, but not a good idea for production. It turns out that infinite memory is not

01:19:00

actually available yet. It turns out that you can have a system fail because of starvation,

01:19:09

priority inversion, all kinds of exciting things that mean that something runs away with that.

01:19:12

You want to have failure at well specified points. So generally, don't leave them there.

01:19:17

But we have names for other categories. N equals one bounded buffaday synchronous.

01:19:23

One place queue. What good is that? Well, we like to call it a future from the other side. It looks

01:19:28

like a promise. You can build everything out of these things. Those are redundant ideas once

01:19:33

you have the concept of queue. What about a zero placed one? What uses that? That's a classic

01:19:39

channel. Now some people might be sitting there going like, ooh, you're talking about go. No,

01:19:44

I'm not. The go people are kind of late again. 1970s, communicating with sequential processes,

01:19:50

which gave rise to the Occam language 1980s. Occam is one of the most brutally uncompromising

01:19:57

procedural languages I have ever encountered. And it was a joy to programming. It was systematic.

01:20:05

It believed that indentation was significant. It didn't want you to type too much. It showed

01:20:14

its Algos 68 influences as well. It didn't believe in this kind of like stroking of the

01:20:21

programmer. It said your program did not compile. It's as simple as that with one error.

01:20:29

Oh, only one error. Yeah. Because it didn't have a list of errors. It would just stop at the first

01:20:34

one. That's it. I'm stopping. I'm not going any further. You never got a cascade of errors

01:20:40

because it would just stop at the first one. Yeah, I'm done. Until you fix it, I'm not playing.

01:20:45

But if you think that, you know, everyone uses this language, it's got such a strict

01:20:51

type system until you use Docum. You have no idea of the level of bondage and discipline you

01:20:55

can program in outstanding. Anyway, so where does this leave us? It leaves us with a question of time

01:21:05

because what we find on the way she, Nobel Prize winner said this, everything has been said

01:21:14

before. But since nobody listens, we must always start again. Most of this stuff is not new.

01:21:21

But we get terribly excited about it. I do love language design and languages. I think they're

01:21:25

great fun. But that doesn't stop me being hypercritical of them or our failure to learn.

01:21:29

Reading the software engineering document was profoundly fail depressing because it turns out that

01:21:34

we haven't really done very much in the last 50 years or other the hardware people have been

01:21:39

really busy. Let's put it that way. All of the benefits. Yes, yes. But as a modern developer,

01:21:44

I have a big screen. Yeah, that's a hardware thing. I have so much memory now. Yeah, that's also

01:21:48

hardware it turns out. It turns out that most of the benefits were anticipated but were

01:21:54

bottled up. They were waiting at the starting line waiting for somebody to say,

01:21:57

look, here you have the hardware to be able to try this. But there's a lot of these ideas

01:22:01

that are surprisingly not new. And we also have a habit of just putting things in a box saying,

01:22:07

oh, that's the pass it's dead. It's dead to me. As a case of what procedural programming,

01:22:12

we do have this habit of saying, oh, that class was really procedural. We use it, but I've used that

01:22:17

term. But then to actually go back and look at it, are we using it fairly? And did we properly

01:22:23

understand what we meant by procedural? Anyway, it turns out, by and large, no, we didn't.

01:22:29

It turns out that the truth was always out there. It just takes a little bit of

01:22:34

sort of looking around and digging out. And then you reveal these deeper insights as to how

01:22:39

things are connected and how programming models are connected. The things that we actually have

01:22:44

learnt, as opposed to the things that we have accidentally reinvented and re-led. There's matters of

01:22:49

form, matters of structure, and ultimately matters of reasoning. So I'm not going to say, oh, go forth

01:22:54

and do procedural programming. It's a case of, like, understand what it is before you working

01:23:00

out and work out how excited you should be by the next language feature.

01:23:04

Outstandingly, I finished five minutes early. So I'll do a thank you and then I'll ask for

01:23:09

questions. So thank you for listening.

00:00

Introduction to Procedural Programming

00:38

Reassessing Procedural Programming

02:05

Understanding Programming Paradigms

03:42

Exploring the History of Bristol

08:31

Software Engineering in the 1960s

16:11

Understanding Input and Output in Programming

16:19

Modes Over Types in Procedural Languages

16:24

Revisiting Proposition Structures

16:29

Procedural Languages and String Handling

16:52

Iterating Through Arrays in Procedural Code

33:40

Understanding Control Flow in Programming

34:20

Analyzing Duff's Device

36:50

Exploring Historical Programming Languages

45:00

Understanding Code Structuring

47:20

Decoding Procedural Paradigms

49:10

Transition Between Programming Paradigms

51:00

Understanding Abstract Data Types

53:00

The Concept of Modules in Programming

56:00

Exploring Garbage Collection History

58:40

Introduction to Inheritance in Programming

01:05:55

Scaling Procedural Programming

01:08:05

Coordination vs Computation Models

01:10:00

Challenges with Multi-threading

01:17:20

Pipes and Filters in Programming

01:21:10

Reflections on Programming Paradigms

00:38

What makes procedural programming relevant today?

02:05

Are modern programming paradigms better than procedural?

08:31

How can historical software engineering inform current practices?

11:00

What unique contributions did 1960s software architecture have?

16:11

What logical connections do I/O have in programming today?

16:19

How does procedural programming handle modes instead of types?

17:35

What role do parentheses play in older languages?

24:33

How did structuring programming evolve past using GOTO statements?

34:20

What is Duff's device and why should we avoid it?

38:10

How did early programming languages visualize nesting?

39:25

In what ways do modern and older languages handle returns?

43:00

How does structured programming emphasize cognitive clarity?

49:30

How do functional and procedural programming differ in side effects?

51:50

What impact did Barbara Liskoff have on programming structures?

52:17

How do abstract data types define programming behavior?

01:06:15

What proves the risk or substitution principle in programming?

01:09:10

How does the coordination model help in scaling procedural code?

01:22:10

What lessons can we learn from past programming models?


Stack (abstract data type)AlgorithmComputer scienceObject-oriented programmingMixinGuard (computer science)

Description

In this talk, Kevlin Henney questions whether procedural programming is still relevant in today's software development landscape. He notes that while the term 'procedural programming' has a negative connotation, the idea of thinking about programming in a procedural way is not necessarily a bad thing. Henney explains how new devices and technologies are changing the way we think about programming and whether procedural programming is still relevant. He highlights the importance of considering both functional and procedural approaches to programming and how they can complement each other. Henney also discusses the potential drawbacks of focusing solely on one approach and the need to consider a broader range of paradigms in software development.