Tuesday, May 27, 2014

Golang: Formatting Your Code with Gofmt

Contrary to what some may think, I do try to keep several balls in the air; work obligations, the podcast (Geeking After Dark), and (when I have a good block of time along with a solid idea of what small step I want to accomplish) my organically mutating GoLang experiment, all being kept in the air as I try to fit in a functional amount of sleep. Recently I have been losing more sleep than usual to the stress of finding a new apartment, and now am in the middle of a rats nest involving the arrangements that come with trying to actually move locations.

Good times!

But through all this I still managed to get an occasional commit on my personal Go project.

Learning to program with a personal project in a language you haven't used before can be an almost zen-like experience. I'm hitting all sorts of moments when I sort of feel like I'm starting to understand why certain memes and practices are in place, and using a language that itself is the product of insights gleaned from perceived design issues with other languages allows me to take advantage of certain aspects encouraged in the programming language. Rarely will you find a language where the users keep asking each other for help in the form of, "What is the idiomatic way to do this?"

The last time I found a language that had such a strong "This is the proper way to do this in this language even though you can get it to work doing it a different way but we'll judge you for doing it wrong" vibe it came from books introducing new programmers to Ruby on Rails. Not that this was a bad thing; I feel that in a proper context with a proper design, it's possible that the "proper" way of doing something in that language ends up just feeling better and being more readable.

Readability...often subjective, and something that can (and does) spawn huge threads of argument. It's probably where much of the push for newer programming communities to have a canonical proper way to do things originated.

I was looking up information for implementing a feature fermenting in my head when I discovered that Go, despite being a relative newborn in the field of programming languages, has a utility in the standard suite of tools meant to help you format your source code in the proper way.

I used it, and I really like it.

all you have to do is:

gofmt -w yoursourcecode.go

...and it'll replace your .go file with a reformatted file. While I didn't have (from what I could tell) huge changes, it did spruce my stuff up a bit. And it looks, so far, like it didn't break anything. If you just run gofmt without the -w, it'll write the output to standard output, which you could direct to a new file through redirection if you were so inclined.

Gofmt actually has a few options you can use to try streamlining things by eliminating extra parens and such. I haven't experimented with it; being relatively new,  I sometimes prefer being overly explicit in what I place into my sources so I have less trouble figuring out what I'm trying to accomplish later on; besides, the compiler removes and optimizes much of my inefficiencies for me. For now I'm at a level where running gofmt before a commit will be a workflow insertion to help keep my source a little more clean, and it also helps in learning the proper way to format source code.

If you're new to programming and trying to learn Go, try using gofmt in your workflow. Use the resulting files to absorb what is considered good practices in writing clean-looking and maintainable source. I won't say that it's perfect, but it should at least point you in the right direction of creating source code files that are easier for others to read and maintain down the road, including for your future self.

Especially your future self. Trust me on that.

Monday, May 5, 2014

Creating Mini Applications to Learn More in the Process

The topic of how to approach developing programming skills is one I've discussed before, both on this blog and on the Geeking After Dark podcast. On the podcast, we (Pete and I) generally agreed that it was best to have a project in mind when trying to program; it gave you a goal to work towards, and you were solving a practical problem. Too often the exercises in programming classes seem boring; what't the point of creating an application that counts to 10, unless it's a prime number?

I missed one another approach to improving programming skills; solving mini-problems. Unexpected things that crop up present opportunities; scripting tasks can be done with actual scripts, or you can try creating small, compiled utilities for future use...scripts on steroids.

 I've been working on a project for awhile that involves creating kiosk-like functionality on a few select laptops. A utility was installed whose purpose was to restore the systems to a specific configuration when restarted; that way users could save files or reconfigure the system and it would go back to its pre-login state. 

I had a few issues with them that led me to believe things weren't working the way they were supposed to, but one of the big ones that I definitely could tell wasn't happening was the setting that told the laptops to automatically reboot every X minutes. 

