Temporary variables

Pierre Roy pierre at limbo.create.ucsb.edu
Thu Jun 17 19:09:20 UTC 1999


Hi folks,

I do completely agree with what Peter writes.  The number of tempos needed is
less than 10 in 99% of the methods we write, but sometimes we really need more
than that.

Let me give another example.  I have implemented a constraint satisfaction
system.  A constraint satisfaction problem consists of a set of variables and
a set of relationships (the constraints) defined over the variables.  In many
classical problems, there are more than 20 variables (20 variables is a small
problem).  And in some cases, like the cryptogram I send in my previous post,
there is a standard way to state the problem in which the variables are not
put into collections.  Of course, one cas always use collections to reduce the
number of variables needed, but in these cases it would be particularly
awkward and would lead to a hardly readable code.

If 20 variables are enough when one is doing classical programming, new
paradigms often require new programming styles (constraint satisfaction is
just an example amongst many others).  Therefore, as says Peter, the
limitation in number of tempos is a merely arbitrary choice, that can be an
issue when one uses a specific programming style.  In other words, the
formula: "any method with more than 10 temporaries is definitely wrong.  Any
method with more than 5 temporaries is suspect" quoted from Ralph's post is
obviously a good advice, but it doesn't hold for every programming style you
can think of, especially for declarative paradigms.

Besides, this limitation being more restrictive than for other dialects of
smalltalk, like Visual Works for instance, it hampers compatibility, which
might also be an issue.

- Pierre

Peter William Lount wrote:

