Whitespace is Significant

While I was in my first couple years of college, Python was gaining traction as a hot new programming language. I had been programming in C since high school, but was curious about new languages. I took an interest in learning more about Python. A classmate told me that whitespace (at least indentation) was significant in Python. I changed my mind.

The Holy Wars of Indentation Style

It's interesting that would've been so turned off by a language that placed significance on whitespace and indentation, when I had fantasized about holy wars revolving around C indentation style (Horstmann is the only way!) and tabs vs. spaces (tabs, tab width 4!). I wretched at anything in the GNU C coding style (okay, I still do...), but the funny thing was, I never was able to program in a consistent style: There were other co-workers who had a slightly different preferred style. I was also learning myself, so relative importance of information in code changed, and my opinions on bracing style evolved.

Non-C Languages that Use Curly Braces for Things

It was a combination of Java, JavaScript, Perl, and Ruby that altered my perception of "proper" bracing style (BUT NOT SPACES OVER TABS!). A new line after a conditional or function declaration/call before the brace either took up unnecessary amounts of space, or changed the meaning of the code altogether (e.g., blocks in ruby, for which adding a newline = syntax error). And so, I evolved into declaring that 1TBS style was the only proper way to write C (WITH TABS!)

Ruby

Ruby has a generally accepted coding style that is enforced by no one except for code reviewers and maybe draconian RuboCop build configurations. I'd link to the coding style, if I had any certainty that the one I grabbed was 99% correct. Even RubyMine doesn't format code to the same standards as RuboCop.  (Continuation indent and spacing around braces were two settings I had to tweak.)

Small inconsistencies aside, Ruby code has ended up being the most consistent—visually—to support and add code to. I've introduced tighter RuboCop configurations on newer projects to try to adhere more closely to generally accepted coding style for Ruby.

Ruby also introduced me to an acceptance of significant whitespace. While C code often gets sloppy with spacing around punctuation markers in code, Ruby developers take more care in proper whitespace around the conditionals, braces, etc. Some C/C++ projects like Mozilla do similar standards. However, Ruby is the first language that I've seen a community-wide interest in code that presents in the same manner. Of course, most of this code isn't syntactically significant, but it is of human significance--and humans have their own mental compilers that optimize on standard patterns.

Still, this isn't the largest impact Ruby has had on my opinion of significant whitespace. Through Ruby, I've been exposed to YAML, HAML, and Slim. (I have dibs on forming a band of Rubyists with that name!) All three languages are unforgiving about inconsistent indentation. They take out explicit expression of boundaries and create visually implicit boundaries via hierarchies of indents. You don't need to look for an end or closing brace to know that the context has moved up a level. The indentation tells you where that happens.

(And yes, because of the generally accepted coding style in Ruby, I use 2 spaces instead of tabs now.)

Golang

And yet, Ruby coding style is informal. You can code in improper style and still commit your code and/or run it. There's something about having the freedom to write improper style and being able to be a good "citizen" on your own that is comforting.