In the course discussing the problem with their tech support, they said they spoke to the developers and it used the same mechanism (GetLastInputInfo) as the Windows screen saver for determining when to trigger the reboot. They suggested I set the screen saver to run 5 minutes before the reboot was supposed to happen to see if something wasn't resetting the idle counter. 

I thought there had to be a way to get a more direct way to get the counter setting; as I had been playing with Go, maybe that had a method of printing that value. 

Why Go? It's fast. It compiles to work on multiple platforms. It seems pretty flexible. And it compiles a single executable, so there's no need to install a framework or support libraries. Or even run an installer. Plus it's the language I've been recently trying to learn. 

The initial problem wasn't simple to solve; turns out there isn't a direct way to access an API call on Windows using Go. I asked for help on Stack Overflow and fortunately found someone who gave a thorough response; Go has a mechanism for indirectly getting information from API functions. 

The code snippets he gave worked rather well, but reading the code made me think that there was no way I would have figured it out on my own; this was rather disheartening. Once again the "programming makes me feel dumb" bug was biting; it was a profession for people with some kind of innate ability that I lacked. 

I approached a developer working at our company (and who was also playing with Go in his spare time) to ask him for some advice. In part I said,

I’m not entirely sure I understand it, and am hoping that the process of implementing it will shed some light on how it works, but…this is where it seems like there’s a cliff between compiling “Hello, world!” and “WTF is this?” 
So as an experienced developer that looks at that question and probably sees it as, “Of course that’s how you do it!,” where and how do you think that cliff is scaled? Just experience? Is there a thought process or some comprehension that I’m simply missing?

I was still anxious to ask this since I felt that it made me look as stupid as I felt, plus this was a coworker I looked up to. I had to set aside the hero worship part of my brain and instead cash in the reality check that he was an actual person who might be willing to spend a few minutes to offer some encouragement. And he came through. His reply read in part,

Programming experience does have the quality of amassing an amount of trivia (like this) over time. And devs have a habit of making one feel like you should have known that. But no, you shouldn't have known that. You might have known it, or not. 
There are problems that are a test of smarts, but this one has more to do with whether you happen to have been down a very specific road before. Hope this helps! 

That's the kind of encouragement that helps validate that it's okay to be confused or feel a little lost. So I kept with it and within a couple of days of after-hours tinkering, I had a very bare-bones utility that ran a loop dumping the current last input count; the API returns the Windows tick count when input was last recorded from the keyboard or mouse.

So what was I missing?

The laptop was set to run as a kiosk; it booted up and logged in as a non-privileged account, with access from the desktop to a few basic communication tools. When the computer logs in automatically, the tick count reads 0. Let the computer sit until it was supposed to reboot, nothing happened. Let it sit for a bit then hit a key on the keyboard so the last input tick count was non-zero, wait the length of time for the automatic reboot, and it rebooted.

I sent this information to the company, and they realized that I was actually auto-logging in and it sounded like that wasn't a test case they'd tried, although it also sounded like this was purposely designed this way because otherwise it would reboot constantly without ever having been touched. The Windows screen saver didn't care if the counter was zero.

I won't get into the reasons why, yes, I'd like to reboot the computer anyway, because the point is that instead of having to indirectly test the state of the idle timer (which in this case it wouldn't help, since the screen saver counts an idle tick count of 0 and the utility didn't) I had a small utility that can give the accurate insight to what's happening.

It was a small project with a niche purpose, but it was useful and solved a problem while giving me some experience with the language, and it gave some information on how Windows treats login sessions and the scope of the idle timer (I tested at one point whether the mouse/keyboard being used on the laptop would be affected while I was logged into an RDP session, for example.)

You don't need a large project to assist in learning. Small, niche projects can be very useful as well. Mixed with the occasional bit of encouragement from those with more experience, and you have a pretty good recipe for building some programming experience.