Monday, June 9, 2014

New Programmer Insecurity: Multiple Ways to Implement

I've been working on my GoLang side project for awhile now, and since I didn't sit down and write a specific set of specifications I ended up making a few changes in implementation along the way.

When I get a chance to work on the program, I'll make a few changes, add a small function, test it, and set it aside until my next chance to work on it. Recently I realized I wanted to make a few changes in how the functions...function. But when the application is run, there's no appearance that anything has changed.

That got me thinking about another aspect of beginners programming; another reason I feel fear creep in at the prospect of an experienced programmer looking at what I've done only to scoff at the work I've done. I have been working with the idea that, "As long as it works, I must be doing something kind of right."

Let's take a simple example. The simple, cliche test for a programmer new to a programming language is to have it spit out "Hello, world!" For most languages this isn't all that hard.

I create a hello_world.go file and populate it with the following:

package main

import "fmt"

func main() {

fmt.Println("Hello, world!")

}

Using "go run hello_world.go" yields simple results.

Let's make a simple change. Here's the new code:
package main

import "fmt"

func main() {

var hello string = "Hello, world!"

fmt.Printf("%s\n", hello)

}

A quick retest does this:

Look familiar?

Let's make another minor change.

package main

import "fmt"

func main() {

var hello string = "Hello, world!"

fmt.Println(hello)


}

Run again:

Hmm...still look familiar?

Here's something only slightly more advanced in technique...

package main

import "fmt"

func sayHello() {

var hello string = "Hello, world!"

fmt.Println(hello)

}

func main() {

sayHello()


}

What does it do?
Let's bump it up one more step.

package main

import "fmt"

func sayHello() (string) {

var hello string = "Hello, world!"

return hello

}

func main() {

greeting := sayHello()

fmt.Println(greeting)


}

I bet you can guess what the output looks like.
See a pattern?

The point is that this same output came from several similar, but different, implementations of code. Which of these implementations is "better"? Is there a better way, if the output is the same each time? What if there's another method that "should" be used but I don't know about?

Those are the thoughts that makes sharing source code, for beginning programmers, more of an exercise in anxiety. 

"Look! This is pretty awesome, yeah?"

"Sure. But...why did you do this? You should probably have done this instead."

Is there a sound pride makes as it deflates?

Worse, I'm not sure there is a way to definitely find answers to what the "best" way to do something is. Some languages, like Ruby, encourage a "Ruby Way" of thinking about program design. Other time, as you gain experience while trying to make an application, you gradually learn about ways to implement a function in a way that makes more sense doing it in a particular way than another. Only experience will demonstrate this, and thinking about the design of your application will lead to epiphanies of implementation.

Regardless, there is no simple "This is how you do it" solution, only fumbling through, trying to understand what you're doing and spending time reflecting on how it works so maybe you'll realize a better way to do it. Or you'll paint yourself into a corner, stuck until you find you must refactor how you did something so you can fix the point you're stuck in and move ahead again.

As for my project, I continue to move ahead on it, despite fears of how crappy the code is once it reaches a release-level in my head. There are several more functions to get working before I reach that point. Once there, I'll be proud of it, regardless of how well it works compared to a company application or how crappy the code is, as long as it mostly works as I envisioned. 

Because really...what else can I do?

No comments:

Post a Comment