Go does not do this. Writing Go in any editor configured to code in it (I've been using the vim-go plugin) automatically formats via gofmt.  It's pretty unsettling. I longed for the ability to become dictator over coding styles, and then was okay when Ruby dictated one, but gave us the autonomy to do the right thing. This auto-formatting? This is tyranny!

But, perhaps, it's time. We can mentally chunk pieces into larger concepts for storage, if code that does the same thing looks the code. Instead of having to remember every brace as an individual piece, we can put "for loop that iterates and prints" as a single chunk.

A stray brace isn't going to permanently prevent distillation into larger chunks; it will just take a higher cognitive load to get there. This in turn will require more experience with the language before a programmer can make that leap. Being able to break things into large chunks helps us discover the what instead of dwelling on the how.

Lua Script to Start, Unhide, and/or Auto-Arrange

I'm starting to try using HammerSpoon, which is driven by Lua, for automatically arranging my applications depending on application scenarios.

I have 3 screens, including a MacBook Pro at Retina native resolution and a Seiki 4K display. I grabbed the names of the monitors from Display Menu's menu bar menu.

I initially made the mistake of looking for "Outlook", "OneNote", and "Chrome", but all three applications require their respective company's names to be included in the application name.

Hammerspoon Lua Script - Split Windows 3x3

I've been using using Spectacle pretty heavily, but with a larger screen, I always felt like quadrants were a poor use of real estate, so I began to crack open the source code, which was pretty challenging to navigate because it's a mix of JavaScript and Objective-C reminiscent of user interface programming from ages past. So, I turned next to Hammerspoon.

Hammerspoon uses Lua as a programming interface. I was able to automate moving windows around a 3x3 grid on the current screen with 18 lines of code.

Pundit: NoMethodError (undefined method `verify_authorized' for [WhateversController])

Sometimes, having done things several times before can make you miss the OBVIOUS.

After adding

  after_action :verify_authorized

to my ApplicationController to verify that Pundit was being used for authorization, I got the following error in rspec:

  2) Jobs GET /jobs works! (now write some real specs)
     Failure/Error: get jobs_path
     NoMethodError:
       undefined method `verify_authorized' for #
     # ./spec/requests/jobs_spec.rb:6:in `block (3 levels) in '

Maybe there's a problem with my RSpec? Nope:

Started GET "/" for 127.0.0.1 at 2015-07-31 07:13:17 -0500
Processing by JobsController#index as HTML
  Job Load (0.1ms)  SELECT "jobs".* FROM "jobs"
  Rendered jobs/index.html.slim within layouts/application (0.5ms)
Completed 500 Internal Server Error in 8ms

NoMethodError (undefined method `verify_authorized' for #):

Okay, does ApplicationController have the method?!

irb(main):008:0> ApplicationController.new.methods.include? :verify_authorized
=> false

Ok, am I doing that wrong?

irb(main):010:0> ApplicationController.new.methods.include? :authenticate_user!
=> true

Sigh. *Rereads documentation.*

Screenshot 2015-07-31 07.25.24

What's missing? Oh yeah, a simple `include Pundit' in the ApplicationController
8729962194_b4cc81b2ee_z

Programming Style: Language Specific Domains

My Beginner and C Days

The visual presentation of the code has mattered to me, from the first days I wrote C code in Microsoft editor. In those days, it was a Microsoft C 5.0 IDE on either DOS or OS/2.

#include "stdio.h"
main()
{
 
	int rows,columns,ROW, COLUMN;
	scanf("%d %d",&ROW,&COLUMN);
	rows = 0;
	columns = 0;
	while(columns++ < COLUMN)
		printf("\xdb");
	printf("\n");
	rows += 1;
	while(rows++ < (ROW - 2)){
		columns = 0;
		printf("\xdb");
		while(columns++ < (COLUMN - 2)){
			printf(" ");
			}
		printf("\xdb\n");
		}
	columns = 0;
	while(columns++ < COLUMN) {
		printf("\xdb");
		}
 
 
}

Ok, not *that* far back, but I did have strong opinions about C from the early days of my being paid to program in it:

  • TABS, not spaces
  • 3 (in Microsoft land) spaces per tab (eventually switched to 4)
  • always include braces for if clauses
  • generally no parentheses for return values
  • ternary operator GOOD

That made the code look like this (except that tabs are tabs in pre blocks).

 
int compare(const void *a, const void *b)
{
	return(strcmp(*(char **)a, *(char **)b));
}
 
int checkDictionary(char *word)
{
	if(!dictionary)
	{
		loadDictionary("WORD.LST");
	}
	if(bsearch((void *)&word, (void*)dictionary, wordCount, sizeof(char *), compare))
	{
		return 1;
	}
	return 0;
}

But I remember so much variation in coding style preferences, as evidenced by the Indent Style article on Wikipedia. Everyone had their own preferred style, and everyone had their own preference for how much everyone else should adhere to a common style. On one team I worked, they eventually developed code reviews which were nothing more than berating people for not adhering to an arbitrary style guide: an in-house version Hungarian Notation, exactly one return per function, etc.

Java and Perl days

In Java land, my preference for camelCasing was reaffirmed. Working with Perl and Java, I eventually started putting the opening brace on the same line as if statements and function declarations.

if(iAmAChangedProgrammer) {
   hugWithBraces();
}

I think the brace thing was a result of a block that evaluated differently in awk or perl if it didn't hug the clause. I don't remember, but from that point on, I was convinced of that way being the only way.

Ruby

Coming into ruby has been interesting. Multiple returns (which never bothered me) are common. Implicit returns are the norm as well. There's a style guide which, for the most part, experienced rubyists adhere to (even if there are slight variations in practice). I find some disagreement with some of the style recommendations (I think I have found legit use for and over &&, etc...), but I'm happy to fall in line with the style recommendations and help enforce them.

Some of the styles have obvious purpose, but some seem rather arbitrary. Why are guard clauses so accepted in Ruby when C was so scared of them, etc...

Smalltalk

In reading Smalltalk Best Practice Patterns, it all came together.

As part of the style guide near the end of the book, the author talks about using the line-wrapping of the browser window to naturally wrap argument lists instead of taking up vertical space with them. That's when it dawned on me how much preferences in code styles also come from the languages that influenced the current language.

Ruby's heritage from Smalltalk means that it carried forward that aversion to deep nesting that performs poorly in small code browser windows (even in Squeak and Pharo, the code windows can get pretty tiny.)

C coders may have come from GOSUB type languages where there truly was only one return (unless an IF clause buried another) and there could be multiple entry points. Multiple entry and exit point aversion came from languages in which you could GOSUB to anywhere before a RETURN statement, and a nested RETURN could be harder to detect than one on the main logic level.

Conclusion

Early language coding styles likely came from specific pain points experienced by a prior guru and then arbitrarily passed along because "We've always done it that way." At some point, tasks and readable code become hindered by following rules that we don't have a rationale behind.

Community style guides hopefully have the benefit of thousands of years of cumulative experience in challenges and best practices collaborating on equal footing, but that assumes that we're not just agreeing with our technical elders because that's the way it's always been done.

Try to understand the problem domain of coding in a specific language as it relates to coding style. Maybe your coding style thinks its still programming in COBOL or BASIC.

Naive palindrome substring check written in C.

Below is a quick and naive implementation of a palindrome substring checker written in C. All characters are considered part of the palindrome (i.e. whitespace and punctuation is not filtered out). Substrings of larger palindromes are also printed separately.

 
#include <stdio.h>
#include <string.h>
 
/*
 * printPalindromes - prints all palindromes in 
 *  a string, including substrings of larger 
 *  palindromes. Treats all characters as 
 *  a valid palindrome character, including 
 *  whitespace and punctuation.
 */
void printPalindromes(char *inputString) {
    int center;
    int offset;
    int length = strlen(inputString);
 
    /* odd-sized palindrome is a minimum 3 characters,
     * so center must at least be 1 more than 0, and 
     * must be at least 1 space from the last element.
     *
     * left side: center - offset
     * right side: center + offset
     */
    for(center = 1; center < length - 2; center++) {
      for (offset = 1; 
          center + offset < length 
          && center - offset >= 0
          && inputString[center + offset] == inputString[center - offset];
          offset++) {
        // print subString from center - offset to center + offset
        printf("%.*sn", offset * 2 + 1, &inputString[center - offset]);
      }
    }
    /* even-sized palindrome is a minimum of 2 characters
     * (the center). Center and center + 1 must match for even
     * length
     */
    for(center = 0; center < length - 3; center ++) {
      if(inputString[center] != inputString[center + 1]) {
        continue;
      }
      /* we know this matches by default */
      printf("%.2sn", &inputString[center]);
 
      /* offsets on the right side are one over because "center"
       * is actually 2 characters.
       * left side: center - offset
       * right side: center + offset + 1
       */
      for(offset = 1;
          center + offset + 1 < length
          && center - offset >= 0
          && inputString[center + offset + 1] == inputString[center - offset];
          offset ++) {
        // print subString from center - offset to center + offset + 1
        printf("%.*sn", offset * 2 + 2, &inputString[center - offset]);
      }
    }
}
 
int main(int argc, char **argv) {
  int arg;
 
  for(arg=1; arg < argc; arg++) {
    printPalindromes(argv[arg]);
  }
}

Example results:


CostaRica:c thomaspowell$ ./palindromes "why forerof baad baab ddi"
rer
orero
forerof
 forerof 
aa
aa
baab
 baab 
d baab d

Trying to Dig a Little More In-Depth With Maven

I've been reading Maven: The Definitive Guide (affiliate link) as a Kindle eBook and finally got to the point of trying the first example project. The book had mentioned that maven might be installed on Mac OS X already (due to usage with some versions of XCode). Magically, it's there:

So far, I like the book's approach to Maven.  It evangelizes maven as a tool, but puts the purpose of Maven in context, and explains, "Why Maven?" as well as explaining that "Maven or Ant?" is the wrong question.

If you're looking to download the files to complete the example Maven projects, they've moved from the URLs in the Kindle version of the book because Maven: The Definitive Guide has been split into two books, Maven by Example and Maven: The Complete Reference.

All the project examples can still be downloaded from a single zip file from the Maven by Example book. However, the chapter numbers are not the same in the Maven by Example book, and the folders in the examples are named by a chap-{title} convention.

Within the zip file:

  • Chapter 4's project (Simple Weather Application) (originally at http://www.sonatype.com/book/mvn-examples-1.0.zip or http://www.sonatype.com/book/mvn-examples-1.0.tar.gz) is now available in the zip file under:
    • ch-custom/simple-weather
  • Chapter 5's project (Simple Web Application)
    • ch-simple-web/simple-webapp

 

 

Java code to test if a string is a valid java identifier.

public class IdentifierTest {
 
    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
        for(String arg : args) {
            boolean start = true;
            boolean validIdentifier = true;
            arg.toCharArray() 
            // commenter pointed out my error
            //for(byte b : arg.getBytes()) {
            for(char b : arg.toCharArray()) {
                if(start) {
                    validIdentifier = validIdentifier && Character.isJavaIdentifierStart(b);
                    start = false;
                } else {
                    validIdentifier = validIdentifier && Character.isJavaIdentifierPart(b);
                }
            }
            System.out.println("Identifier ""
            + arg + "" is "
            + (validIdentifier ? "" : "not ")
            + "valid");
        }
    }
}

Output:
>java IdentifierTest Test $ds ds$ 2" is not valid

Haskell resources

In order to reclaim some of our programming mojo that has waned from years of maintenance programming and meetings, a couple of us programmers decided to go and try to learn a completely new language--Haskell.

I think this expedition was spurred by a blog post titled Great resources to learn Haskell. I'm as much a math geek as I am a computer geek--I competed on my high school Math Team--so a functional programming language is a natural fit for my hobbyist interest.

Resources that I've used so far:

Learn You a Haskell for a Great Good! is an entertaining introduction to Haskell that reminds me a lot of Why's (Poignant) Guide to Ruby, but without the comic strip story telling.

Haskell for C Programmers is a online book that resonates well with me, because of my deep roots in C programming.

How I studied for the Sun Certified Java Programmer [SCJP] 6 Exam

Including an inline review of two SCJP study guides.

Disclaimer: This is not a guide to passing the test with zero experience and no preparation. The SCJP exam will quickly expose lack of working knowledge. I have roughly 15 years of experience with programming in C and derivative languages, including about 1 year of Java 1.1 through 1.5 and about 2 years of experience with C++.

Studying:

Note: Book links are paid Amazon associate links.

Week 1:

Week 2:

Week 3:

  • Took the "self test" questions at the end of every section of the SCJP 6 book. Got only 51% correct.
  • Hand wrote the answers or a fuller explanation of the answers for every question I got wrong.
  • Took the Programmer's Guide mock exam. When I checked the answers, I noticed that the questions would say something like "select the 2 correct answers" and the answers would give 3 answers, or vice versa. Once I realized how bad the editing was on this book, I stopped using it.
  • Re-took the "self test" questions at the end of every section of the SCJP 6 book. Got only 88% correct. This time, I read through the answer explanations for the incorrect answers, and then re-read the "Two Minute Drill" sections for my two worst sections.

I believe that the SCJP 6 helped me because the format of the questions [choose all that apply] was ultimately harder than the format of the actual certification test questions. The Programmer's Guide "mock test" format was closer to the actual test format, but I spent way too much time reconciling the test answers and test questions for it to be useful.

Other factors and more detail that you may not care about:

I had the opportunity through to take a class [June 7-June 11 2010] to become certified as a Sun Certified Java Programmer for Version 5. The book used in the class was [SCJP 5 study guide]. At the end of the class, we were presented with the option of registering for either the SCJP version 5 or SCJP version 6 exam by the end of June 2010. I took the risk that I could study the gaps between the Java 5 and Java 6 and pass the SCJP version 6 exam. Little did I realize that the studying effort would be a little more challenging than I first thought.

I had originally read through the Java 1.5 Tiger: A Developer's Notebook (Java 5,Version 1.5) when Java 1.5 was brand new [5 years ago]. Since then, I have done a small amount of maintenance programming, which got me familiar with a few of the advanced concepts. In addition, the concept of generics was familiar as C++ templates and I have my basic computer science engineering classes from 16 years ago as a foundation for it all.