> Hi,
>
> The number of temporary variables in a method is an implementation detail
> and limit. It seems to vary in different versions of Smalltalk. This limit
> is not part of the language or the proposed Smalltalk ANSCII standard
> (please correct me if I am wrong). Any limit choosen is purely arbitrary
> (or required by an implementor).
>
> I feel that Smalltalk should not impose a limit as you'll encounter
> situations where you'll need just one or two more than the limit just when
> you have no time to refactor the method. Isn't this usually the case with
> limits of various types? Like variable name lengh. Realistically though an
> unlimited number of temporary variables is not going to be very high on an
> Smalltalk virtual machine implementors prority list...
>
> That said, it's very rare to have a method that really needs more than 25
> variables, however it does happen. Re-organizing the code so that it uses
> less temparory variables is the obvious thing to do. However, sometimes
> people write very long methods with require lots of temporaries and they
> are not easily or quickly refactored.
>
> I personally discourage long methods. A rule of thumb being if the method
> is longer than 10-20 lines (depending on pretty printing) it should be
> factored into multiple methods. This helps me avoid having too many
> temporaries. Sometimes this is difficult or time consuming to do. Maybe the
> code was written by someone with less "concern" for short, neat, tidy, and
> clean coding practices.
>
> I came across this type of situation recently when porting code from one
> Smalltalk to another. The newer Smalltalk has a lower limit on the number
> of temporary variables (the method had one or two more temporary variables
> than the new Smalltalk permitted) and it was a pain to port these methods.
> Instead of just filing them in and dealing with them later I had to rewrite
> them just to get them to compile. Anoying.
>
> I often write short lines of smalltalk code and use lots of temporary
> variables just to make the code easier to read. I often have many more
> temporaries than 10 as a result (< 5 is normal, 5 - 10 is less common,
> 11-15 is not that uncommon, > 15 is unusual, >25 is rare but I have
> enountered it). The code could easily be "obfuscated" to reduce the number
> of temporaries but I prefer to write clear methods at the expense of extra
> temporaries. The extra temporaries allow for easier debugging and
> understanding of the code. The extra "clearity" gained in reading the
> method is important for people who maintain the code after you have done
> with it. I think it's a practice called "Literate Programming" invented (or
> described) by Donald Knuth in a book by that very name.
>
> I aim to reduce the size of large methods by factoring the component
> expressions into other methods or even into new classes of objects.
>
> Sometimes a method is just trying to do too much in a single place. In this
> case it's easy to refactor it into multiple methods and quite often you
> gain flexibility in the object. Other times what the method needs to do is
> just too complex a process with too much state needed to be remembered
> between expressions and refactoring it into an object is suggested.
>
> Often when I can't get a method down to a resonable size I consider if it
> should be it's own object with instance variables instead of temporaries.
> Complex methods usually work better when they are an object and have an
> extra benefit - they can be reused outside of the original design context.
>
> An example is in order. Recently I was writing a Bezier Curve calculation
> method and it was getting too big and complex so I refactored it into it's
> own object. It's now reusable beyond the initial useage (the curve of a
> roadway in an engineering application) and I've added additional methods
> that were not in the original requirements (like displaying itself on a
> bitmap). In addition as an object it now takes advantage of caching some of
> the calculated values (in instance variables) to improve the performance on
> subsequent message requests that it receives.
>
> Another way to know if your method is getting a bit unwieldy is if it has
> lots of parameters (or if when breaking it apart it the new factored
> methods would have lots of parameters). This results when you have a
> complex method that is implementing a complex process with lots of
> calculations (i.e. engineering software) where you must have lots of
> temporaries to maintain the "computational" state. Again this is an ideal
> candidate for a new kind of object.
>
> Unfortunately, calculation intensive methods or complex methods can't
> always use collections (of whatever kind) to come to the rescue. A
> combination of refactoring techniques such as splitting the method,
> reorganizing it into an object, rethinking how it's written by making use
> of other existing objects, removing unnecessary temporaries (like my use of
> temporaries for easier debugging), and other techniques can assist you in
> making your code easier to create, debug, test, maintain, and reuse.
>
> A similar problem exists for objects. Lets say that you took a overly
> complex method with 25 temporaries and made it an object. If the object has
> 25 variables maybe it needs to be refactored. Then agian maybe not all the
> 25 variables would need to become instance variables as some of them would
> work just fine as temporaries... It's just not so cut and dry.
>
> I wrote a 3D matrix transformation class last summer for 3D graphics. It
> has 16 instance variables to hold the 4x4 matrix of floating point numbers
> and 1 instance variable for a flag. I am considering adding a few more
> flags to improve the performance with optimizations in some obscure, but
> sometimes frequently used situations. This is a lot of instance variables
> in an object. But their use is justified for performance and space reasons.
> The code just runs faster using this approach than a collection to hold the
> matrix.
>
> I once had an object with 22 instance variables (it implemented a full
> object oriented drag and drop in VisualWorks Smalltalk in 1992). This was a
> lot of instance variables. I could only have reduced it by a few instance
> variables as their were many calculations and I wanted to cache the values
> for clairity, performance and debugging reasons. I took a lot of flak from
> one of the original designers of Smalltalk (with whom I worked with at the
> time). But the 22 variables were defensible and I could show why each an
> every variable was needed. For the 2 or 3 variables that were "extraneous"
> I defended them on the basis of clarity and debugging - I would not remove
> them JUST to reduce the count of the variables as this would obfuscate the
> object and make it harder to debug in operation. It's difficult to debug a
> realtime user controlled process so having the extra information around
> later helps understand how it's working or not working. Also the object was
> already collaborating with other custom objects to support the objects
> being dragged so it could not obviously be "refactored" into multiple
> classes.
>
> When using this many temporary or instance variables I highly recommend
> that you take extra time and care to document the method or object. A clear
> and complete explaination of the use of each variable can save someone a
> lot of time in understanding the reason behind the large number of
> variables.
>
> One of the key reasons to limit the size of the number of variables in a
> method or object or the number of lines in a method is that studies of
> humans reveal that people can hold 7+-2 (5 to 9) things in their conscious
> mind at a time. This is why phone numbers are seven digits. When you have
> more than 7+-2 items you need to chunk them into pieces. Thus area codes.
> 888-123-4567 are born. It just makes it easier for the human brain to
> process and remember.
>
> I thought that I was bad with 22 variables in an object. The most
> extreeeeeeeeeeeeme case of too many variables I've come across is a
> "relational table" that someone insisted on translating directly to one
> class of object. The table, and then the object, had close to 300
> fields/instance variables. They were nuts to have done this. Even after
> refactoring it one of the object classes had over 50 variables! Uggg. I
> encouraged them to refactor some more, but they refused because the code
> was already working and the project was nearing completion. Yuck.
>
> Good design and implementation is not cut and dry. It's fuzzy. Guidelines
> are just like a hiking tail through the woods. It's ok to leave the trail
> sometimes as long as you can backtrack or have a compass and map to get
> back to the trail.
>
> If it's at all possible keep your methods slim and easy to read.
>
> All the best,
>
> Peter William Lount
> http://www.smalltalk.org
> peter at smalltalk.org
> Copyright 1999 by Peter William Lount. All rights reserved.





More information about the Squeak-dev mailing list