Section 7.7: Side-effects in functions

30 December, 2009 § 6 Comments

I’ve been reading Bertrand Meyer’s Object-Oriented Software Construction recently and have enjoyed learning a bit about the Eiffel programming language (also written by Meyer) at the same time.

The book focuses on principles of OOP (such as modularity and re-usability), techniques (such as generics), and also discussions such as genericity versus inheritance.

While there are many great topics covered in the book, I wanted to first write a blog post about § 7.7: Side-effects in functions.

Side-effects in functions

C#, much like Eiffel, has the notion of properties and functions. Both of these can be used the exact same way. For example, a Point class may have a property Theta or a function Theta:

// C#
public class PointP {
   public double Theta { get { return 0.0; } }
   public double Rho { get { return 0.0; } }
}

public class PointF {
   public double Theta() { return 0.0; }
   public double Rho() { return 0.0; }
}

public class Test {
   public static void Main() {
      var ppoint = new PointP();
      var fpoint = new PointF();
      Debug.Assert( ppoint.Theta == fpoint.Theta() );
   }
}

While both can accomplish the same goal, there are semantic differences between the two. Meyer’s espouses that properties should be thought of as simple accessors, while functions may be thought of as mutators. Within Eiffel, this is referred to as the Command-Query Separation.

Therefore, functions like C’s getint() violate this principle, since they return the last integer seen on the input stream and advance the cursor at the same time. getint() is therefore an accessor and a mutator.

Accessors should have the property that they can be called multiple times with the same output each time.

Functions, in their most mathematical sense, should have the property that they can be called multiple times given the same input and have the same output each time.

In this example, Meyer would have written something like this:

/* C */
FILE input;
input.advance();
int lastSeenInteger = input.lastint;
ASSERT( 2 * input.lastint == input.lastint + input.lastint );

The same cannot be said for getint().

While we have now achieved an arguably better solution than what existed before, Meyer leaves the reader to decide if the function should mutate itself or return a mutated object. I will take this opportunity to conclude on his discussion.

Taking away the guesswork

At this point, it is up to the programmer to know if the function is going to mutate itself or return the mutated object. The programmer may check the interface of the class explicitly, or use features of their IDE to tell them if this function returns a void or a separate FILE reference.

By convention, Ruby solves this problem by using an exclamation point at the end of the function name to be explicit that the function will change the internal state of the object.

# Ruby
input_b = input_a.advance
b_last_int = input_b.lastint
input_a.advance!
a_last_int = input_a.lastint
assert( a_last_int == b_last_int )

Conventions like these remove guesswork out of the equation and allow the developer to know when they are calling a function with side-effects.

Readability is key

In the end, we as software developers should strive for the most readable and maintainable code. Each one of these tools, like side-effect function conventions in Ruby, should allow us to achieve this goal.

Do you have any conventions that you use or know of that call out side-effects in functions?

Finished Reading Clean Code

20 December, 2009 § 2 Comments

Today I finished reading Clean Code by Robert Martin aka Uncle Bob. I found out about the book from some coworkers during our weekly programming-discussion meetings. The book claims to leave its readers understanding:

  • How to tell the difference between good and bad code
  • How to write good code and how to transform bad code into good code
  • How to create good names, good functions, good objects, and good classes
  • How to format code for maximum readability
  • How to implement complete error handling without obscuring code logic
  • How to unit test and practice test-driven development

Part 1: Principles, Practices, and Patterns

I really liked part one of the book. The principles, practices, and patterns are well thought out and provide a style of programming that is, unfortunately, rarely seen. Since reading this part, I’ve been writing smaller functions (about 4-5 lines at max) and have seen a payoff in the amount of reusability and readability. Chapters 1-7 read quickly, are informative, and are really great pieces to read.

Part 2: Case Studies

The pace of the book really drops off after chapter 7, and each subsequent chapter I lost more of that urge to pick up the book and continue reading. The final nail in the coffin that actually put me to sleep once was the Case Studies part (chapters 14-16). The example of the Args module was too large and my internal-brain compiler just couldn’t handle JITting three pages of code at once. I pushed through and read this whole part, but I wouldn’t recommend you doing the same.

Part 3: Code Smells

Part three is one chapter long and focuses on Code Smells. Code Smells are patterns in code that when seen give a bad taste in your mouth. They are implementations that shout that they could have been done better. The longer the code smells, the worse it gets, until finally the abomination that once started out as a faint odor now is the muskiness in the room that scares off developers from maintaining the module. This chapter is important to get familiar with. It might not be too useful to memorize the different smells, but knowing which ones exist is good enough, because you can always come back to this chapter to see how the code can be refactored.

Unit Testing

The last item I wanted to cover was unit testing. While the book mentions unit testing a lot, and devotes a chapter towards it, I don’t feel like developers will walk away from this book with an understanding of unit tests and test-driven development. Any developer looking for further understanding on unit tests should pick up a book that is devoted to the practice, since there is just far too much to cover in one chapter. I would recommend reading Test Driven Development: By Example.

Book Review: The Plot

11 August, 2009 § 2 Comments

After talking with a friend of mine about World War II, he mentioned that he had a book that I might be interested in. When I met him this past Sunday for our weekly poetry meeting, he gave me a copy of the book.

“The Plot” by Will Eisner is a graphic novel that covers the history of “The Protocols of the Elders of Zion“. “The Protocols” is a document authored by Mathieu Golovinski that describes the so-called plan for the Jewish leaders of the world to take over. There has been much proof and many rulings that have claimed this work to be false and that it is in fact a plagiarism of  “The Dialogue in Hell Between Machiavelli and Montesquiue” by Marice Joly.

