raganwald
(This is a snapshot of my old weblog. New posts and selected republished essays can be found at raganwald.com.)

Tuesday, October 09, 2007
  I'm confused


After reflection, this feels like it doesn’t carry enough idea mass to deserve a blog essay, but it isn’t brief enough to qualify as a twitter-like micro-post.


I just stumbled across a parenthetical remark about Why are local variables bad?, an article wherein I started to talk about why it is important to really understand the objective of refactoring code, not just the mechanical process. I then got to the title’s point, that mutable local variables are bad, and why I feel that way.

Ocean wrote:
Local variables aren’t bad they’re just confusing. A lot of times people use the word ‘bad’ when they really mean ‘confusing.’

This is interesting. When we are talking about computer programs, I suggest that confusing code is always bad. Perhaps there are “degrees of bad,” and local variables are less bad than, say, dangling pointers. But overall, isn’t it bad to confuse?

I guess my personal mantra is that programs must be written for people to read, and only incidentally for machines to execute (and here’s the entire text online).

Code that is confusing is difficult to understand. I pointed out that mutable local variables make code difficult to refactor. But hark! The problem is not that it’s difficult to refactor: that’s a symptom. The problem is that the logic is entangled and tightly coupled, such that it is difficult to decompose it into smaller blocks, to move pieces around, or to share common code.

Now there’s a kind of confusion that comes from unfamiliarity. If you grew up with Haskell, perhaps mutation will make your hair stand on end when you first see a BASIC program in all of its glory. But honestly, I have used mutable state since 1974, and it is not getting any easier.

There’s something intrinsically confusing about mutable local variables, and I suggest that this—in and of itself—is bad to the bone.
 

Comments on “I'm confused:
I don't find mutable local variables to be confusing. For one thing, they're right there, so you can see all the code that modifies them.

Immutable "variables" can help you to follow the code, and also help with refactoring (I'm a big fan of const correctness), but that doesn't mean mutable variables are bad.

What is bad is mutable variables that don't actually ever change. By omitting the const, you make a declaration that this variable can change. This is information that you've got to carry with you when reasoning about the code --- every time a variable is used you need to check that it's still got the same value.
 
As an American, I have to say that it is very, very hard to take any post with the words "bad to the bone" seriously. I blame George Thorogood. :)
 
Jeff, I apologize. I blame The Guvernator for his role in "T2," where somehow he turned an expression that was supposed to stink of murder, mayhem, and terror and turned it into Harley-Davidson Chic.
 
Bah! Humbug! Are you suggesting humans program in SSA form?

Seriously, LOCAL variables? Where all modifying code is in front of you eyes?
 
the link that you provided at (and here’s the entire text online).

gives a 404 error, irony is this error is not actuially human readable....
It would be great if you can provide a working link, I would like to read it.
 
You've established elsewhere (from memory, no refs to hand) that variables lead to different states in code which must then be tested for the program to be deemed correct. Therefore increasing immutability reduces bugs.

However, mutability is more natural to humans: they are used to doing things to the world and sensing changes. Think of the evolution of programming languages from assembler, through Cobol, Fortran,... Only comparatively recently have functional languages become established. Also people (in general) find mathematical reasoning difficult, and it is possible that this is because one is dealing with relationships between immutable entities, not something one does that often outside of mathematics. What about hardware: does there exist a purely functional CPU?

Even functional languages must introduce the nontrivial idea of monads to allow programs to print.

If you wish to expand this post into something longer, explain to us why functional programming is less confusing than local change in procedural or object oriented programming, the latter holding local mutability to be exemplary. How is it "natural" or "not confusing" to make a program work for you when it doesn't *do* anything? :-)
 
explain to us why functional programming is less confusing than local change in procedural or object oriented programming

First, reducing local state changes by reducing or eliminating local mutable variables is not the same thing as functional programming.

All I'm saying is that methods, procedures, or functions that don't have mutable local variables are less confusing than those that do.

I am reminded of the following conversation: One fellow says to another, "My wife and I are expecting a baby. I hope it's a boy. It would be nice if he grows up to be tall, like me."

The other recoils in horror: "What are you saying? Can you imagine if the world was just men, no women? The human race would die out! And what's with tall? Are we short people so unattractive, so repulsive to you??? I had no idea you were such a shallow person!!!!!"
 
