Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

Wednesday, March 7, 2012

#17 - Putting the Meth in Method

Functions and procedures are old hat. Those ideas were conceived of not only before I started earning a paycheck in Software, but before I myself was even conceived. Modern programmers use more current techniques like Object Oriented programming. A technique that was conceived of over a decade after functions and procedures were, and was still, sadly, before I was conceived. It's not modern, it's just the modern fashion.

class FizzBuzzer(max: Int) {
    var i:Int = 0
    val max:Int = max

    fun hasNext() : Boolean {
        return i < max
    }

    fun nextValue() : String {
        i++
        return when (i%15) {
            0 -> "FizzBuzz"
            5, 10 -> "Buzz"
            3, 6, 9, 12 -> "Fizz"
            else -> i.toString()
        }
    }
}

fun main(args : Array<String>) {
    val fizzer : FizzBuzzer = FizzBuzzer(100)
    while (fizzer.hasNext()) {
        println(fizzer.nextValue())
    }
}

The implementation for this solution is one of an iterator. But we won't dwell on that since that isn't what we are looking at in this post. Similarly to talk about methods we have to embed them in a class, which is something we will just wave our hands over now and come back to later, because the true power of OO actually can be used to solve FizzBuzz. So I will wave my hands over that and move on to what you can't get enough of: methods.

The first thing you should notice about Kotlin classes is that the constructors are for the most part integrated into the class body. There is a notion of a primary constructor which is in place to discourage the proliferation of constructors. When combined with default parameters it handles nearly all the reasons for constructor proliferation, leaving for the most part only weird stuff like copy and pseudo-copy constructors. It is unclear in the current docs if there is any allowance for other constructors. I am not sure if this is a bad thing.

Next, we look at the member variables. In Kotlin all fields are properties by default. You can change this with a private modifier. Also, because fields are properties by default each property either must be initialized or have a get defined as part of the declaration. What is good practice in C (undefined fields can be practically random and a security risk), and implied in Java (zero, false, or null as appropriate) is compulsory in Kotlin.

When it come to actually instantiating an instance of the object on line 21 we see that the new operator is not required.  In fact, it is not even allowed! Calls to create objects look just like regular function calls. While you may argue that this limits the namespace of functions I counter by saying this is a good thing, since functions named like objects usually create bugs. Add in the practice that  class names generally get the German Noun treatment distinguishing a constructor call from a method call should be trivial.

Finally, an implementation note. It may look like the main function doesn't belong to a class. But because of the structure of the JVM it does belong in a class, as a static method of that class. The class is (currently) named namespace and it is declared in the package of the code it is written in.

Be careful when picking up Object Oriented programming. You may think you can stop anytime you want. But you won't ever want to. And when you try to stop, your language won't let you.  You will be coding methods for the rest of your life.  Even languages like Clojure are fooling you.  It's all methods all the time.

No comments:

Post a Comment