Douglas Crockford: Programming Style & Your Brain

Douglas Crockford: Programming Style & Your Brain



Views:72535|Rating:4.85|View Time:54:44Minutes|Likes:712|Dislikes:22
In this talk from JaxConf 2012, Douglas Crockford discusses programming style and your brain, the relationship between the two and the importance of adopting a more rigorous programming style in your strive for lowering error rate.

“The approach I finally settled on was language subsetting, which was not something I ever expected. It’s been said only a madman would use all of C++. It’s also been said only a madman would use C++.”

** For more presentations from Doug and others from JaxConf 2012, head to

good afternoon I have two topics for you the first one is programming style which is sometimes thought of as the part of your program that the compiler ignores sometimes thought that since the compiler doesn't pay any attention to it there's no reason for us to pay attention to it either that one style is as good as another I can't try to persuade you that's not true that some Styles are significantly more beneficial than others the other topic is your brain now these topics would appear to have absolutely nothing in common with each other what could brains have to do with programming it turns out there's a connection a really surprising connection so I'm I'm going to be misrepresenting the work of Daniel Kahneman the nobel-winning psychologist now it turns out no Belle doesn't award a prize for psychology so they gave him the award for economics he's not an economist but he found that that some of the first principles of economics aren't true such as in any transaction a party can be expected to pursue their own best interest this turns out not to be strictly true if any of those parties is a human being because it turns out that people do not think the way economists think we think in fact we don't think the way most of us think we think the way we think is really quite different and surprising and and that is why I cannot the prize so he came up with a model of two systems it's not a a physical model it's just a descriptive model system two is the analytical engine it's the thing that we think with it's the thing that we think we are when we think about ourselves it is able to do mathematics and arithmetic and logic it's where we do our high-level reasoning it's also very slow it's because it's so slow that we had to invent computers because system 2 just can't generate the numbers as fast as we need them and also it requires a lot of effort to run system 2 so we tend to turn it off as much as possible then there's system one system one is heuristic it's associative it is very very fast and you cannot turn it off one of the characteristics of system 1 is that if it is given a problem that is too difficult for it to solve it will substitute a simpler problem and solve that instead now the fact that there these two systems is not surprising we've always been aware of that you know my head tells me one thing but my gut tells me something else head and got very easily map onto system 2 in system 1 the thing which is surprising is that system 1 provides the working assumptions for system 2 and system 2 is completely unaware of that and because system to our system 1 is associative and approximate and has no understanding of mathematics it frequently gets things wrong but system 2 is trying to do logic with these false assumptions and as you know if you have a logical system of false inputs you can get false outputs and it turns out we do this all the time the more you read Kahneman the more amazing it is that we ever get anything done because we are really fallible creatures so I'm going to give you an example of how these two systems work from visual processing visual processing is the opposite of computer graphics it's where you take a signal from a camera extract the pixels and analyze the pixels in order to figure out what all the objects are on the scene and how they are all moving relative to each other and the camera it turns out just a walk around in the world it's really important to be able to solve these problems and it's really hard computers have a very difficult time doing this but we're able to do it all the time and there's obvious evolutionary value and order in it being able to do that you know when you're being chased through the jungle by a sabre cat you need to solve the problem of how you get through the thing and also do the latency compensation because it takes time for this hunk of meat to work out the calculations but you need to anticipate where you're about to be in order to keep your feet moving we do that without even thinking about it which is really quite remarkable but in order to do that we will substitute the solutions to simpler problems rather than hard problems which sometimes gives us incorrect results and we can observe that in optical illusions this is an illusion developed by Edward Adel s'en of MIT here we have a checkered board with white squares and black squares and it's cylinder on it and two of the squares are labeled a and B it turns out a and B are exactly the same color if you're to load this into Photoshop and test the pixels they are exactly the same pixel values and that may be a surprise to most of you so to prove that in fact they are the same I'll take a solid colored square and connect them you can see there's no break it's completely continuous they are the same color now some of you may be seeing a gradient there connecting them if there's no gradient it's solid color and you can prove that by covering up square B with your hand and the gradient disappears and then if you drop it the gradient reappears now you know the truth of this picture your brain is lying to you there's this component in our heads which when presented with inconsistency will generate consistency and that's probably a good thing because computers when they become inconsistent are likely to follow but when you're running through the jungle you don't want to be falling over because you get some inconsistent data so instead we've got systems which are working continuously to try to make consistent what is inconsistent and sometimes that tells us that things are true which are not true now it turns out all of this stuff was not news to the advertising industry they've been depending on this stuff for a long long time that they could convince us that we needed things that we do not need by creating messages and target targeting them directly to the gut to system one in system one will receive those messages system two can be oblivious to them but once system one determines that there's a need system two is hopeless to resist and nobody understood this better than the tobacco industry because you look at tobacco how do you sell tobacco what does it do it makes you smell bad it turns your teeth yellow it makes you sick and then it kills you so how do you convince people yeah I want to do that you give them images which are confusing and you know for example the gut is very much attuned to immediate danger you know fight-or-flight is associated with that but slow death is confused with good for you and so you know if we're not reliable so that is the brain that we're using to write computer programs and there's nothing in our evolutionary background to suggest we should be able to do this and somehow we're able to do it anyway and it's really hard because programs are the most complicated things that humans make they're made up of a large number of pieces a lot of operators and variables and structures and they all have to work together and we don't have anything else that contains as many component parts as programs so very early on it was recognized programming is way too difficult we need to get the machine to be writing the programs for us because in many ways it's smarter than we are so one of the first goals of artificial intelligence was to be able to give a specification of a program to a machine and let the Machine write the program and that completely failed artificial intelligence has been able to do a lot of amazing things it plays really good chess now you can play a pretty good game of Jeopardy but you can't give a set of requirements and a stack of of customer interviews to a program and ask it to write another program if you could and then what we could do is ask the program okay now write a program that's better than you and we keep doing that until they take over but that hasn't happened and it hasn't happened because we don't really know how we do programming at least not well enough that we can tell a computer how to do it what computers can do is translate one formal language into another that's something that is algorithmic and they can do it very effectively and so we leverage that in programming languages because that's what a programming language is it's a mapping of one language to another and every generation or so we raise the level of abstraction up to where things are easier which gives us more leverage the ability to write more more complex stuff the the hardest thing about programming is that it requires perfection a program has to be perfect in every aspect for all possible inputs in all possible states and that's hard because the contract we have with the computer is if the program is not perfect then the computer has license to do the worst possible thing at the worst possible time and it's not even the computers fault whose fault is it your fault you're the guys who get the call why is the thing not working but it's not surprising that it's not working because um you know given that that's the case we would want to never release a piece of software until we were convinced it was perfect but we don't do that for a number of reasons one is we wouldn't know perfect if we saw it we we have no way of determining if a piece of software is perfect there's no test no way to know so we wouldn't know it if we saw it but even if we could probably take too long and we could not afford the time it would take to reach perfection before we got some utility out of it so instead we release the software in a form which we know is imperfect and hope that any imperfections can be found before anybody notices we call that data and and that's the state of the art that's the best we figured out how to do which is crazy but that's where we are and we are there because we are hunters and gatherers there's been no human evolution since the Ice Age and there's nothing in our evolution to have prepared us for this so it's sort of miracle that we're able to do this at all so evolution likes dual use technologies it develops something for some purpose and then finds another use for it and I think that happened for programming as well so obviously we're using the head we're using system two because so much of what we do is analytical we're keeping all the state in our heads and manipulating it until we can get it down into a representation that can execute but I think the gut also has a role in this because we cannot describe how we do programming you can't write down a list of steps and give it to someone and say that's how you write a program you know you kind of go top-down for a while and then it kind of bottom-up and your inside out and macro view micro view you're constantly shifting around looking at the problem from all aspects until finally sort of the program starts to come into shape and we don't know how we do that there's no way we can describe that and that's somehow we all figure it out but we don't know how we figured it out and that's why we can't teach computers to do this and I think that there is some some role for the gut in doing that that somehow it does this counterintuitive thing which gives us these flashes of insight which finally help us to find a solution and allows us to go forward so I think programming would not be possible without system one without the gut now I have absolutely no evidence to support that statement but my gut tells me it's true so I believe it oh and programming is all about trade-offs right there's rarely the absolutely correct way to do something there are always trade-offs and we tend to make most of our trade-offs with our gut which is a problem because it doesn't understand arithmetic it confuses confuses a lot of things for example it thinks most has more weight than all it thinks not very much is the same as nothing it's really bad at math but we use our gut in doing trade-offs and that very often gets us into trouble so I'm going to be giving you some examples of programming style in JavaScript the the theory that I'm going to give you works in all languages but JavaScript is particularly good for these sorts of examples because it has some of the best parts ever in a language and most of the worst parts ever put into a programming language javascript has by far more bad parts than any other popular language so adopting a programming style which helps to mitigate that badness is really important um because there's so much sadness in the language and all the traps that that badness sets for me I don't trust myself to program in the language without good tool support so I wrote something called J's lint which is written in JavaScript which reads my JavaScript programs and tells me when I'm using the bad parts so that I can know okay that's bad stuff I don't want to be doing that because it's really easy to stray into the sharp edges in this language they're traps all over the place and it's free and it's available to everybody and it comes with this warning it says warning jslint will hurt your feelings and it's true I've had my feelings hurt by it and I wrote it and I hear from people all the time whining jslint hurt my feelings you know can you fix it make it stop you know recognize my special needs that I have to write crappy code this way so can you be more forgiving and so I've been hearing this whining for years and years and at some point I start wondering why is this why are people whining because what this is it's a code quality tool you don't have to use it but if you decide you want to use it it's because you want it to inform you about ways to make your program better stronger more resilient and when it offers you that good advice you go where I don't want to do that you know and they start crying they don't wait a minute there's no crying in programming well why aren't people getting so upset or are they getting so emotional you know programmers can argue and lessly about stuff which appears to be a VOC on secuence but from the intensity of their arguments appears to be really important you know for example do you put curly braces on the left or on the right now when Ken Thompson designed the B language when Dennis Ritchie added Pascal types to it to create the C language they were putting the curly braces on the right just because it seemed to make sense it turns out there's not a good reason for why should do it one way or the other it's sort of like driving should we drive on the left side of the road or the right there's not a good argument you know people in England drive as well as people in Europe there's no evidence to suggest that one is safer or more efficient than the other it's just a convention um so you know you can't say if you should be on the left or right but there's a really good reason for why we should all be on the same side and we're lucky there's not a bridge from London to the rest of the world because I would get confusing but we don't so you know we got compartmentalization there now there were other people in Thompson's lab at Bell Labs he said we want to put him on the left and I'm sure they had a meeting about it and after a while Thompson said hell with this I don't care this is a stupid argument there's not good reason one way or the other do what you want just don't invite me to any more meetings just leave me out of this and it's a shame because Thompson could have said you know could have had the compilers say it's got to be on the right dammit in otherwise it's a syntax error because he didn't do that who knows how many man centuries we've wasted arguing about should it be on the left or on the right and we get really upset so if someone who's used to putting them on the left goes to work for a shop that puts them on the right and they say okay now you're working here you got to put them on the right he's going on no I don't wanna put them on the right that's so wrong can't you see how wrong it is and system two will start rationalizing because system one is saying this is wrong dammit so system two is going yeah that that's right it is wrong why is it wrong it starts making up all these things and none of them make any sense because there's not a good reason to prefer one or the other just to convince it's punctuation it's just punctuation you know why are we getting so upset about punctuation so ultimately where should we put them I don't know and there's not a good answer to that question except it turns out in JavaScript where there is turns out in JavaScript you want to always put them on the right and never on the left and this is why one of the things we do commonly in JavaScript is return an object literal which produces a new object this is a common pattern we do this a lot if you put the curly brace on the right it always does the right thing and if you put the curly brace on the left it returns undefined instead of your object and it doesn't produce in this case any other warning there's no syntax syntax error there's no runtime error it's just at some point your program is going to notice we expected a function to be here and we get the undefined value instead and that could be a large distance away from where this error actually happened and so then you have to start debugging and walk it back and you might actually bring it back to this statement and go well I don't get it it's there you know you can look at that code for now or not understand where the object disappeared this is because of a horrible design error in JavaScript called automatic semicolon insertion it was a well intentioned feature but it's a terrible feature it's one of the very bad parts of the language and in this case it causes this problem so if you always put your curly braces on the right you will never experience this and if you put your curly braces on the left the day will come when you're going to endure this pain so you look at it in terms of a trade-off okay what's the difference in cost of putting the curly braces on the left or right none there is no cost what's the benefit we can avoid a terrible time-consuming headache that's a good trade-off for nothing I get a little bit of immunity from from a particularly nasty bug that's a good trade-off so we should prefer forms that are air resistant because we're trying to be perfect so we want to avoid errors wherever we can so another thing that Thompson came up with was the switch statement he took Horus case statement and filtered it through the Fortran computed goto now Dykstra said that go-to was harmful and he was right they took us a generation to get rid of go-to but it still exists in all modern languages in the form of the switch statement so there's a hazard where you can have one case fall through into the next case and one day someone wrote to me and said Janis Lynch and check for this because it's a subtle error and it's difficult to see from reading the text but it can really cause problems and hmm I thought about it really carefully and I wrote back to them I can understand how that could happen but there is this elegance that happens when you can line up all the cases and get them to cascade one and to another that elegance is really highly desirable and the error could happen but it hardly ever happens and so looking at in terms of trade-offs you got elegance versus hardly ever happens I think this is actually a good feature of the language I'm not gonna report on it next day the same guy wrote to me and said I found a bug in jslint good ok so I throw it in the debugger you know what happened I had a case that was falling through and in that moment I achieved enlightenment because it turns out we spend enormous amount of time tracking down errors we like to think we spend most of our time power typing but that's not where the time goes the time goes and correcting our mistakes and it's painful in time-consuming and we tend to block it out once once we found it we get this little rush of euphoria and go ha good back to power typing but in this particular instance it was so humiliating because I just given the speech about how this was a good feature and boom it I can't ignore the evidence in fact that this is a bad feature so I was forced in this one instance to learn from my mistakes which is rare it's something I'd like to do more of but generally we don't do it very often so I adopted a new strategy with respect to switch statements that I never intentionally fall through which means I can now find the cases where I accidentally fall through it's hard to find the accidental cases when you've got the intentional cases so so what was my error I said that hardly ever happens which means the same thing is it happens that's the gut talking the gut is really bad at math and I was depending on the gut in in doing this evaluation um also I was wrong in the elegance argument it turns out what is the cash value of that art of that elegance it turns out there isn't any and and perhaps there is even a negative value because it can often cause you to do coupling and weird code convolution in order to achieve this cascade which in fact has no values you can actually make the code craftier so it turns out not to be worth it um so don't fall through so a good style can help produce better programs style should not be about personal preference or self-expression it should be about driving down your error rate because ultimately that's the thing that's important and we can learn something about programming style from literary style the Romans wrote laughing all in uppercase with no word breaks punctuation and this worked for them they were able to produce great literature to our modern eyes this is hard to read and and there were ambiguities which could make things difficult for example the third line could be read as now or DB reaks now we know it doesn't mean that but it could but this worked well I mean there they were the greatest empire in the world for a while but when Constantine has adopted Christianity as the state religion of the Roman Empire it became necessary to take the scriptures and copy them and send them all over the world and let's presented a problem because they did not have originals of any of the documents all they had were copies of copies of copies and none of the copies agreed every copy was different because it turns this is an an error inducing format on medieval copyists introduced lowercase word breaks and punctuation and these innovations helped to reduce the error rate it made it easier for them to copy the manuscripts and distribute them they also had the unexpected benefit of making the manuscripts easier to read and interpret and that turned out to be useful too so when Gutenberg started printing he copied these conventions and we're still using these conventions today the conventions we have of capitalizing the beginning of a sentence and putting a period at the end of it all of that we've been doing that for hundreds and hundreds of years and it works we've all gone we've all been schooled in this stuff it all looks right to us you know so a sloppy reader might say well it doesn't matter if I put the periods in the right place because the reader can figure it out but we know you don't want to be doing that because it makes you look at literate and it distracts the reader from the message you want them to be focusing on you're on your writing and not on your punctuation you know so you never see a great author saying I'm such a great stylist I'm going to put all my periods at the beginning of the sentences and not the end you just don't see that because it would look stupid so I'm good style can help reduce your occurrence of errors it works in the literature it's going to work in programming too there are lots of good style books around one of the best ones is the Elements of Style written by William Strunk it was self-published about a hundred years ago English has evolved some since then so some of his advice is a little dated but a lot of it is still really good it's all about good composition and good use of language and a number of writers have adapted the elements of style to programming languages it's a very good mapping so programs must communicate clearly to people there's a school of thought that says it only matters that the compiler understand it but that's wrong especially as we're getting more agile as we're doing more team development it's necessary for everybody to understand the program so clarity is essential so we should be using the elements of good style wherever possible and in fact most of or a lot of the conventions of literature mapped very nicely under programming languages um so you know we have conventions where we put a space after a comma and not before and this you know in literature that doesn't impede a writer because a good writer will slavishly conform to the elements of style and express his creativity in his words in his structures and his in his images you know so you don't need to be messing with punctuation in order to prove that your creative programming languages require more precision than literature does so we can have conventions to help disambiguate things like we use parens to do grouping and statement structures and we also use it for invoking functions so we can use strategically spaced placed spaces in order to help disambiguate those one of the good parts in JavaScript is its functions they're they're brilliant but it didn't get everything right so one of the things that's useful is the immediately invoked function expression where we create a function and then immediately execute it that gives us a closure and a scope which helps us to contain and and bind variables which is a really useful thing but unfortunately in statement position this form turns out to be a syntax error because of a design flaw so people figured out that you could overcome this flaw by wrapping the function in parenthesis and now it's not in statement position anymore and it does the correct thing but I think this is missing something because I want to do more than just trick the compiler into accepting this I want to make it clear to the reader what's going on here and this use of parentheses doesn't communicate that in fact we the invoking parens hanging off there like a pair of dog balls just you know like they're not part of this expression the ladies might want to look away so I think this whole thing is cleaner if we put the invoking parentheses around the whole thing so the outer parentheses say reader what's important here is this whole expression that we are taking this function and invoking it look at the consider this whole thing as a unit because that is what's important don't think of just the function I don't want them to miss the invoking parentheses I want the whole thing to be together so I told you about automatic semicolon insertion being one of the bad parts of JavaScript this is one of the places another place where it hurts you so if you have an assignment statement followed by one of these parentheses function expressions you would hope that would insert a semicolon there but it doesn't so it will instead treat Y as a function passing the result of the other function as its argument which is wrong but you get no syntax warning here because this is considered to be a correct statement even though it's obviously wrong so the lesson here is do not depend on JavaScript semicolon insertion again it was a well intentioned feature but it is stupid in the way it was designed and you know so if you look at the Ekman script standard which describes how this works it gives you it shows you this case you know it says oh by the way it fails in cases like this so just because it's in the language doesn't mean it's a good part it's a very bad part should be avoided javascript has a width statement that was modeled after Pascal's with statement and this is another bad part so here we're saying with Oh foo equals coda and it can expand into one of these four statements um I don't know if anyone here knows JavaScript or if you could guess which of those four statements it will expand into anybody it's a trick question it could expand into any of them there's no way you can tell from reading this code which one it's going to do in fact every time the statement executes it could do a different one so since we're trying to be perfect we can't have any confidence in a program that we cannot even read and know what it does so my advice is never use the with statement it's got this ambiguity in it which makes it extremely unreliable it also is terrible for performance but ignoring the performance problems it's just unreliable now there are a lot of clever people who have found uses for with and they suggest that you should be able to use it in limited places in the cases where it actually does something useful but I'm not saying that it isn't useful I'm saying that there's never a case where it isn't confusing and confusion is the enemy when a program appears to be doing one thing and does something else that's when errors happen so confusion must be avoided and in this case it's easy to avoid if you simply don't use that statement and write the thing that it expands into instead there's no confusion it's very clear what the program is doing JavaScript's equality operator does type coercion before it does its equality operation so as a consequence you get a lot of false positives and you also lose transitivity which is something you would like to have in an equality operator now fortunately javascript has a triple equal operator which does the right thing in all of use cases it only does the wrong thing in the case of man so my advice is always use triple equal never use double equal because you avoid this confusion now they're people who have found the you know the rare case where double equal actually does exactly what they want so they ask well can I use double equal in that case and my advice is no because the reader of your program doesn't know that you found the caseware double equal does the right thing you know it it's more likely that you just made a mistake so you want your programs to be clearly not mistakes if there's a feature of the language that is sometimes problematic and if it can be replaced by another feature that is more reliable and always use the more reliable feature this is a relatively new feature in JavaScript but it's been in other languages for a while multi-line string literal I don't like this for a couple of reasons I think it was a mistake to put it into JavaScript first off is it breaks indentation because the continuation has to go all the way out to the margin and we do a lot of nesting in our programs you know we've got functions within functions and objects within objects and having things go out to the margin breaks indentation and actually makes the programs more difficult to comprehend but worse than that we've got this syntactic hazard so here we've got two statements one is correct the other is a syntax error can anybody spot the syntax error in the second line anybody there's a space right here it's obvious once it's pointed out right um but I want my program speed obviously correct so I don't want to be using forms that are difficult to distinguish from common errors so I just don't use this form I've got there at least two other ways in the language to create long strings I'll use those instead and in the next addition we're going to get back to strings which will work properly so there's no reason to use this feature avoid forms that are difficult to distinguish from common errors on this is something that was wrong in the sea and in JavaScript Java got this one right so the first line looks like it does what the third line does but it actually does what the second line does so when you get a program that looks like that you have to ask okay what's going on here is this an error or not the only thing you're sure of is that the programmer was incompetent beyond that you really don't know so my advice is figure out which one of these you mean and always write that instead don't be writing on things that look like errors make your programs look like what they do scope is one of the best inventions in the history of programming languages we first got it in alcohol sixty and it's not its way into virtually all languages since then most languages have blocked scope which means you know between any within any block within curly braces any variables defined in there are visible only within that block JavaScript doesn't do that javascript has function scope which means any variable declared in a function is only visible within the function but and it turns out that's enough you can write good programs just typing function scope the problem here is that JavaScript syntax looks exactly the same as languages that have block scope and so for programmer is coming to JavaScript from other languages they assume that the conventions are used for block scope are what they should do and in fact those conventions can fail in JavaScript because it doesn't respect block scope it only has function scope so you know there are conventions in a book in a block scoped language that say you should declare the variable in the in the block which contains all uses of it at the site of first use if possible and that's really good advice in such a language but if you don't have blocks scoped then the best advice is declare all of your variables at the top of the function because that's actually what happens javascript does this weird thing called hoisting which puts a var statement to two pieces and the declaration part gets moved out of whatever block it was in to the top of the function if it turns out you had a couple of blocks that were declaring the same variable name both of those var definitions get moved to the top and unified so what looked like two variables is actually one and that is a real source of confusion that can cause real errors so as a result of that in JavaScript you need to declare all of your variables at the top of the function in functions of function statements do a similar kind of hoisting thing which has its own set of confusions so I recommend to clear all of your functions before you call them as well I find this is the most controversial thing in JavaScript here we have a for VAR statement and the variable I the induction variable is not scoped to the loop it scoped to the function so properly you should move that var I to the top because that in fact is what's happening people especially if they've come from Java or C or C++ yeah this is how you do it this is how you if you're writing in Java you put it there and I say right in the language you're writing it it turns out to be the wrong way to do it in JavaScript it will get you into trouble on the next edition of JavaScript will probably have a let statement which will work just like the var statement except it will respect block scope so when that happy day comes and we have left my advice will change to never use the VAR statement always use the let statement unless you have to run on ie6 or IE 7 or IE 8 or IE 9 or IE 10 we don't know what's in IE eleven yet but if you only have to run an IE 12 and above then yeah you'll want to use LED statement global variables are evil in all languages javascript requires the use of global variables because it doesn't have a linker so all the way a compilation units communicate is they're all dumped into a common global variable space where they can collide with each other this turns out to be the root cause of the cross-site scripting attack you know security problem of the browser come from this this was a design error and we're trying to fix it but because we have function scope it's possible to mitigate this problem so there are programming conventions we can used to minimize our use of global variables um so for the few global variables that you actually do use advise use all upper case because I want them to stand out this thing is dangerous and weird and you need to respect it and so I want its name to make it clear that that's what's going on now another language is all uppercase means different things for example and see it can mean a macro in that because and that was for a good reason there was a confusion and see is something a variable or a macro that was a confusion and sometimes it bother people so they came up with the uppercase convention since then that convention has been copied into other languages which didn't even have macros in them and had no confusion there at all and so that style says well you should use uppercase four constants but there's no reason for that convention I think at least in JavaScript it makes more sense to use it for global variables javascript has a new prefix which was modeled after Chavez new prefix but it doesn't work right it it's weird it was intended to simulate classical construction but it does something very very different and it turns out in JavaScript if you forget to use the new prefix instead of getting a syntax error or runtime warning instead it will just go and start clobbering global variables which is a terrible thing unfortunately this got fixed in es5 strict but in older versions of the language or if you're still in the sloppy mode you need to watch out for this so we have a convention that all constructor functions should be written with an initial capital letter and nothing else should ever be written with an initial capital letter that's the only convention we have to help us determine when new is missing on this is an ambiguous case that's unique to JavaScript the first statement looks like it does what the second statement does but actually does what the third statement does so this is another case where the only thing you know for sure is that the programmer is incompetent he thinks he's defining two local variables but he's actually creating a global variable and a local variable which is quite bad so right in a way that clearly communicates your intent okay this one's going to be a little controversial and I'll remind you that controversial does not mean wrong okay so this operator was designed by Ken Thompson in B and was copied into C and was originally intended for incrementing pointer variables now since then we have determined that pointer arithmetic is harmful and so we don't do it anymore the last popular programming language to feature pointer arithmetic was c++ a language so bad it was named after this operator um this operator was implicated in the buffer overrun craze of the 90s because it's really easy to write dense code using this which tries to do too much which is very difficult to understand and which can very easily run off the end of memory and allow an attacker to take over your system I find in my own practice that when I'm using this operator anywhere I get this twitch and I got to start optimizing I got to try to push stuff it all into one line and I can't control it so finally I had to say I'm done I don't use plus plus anymore I don't trust myself to use it because I can't control this because optimizing stuff into one line has no value you know so it's a waste of time to even try and it can introduce bugs and security hazards and I can't stop myself so the only way I was able to control my behavior was to say I'm not using it anymore I'm using plus equal one instead and then I'm calm I could just add one and I'm good and I hear complaints all the time from people saying oh wait a minute you know I should be able to write X plus plus because it means exactly the same thing and it's one character shorter that means when I'm power typing I can just go and you know and I'm so much more productive and I have to say well first off typing is not where we spend our time and second off they're not equivalent plus plus X is equivalent so when I see somebody making this mistake you know in the increment part of the for statement if I see X plus plus I have to go okay this clown does he know the difference between pre increment and post increment and so I have to look at every plus plus in this program did he get this one right you get this one right it's because this is a really subtle off by one error because it's only off by one for a tiny amount of time and so tracking that downing debugging it is really hard and so I think it's better just to avoid it entirely recently I was reviewing some code and I saw this plus plus X plus plus X Englander okay what's the story here what's going on I'm guessing somebody wrote putz plus X and then later if someone else came and noticed there's an off by one error so they put it put in another one now if the first one had been written X plus equal one it would have been really easy to change it to X plus equal two and it would have been right and that raises a question why do we have a completely different syntactic form for adding one than any other value how what's the benefit of that I really don't see a benefit but I do see people get really emotional you can't take my plus plus away how am I going to add one two things I think only just one you know if people get really really upset about plus plus so for no cost by adopting a more rigorous style many classes of errors could be automatically avoided here's another one this is another of Thompson's fault by the way Ken Thompson I think is one of the smartest programmers to ever live but I think he made some stylistic mistakes in in B and these mistakes been copied into every other language since then so um B was based on BCPL which was a marvelous little language Thompson's major contribution to the syntax of B was to take BCPL and make it look more like Fortran so PC PL required the curly braces and the parens around the were optional and Thompson did it the other way because that's how it was in Fortran and that was a mistake because you know it looks like it means that but it actually means that C is going to be executed unconditionally and this isn't another common source of errors that the program appears to be doing something but does something else so my advice is always put the curly braces in every time even if you're only going to do one thing put the curly braces in because it makes your program more resilient and it's much less likely that the next person to modify your code is going to be tricked by your austerity and introduce errors and I go oh but you know yeah but you have to type you go so hard yeah and it's not it's really easy just go pump them and boom you know and there's this new thing now called keyboard macros where you can just have them put in for you automatically highly recommend always put the curly braces if it costs next to nothing and it helps reduce your error rate and that's what it's all about as our processes become more agile our coding must be more resilient so I see a lot of people being intentional bad stylists on some of its a lot of it's due to under education it turns out most of the people who are writing in JavaScript should not be writing in any language but they do because it's the most popular language in the world and so they're doing it and and they can get away with it but often they don't understand where the stuff's supposed to go and so they just leave it out we see some old school guys who you know that they're coming at the language from Java you know you know I'd rather be using Java but you know Kay I'm writing in in JavaScript but there's no way I'm going to know what I'm doing you know I'm principle and so they'll adopt conventions that don't fit the language then there are thrill-seekers people who will intentionally write code we is confusing or error-prone just to show off their mad skills and they think you know I'm so good at this stuff I can write crazy stuff and it doesn't go bad ignoring the cases where it does go bad and then there exhibitionists who will study the language and find the weird edge cases and places where the language does stuff you would never expect they go wow what an amazing discovery how can I use that and they'll start designing programs specifically to show off these weird features programs that nobody's going to understand you know it's just childish but we see a lot of that especially in the JavaScript community and they'll be saying that's intentional I meant to do that I know what I'm doing I say no if you knew what you're doing you would not be doing that so programming is the most complicated thing that humans do and programs must be perfect and people are not good at perfect on myself I'm a deeply flawed human being but somehow I make a living as a programmer and it's hard on programming just demands discipline and a programming style demands discipline it's not selecting features because they're pretty or familiar or popular it's because they help drive down your error rate so when deciding what should go into a style that should be the number one criteria above all else saving keystrokes should not be a consideration now the alternative is the abyss right you know we spend a lot of time you know in the abyss Nietzsche said when you gaze into the abyss the abyss gazes into you it's terrible it's cold it's soul destroying and normal people can't do it the normal person has to debug a program and they spend any time Lee abyss they say I'm changing majors I don't know what's wrong with you people I can't do this it turns out there's something seriously wrong with that we are able to or we have two things going on one is we've got this incredible optimism that we can go into the abyss and we will come back out normal people can't do that but because we have that optimism it means we can't do scheduling worth of crap because we just have no idea where we're spending our time or how long things take but the other is we get selective amnesia we are not aware of how much time we spend down there we black it out and all we remember you know what did i do today is power typing I was wearing program that um you know so if we want to be more productive the best thing we can do is figure out a way to spend less time in the abyss and and that's what I'm advocating so the jeaious lint style was driven by the need to automatically detect defects I spent a lot of time on complain JavaScript and there was a constant flood of people coming in to the conference saying my program doesn't work and someone spot the problem so I cut it out and put into jeaious lint and sometimes jessalyn would immediately find what was wrong and sometimes it couldn't and I go okay so what do I need to do in order to solve that and it turned out in some cases they were using forms which were undecidable that there was no way I could statically determine what the defect was and ultimately reluctantly I had to decide that those forms themselves were defects that if I could persuade people not to write using those forms then I could do a much better job of finding the errors where they really occur so the approach I finally settled on was language subsetting which was not something that I ever expected it's been said only a madman would use all of C++ it's all something said only a madman would use C++ but that's for another conference but you know the subsetting idea applies to all languages it turns out every language has features which probably shouldn't be there that um every language designer is trying to push the state of the art and he'll be adopting features from other languages and come up with a few inventions of his own and very often they get it all right but invariably there's at least one place where they went too far and once the language gets out there and people start using it they can't take it back the language designer is powerless to to remove design mistakes from the language it turns out you have that power you can decide yourself that that is a bad part and I will avoid the consequences of that badness by simply not using that feature that's a power you have that the language designer does not have I strongly recommend you exercise that power so there will be bugs I'm not promising that you're going to be bug free by adopting a more rigorous programming style what I am saying is that you can move the odds in your favor and any thing you can do to help reduce the amount of time in the abyss that turns out to be a great trade-off so good style is good for your gut that's the end thank you and good night