Joly wrote his book to compare Napolean III, the current emperor of France in 1878, to Niccolò Machiavelli, a man regarded for his “use of cunning and deceitful tactics in politics or in general“. When Russia faced political unrest in the early 1900s, Golovinski was assigned to produce propaganda that would lay blame to the Jewish citizens of Russia for all of the problems.

“The Protocols” has since been translated to numerous languages and cited by the likes of famous antisemites Adolf Hitler, Anwar Sadat, Henry Ford, and Louis Farrakhan.

The opening quote of the novel says that “whenever one group of people is taught to hate another, a lie is created to inflame the hatred and justify a plot”. Previous to reading the graphic novel, I had never heard of “The Protocols”. After learning of them, I feel that I have a better understanding as to why there is so much hate towards the Jewish people of the world. The spread of these lies continues to this day.

The production of “The Protocols” has led to many lost lives and even more hatred. It is no wonder that when a new book or film enters the market that contains possible antisemitic content such as The Passion of Christ or Borat that Jews and their allies worry for their safety.

At 148 pages, the book is a quick read. I read the book over three days (maybe totaling 4 or 5 hours). I appreciate the book recommendation and will be adding it to my recommend reading page. Thanks Ken.

What You Learn When You Read

5 August, 2009 § 1 Comment

It is pretty discouraging to learn that most programmers don’t read books. I’ve taken it upon myself to buck the trend and try to read as many books as possible this summer while I take a break from my graduate courses. Over the summer, I’ve read the following books:

  • Effective C++
  • More Effective C++
  • Test-Driven Development: By Example
  • The Pragmatic Programmer: From Journeyman to Master
  • Peopleware: Productive Products and Teams
  • Best Kept Secrets of Peer Code Reviews

The following books I’ve read bits and pieces of:

  • Effective STL (I’ve read about half of the book)
  • C++ Template Metaprogramming (I read the first 60-70 pages)
  • The C++ Programming Language: 3rd Edition (I read about 2/3 of the book)
  • Le Ton beau de Marot: In Praise of the Music Of Language (the first couple of chapters)

I’ve stopped reading the above books for different reasons. Effective STL was very interesting, but my day-to-day work doesn’t use much from the STL and I found it hard to think of applications where I could play with what I was learning (although I must admit I am now able to think about those applications when refactoring/fixing bugs/implementing new features). C++ Template Metaprogramming was genius in the way that you can get so much computed at compile-time, yet the syntax and obscure corners made it hard to write good demo and test programs. The C++ Programming Language is an all-around great book! I highly recommend it. The book walks you through all of the C++ (and some C) language, yet I stopped reading it to pick up another book (which I’ll get to later). Le Ton beau de Marot is an interesting book about a French poet and the work done to translate his poems to other languages. I picked it up to read as a somewhat abstract reading on the side effects of translating software from one programming language to another (or maybe even just working between two branches of a code base that start to diverge).

The book that I’m currently reading and hope to have finished in the next week or so is called The Design and Evolution of C++, written by Bjarne Stroustup. In the book, Stroustrup talks about many of the design decisions that had to be made when creating C++ and lots of background in the syntax that I’ve wondered about ever since first learning C++. I plan to make a full post in a week or so about all the topics that I’ve learned about while reading the book, but right now I hope to cover just a sampling of the book.

C++ gets most of its roots from Simula

When Bjarne was working on C with Classes, he had just come off of working on a project in BCPL and hoped to obtain the speed of C with the object oriented paradigm of classes found in Simula. It is helpful to know where most of the syntax ideas come from. If you’ve ever wondered by C++ uses this as a pointer and not self, it’s because of Simula. Smalltalk uses self. The only artifact from BCPL is the single line comment //.

The first C++ compiler was written as a precompiler for C

When the syntax for C++ was defined, it was too complicated/costly to use software like Lex and Yacc to create the grammar rules. In the idea of time savings, Cfront was developed as a C code generator which read in C++ syntax and converted it to C code. I found this as an interesting take on compiler design and a simple way to introduce language rules and enforce them without building your own compiler. Over time, commercial compiler companies have created their own C++ compiler, reducing the need to parse the code on two passes.

Stack-only objects

Ever wanted to write a class that could not be allocated on the free store? Simply declare a privately scoped operator new() for the class. While C required that the user allocate memory on the free store (through malloc) and then initialize the memory, C++ combines both of those operations in operator new. If operator new is inaccessible, then the memory allocation for that object will fail. This will generate a compile-time error. (The obvious way around this is to continue using malloc, but if a developer is malicious then it will be impossible for a compiler to stop them).

I am really excited about this book! There are some really cool historical facts about the language and also some great code examples. If you’ve got the time and a library card, I suggest you go check out a copy of the book. You’ll thank yourself that you did.

What I’m Currently Reading

20 June, 2009 § 5 Comments

I’ve been reading The C++ Programming Language: 3rd Edition now for a week and am really enjoying the book. Bjarne Stroustrup, the creator of C++, has explained techniques that I didn’t understand well before.

So far, I’ve only finished reading the Introduction, which includes a tour of C++ and the Standard Library. While reading the book, I’ve been trying out some of the programming samples that I’m less familiar in a sandbox. I’ve already found a couple more ways that I can use the STL, such as find_if and mem_fun.

I’m looking forward to the next 944 pages!

Where Am I?

You are currently browsing the Book Readings category at JAWS.