:-) A nice riposte! However, you have argued before for more functional style, and reducing variables is heading that way, so I think it's a fair thing to ask for. Asking the man why he wants a boy who is tall, what appeals to him about it, is not the same as saying "Why don't you want a girl?". There are interesting cognitive issues here, solved in different ways in, say, Forth, C, C++, and Haskell. Your book links (Eg "To Mock a Mockingbird" ) show you'd have something to say about why a functional approach would address this problem, and I'm still trying to grok functional programming, so I'd be interested in reading that. I agree it isn't all or nothing, though.
 
I'd encourage everyone who is all excited about mutable data to check out Chapter 2 of Hardcore Java:

http://www.oreilly.com/catalog/hardcorejv/toc.html

The final keyword is a beautiful thing, for all the reasons Reg laid out, and they get into programming-language-specific detail in that book.

My big beef with mutable data is that while it may be natural for humans to think in terms of changing things, it's also very hard for humans to deal with lots of moving parts in their head. Once you get past a couple of variables and a few branches, and certainly once you start to mix in abstraction and fun stuff like polymorphism or concurrency, the level of complexity has demonstrably gone beyond the capability of humans to handle.

This is exactly why people have tried to break up and isolate the exposure of mutability, and the ways in which mutable variables are accessed (see the move from global variables to objects). And, as things have continued to progress, you're starting to see people saying that more and more mutable data should be more and more isolated.

This is all symptomatic of what Reg is getting at. And while there may be a place and a time for mutable variables or side effects, code that minimizes those things -- in whatever language or structure -- is a lot more maintainable.
 
Reg,

Yes, that was my point. When we talk about bad code we are really talking about confusing code. The word confusing allows us to really get at the problem. And it provides a good bound in the other direction: I can recall a few situations where introducing state, even temporary state, can make code much easier to understand.
 
Dilip,
In case you didn't find it, here's a working link to the online SICP.
 




<< Home
Reg Braithwaite


Recent Writing
Homoiconic Technical Writing / raganwald.posterous.com

Books
What I‘ve Learned From Failure / Kestrels, Quirky Birds, and Hopeless Egocentricity

Share
rewrite_rails / andand / unfold.rb / string_to_proc.rb / dsl_and_let.rb / comprehension.rb / lazy_lists.rb

Beauty
IS-STRICTLY-EQUIVALENT-TO-A / Spaghetti-Western Coding / Golf is a good program spoiled / Programming conventions as signals / Not all functions should be object methods

The Not So Big Software Design / Writing programs for people to read / Why Why Functional Programming Matters Matters / But Y would I want to do a thing like this?

Work
The single most important thing you must do to improve your programming career / The Naïve Approach to Hiring People / No Disrespect / Take control of your interview / Three tips for getting a job through a recruiter / My favourite interview question

Management
Exception Handling in Software Development / What if powerful languages and idioms only work for small teams? / Bricks / Which theory fits the evidence? / Still failing, still learning / What I’ve learned from failure

Notation
The unary ampersand in Ruby / (1..100).inject(&:+) / The challenge of teaching yourself a programming language / The significance of the meta-circular interpreter / Block-Structured Javascript / Haskell, Ruby and Infinity / Closures and Higher-Order Functions

Opinion
Why Apple is more expensive than Amazon / Why we are the biggest obstacles to our own growth / Is software the documentation of business process mistakes? / We have lost control of the apparatus / What I’ve Learned From Sales I, II, III

Whimsey
The Narcissism of Small Code Differences / Billy Martin’s Technique for Managing his Manager / Three stories about The Tao / Programming Language Stories / Why You Need a Degree to Work For BigCo

History
06/04 / 07/04 / 08/04 / 09/04 / 10/04 / 11/04 / 12/04 / 01/05 / 02/05 / 03/05 / 04/05 / 06/05 / 07/05 / 08/05 / 09/05 / 10/05 / 11/05 / 01/06 / 02/06 / 03/06 / 04/06 / 05/06 / 06/06 / 07/06 / 08/06 / 09/06 / 10/06 / 11/06 / 12/06 / 01/07 / 02/07 / 03/07 / 04/07 / 05/07 / 06/07 / 07/07 / 08/07 / 09/07 / 10/07 / 11/07 / 12/07 / 01/08 / 02/08 / 03/08 / 04/08 / 05/08 / 06/08 / 07/08 /