24 Replies to “Douglas Crockford: Programming Style & Your Brain”

  1. Stefan Wagner

    Why is there an extra empty line below block (18:00 ff.) before the opening brace – just to make it look silly? Lining up braces aren't an arbitrary choice, but an ergonomic one.

  2. Julio Di Egidio

    That's where you and two generations now of self-appointed gurus are, together with an entire industry that was rising and you have sunk for good: but I have been vocal since the late 90's about the fact that you guys just have no idea what state of the art even is, or, should I say, thanks to you, what it used to be and now survives in a handful of professional across the entire globe: you know, the few guys that can still do a proper job and deliver on time and on budget despite all the noise. We, as opposed to you, have long known what you and the whole band-wagon have simply assumed cannot be known to then build a broken industry out of of pure speculation and misguidance: you are the guys of the self-fulfilling prophecies and the royal disasters. And still you won't get it, you…

  3. Waji Deus

    I disagree with his argument on about 'with' being confusing. The thing is, identifiers are always inherited recursively from the parent namespace. All the 'with' statement does is make sure that 'o.foo' and 'o.koda' are used instead of 'foo' and 'koda' if they're defined. We're not saying to use 'o.foo' and 'o.koda' exactly, we're just changing the precedence of the namespace so 'o' is checked first.

    Personally, I like this idea. You can't remove all context from logic. Identifiers aren't unique. What matters is that you can give the compiler enough information to give you the object reference that you want.

  4. Chris

    Great video! I started using tasker (an android application) about a two years ago and although it isn't programming it still introduces the concepts of variables (local and global), arrays, RegEx, array splitting, for loops, count loops, wait until, collision handleing, goto, variabe join and other things, which I had known nothing about before. I made some quite complex things (i.e. profiles) and initially I'd get a kick out of making them complicated because I thought I was being clever, but OMG doing it that way turned out to be a massive pain in the ass. I think my profile had over 200 actions, with different parts connected together in weird ways to help reduce the number of actions I had to create, but it was a nightmare later trying to modify it because I couldn't understand it easily. So I re-did it from scratch and it was so much easier to undertand after that. Now I'v started to learn javascript, but only to use in Tasker's Webview element, to create a nicer looking UI 🙂 It's only for me and just a hobby but I am determined to write some half decent code.

  5. BenRangel

    "JsLint hurts programmer's feelings"
    Sigh. Always telling this story.
    The reason people dislike jsLint is because it gives you a shit tone of useless warnings about code style. And you can't configure it to your style.
    That's why eveyone switched to jsHint and then esLint

  6. Jon Seltzer

    Crazy…try Clojure, there are none of these peculiarities.  It's hard to misunderstand (+ 1 2) – prefix vs. infix notation.

  7. Dan Cook

    This was a very refreshingly objective view on style! I agree that programming is about expressing meaning, so it makes sense that ambiguity is more restrictive than it is expressive, and the thus language sub-setting can increase expressiveness.

  8. MrSaemichlaus

    I think switch statements should not let you fall through cases by default, but rather have a "continue" statement for doing so intentionally. Because you more often don't want it to fall through than not.

  9. Jeliazko Zlatev

    17:47 left is wrong because its taking more space on disk 🙂
    18:38 he is totally right and i have experienced it and my thoughts were : wtf … 😀
    Overall its very good video for people who will ever do javascript especially! 🙂

  10. PixelOutlaw

    JavaScript, what a disaster.
    Why does it have to be the only real choice for web page development.
    Heaven forbid you use any language you like and the language compiles to platform agnostic opcodes for the browser.

  11. krux02

    just because javascript sucks at automatic semicolon insertion, doesn't mean that automatic semicolon insertion is a bad idea. It might be bad for javascript developers, but it go it works fine. Btw go forces you for the bace { on the right side. and those directly executed functions are very much like a simple block in scala, except that they are much more cluttered with braces ().

  12. Leto2ndAtreides

    x++ (or ++x – more rarely used), means "increment". Increment by 1 is a very common thing to do, and likely the reason that it was invented – because it was irritating people. Its common and often does have a different meaning than a regular addition – having it there makes the code more readable, because you know its usually a loop increment or something along those lines. x = x + 1; looks lame, doesn't carry that extra information.

    And in general, everything would be better off having an atomic increment operator (I especially mean databases – some are missing a simple way to avoid conflicts in doing what is a very common and important operation)

  13. Leto2ndAtreides

    There is a good reason for braces on the left. With indenting they make the start and end of blocks clearer and easy to see without clicking on the brace and then having the IDE find it for you…

  14. Warren Postma

    I wish he didn't use stupid "System 1" and "System 2" labels, even HE gets them backwards.  Just say Head and Gut.

  15. Dave Stewart

    It's inconsistent that at 28:34 Crockford supports the workaround of surrounding an IIFE with brackets in order to get it to work, yet at 18:11 does not mention the same as a valid solution to returning an object literal, and as such, says that putting brackets on the left is "wrong".

Leave a Reply

Your email address will not be published. Required fields are marked *