Saturday, April 12, 2014

SMART goals vs organic growth

I suppose there is a book on goal-oriented activity vs organic growth. This is a short review of that possibly fictional book.

The basic idea is that there have been two ways of being in the world. One can be characterized as putting Man in the middle. The most important question is what Men want and need, what Men can achieve and get. The other way of being puts Man to the second rank, removes the capitals and claims that men are subordinated to X. What X is depends on many things, it can range from the greater good of humanity to God.

Image by Seier https://www.flickr.com/photos/seier/1244185274


Both approaches have inspired people to create wonderful buildings, books, and gadgets. And both approaches contributed to bloody wars and injustices. So none of them is right and none of them is better. Both have their strengths and their weaknesses. They have a lot to learn and borrow from each other and this is very difficult sometimes.

There are ages when the one has a lead, at other ages the other has the upper hand. The Medieval Age in Europe was about subjecting ourselves to a higher entity. The Renaissance turned it upside down.
Religion belongs to the organic growth approach most of the time, it emphasizes that the rules of life are way too complex for us to completely understand them. We are small balls on a huge snooker table of greater forces. It’s not something we should be sad about, those balls can have a full and wonderful life. They are just not the main characters or directors of the play.

Rationality, on the other hand, has typically a goal-oriented world view. That’s the dominant and powerful ideology of our age. Since it doesn’t trust any higher forces to arrange things for us, it needs to invent methods to do that. Ethics is replaced by management. What shall we do to others? It’s a question of how me manage them. What shall we do to our life? It’s a question of how we manage ourselves. Spirituality is replaced by goals, even SMART goals. SMART is an acronym that stands for Specific, Measurable, Assignable, Relevant, Time-bound.

The first part of the book goes to great lengths to analyze the two sides of this dichotomy. A number of issues are discussed from both view points. My favorite chapter is about how we make decisions based on these models and how we justify them. The modern way to evaluate an option is to use what the book calls economic justification which is based on a simple (and flawed) syllogism.
If people buy more of something, they think it’s more valuable.
If many people consider something valueable, then it is valuable.

If people buy more of something, then it is valuable.
The second part of the book takes an unexpected turn. It’s basically about software companies and their methodologies. Traditional software development is considered to be an example of a goal-oriented activity with lots of process, systems, all measurable and managed. The Agile turn gave rise to dynamic startups that have a different mindset. They say mantras, like Release early and often which may result, oh horrors, in missing features and buggy code. They say, YAGNI, short for You ain’t gonna need it, when a smart guy implements something for the sake of a possible future request.

But agile startups haven’t realized yet they differ not only in their methodology (and budget), but also in their philosophy. They are to become the new advocates of organic growth. To grow software organically is a humble and controversial approach. It basically says, don’t plan large systems, because they are impossible to implement. Create a small program, share it, find a place in the large ecosystem where it fits. This is exactly how open-source components and repositories work.

The last chapter of the book is a bit inconclusive. What I like about is the idea that software development will fully recognize its potential when the SMART goal will have its organic counterpart. Let me give it a try how it would sound
  • Holistic
  • Subjective
  • It’s done by many people, some of them even anonymous
  • Dreamlike
  • Take your time

Monday, February 17, 2014

Plain text screencast

“How do you install a foobar-quux?”, you hear it from the other side of the desk. “It’s easier to do than to explain”, you respond grabbing your keyboard. A few lines in the terminal and it’s done. You hesitate for a moment to write a neat script of what you’ve just done. But it’s not that easy, because… And it’s not worth it once you’re done. Until you hear the same question again in a week, “How did you install that foobar thing? It looked so easy, but I forgot.”
If you had a really lightweight screencast tool at hand which does nothing fancy, no screen resolution and frame rate settings. Just record what I do in the terminal.
The funny thing is this simple tool exists. It’s pretty old, actually, its first version was released in 2000. The original one is called ttyrec. It has quite some spinoffs. You can even upload it to the web and replay in the browser. I found more sites offering this service
My favorite one is Shelr.tv where you can change the replay speed.

Saturday, February 1, 2014

Rules to write functional Scala code and stay sane

Use only cases classes from the OOP world

Well, with some exceptions that will follow soon. But the baseline is: no regular classes, no inheritance. A case class can be considered an abstract data type, so it can serve as a container. Another use case for them can be seen as a little weird form of currying.

val people = List("Bob", "Mary")

// functional
def join(separator: String, list: List[String]): String = {
  list mkString separator
}

def joiner(separator: String) = {
  (list: List) => join(separator, list)
}

joiner(",")(people)

// with a case class
case class Joiner(separator: String) {
  def join(list: List[String]) = {
    list mkString separator
  }
}

Joiner(",") join people

Use traits only to simulate union types

There are cases when an instance can be one of two types, for example a tree node can be either a branch, or a leaf node. If we follow the above rule of using only case classes, we’ll be in trouble. This is where we can use a trait shared by some case classes.

trait TreeNode {}

case class Leaf(value: String) extends TreeNode {}

case class Branch(left: TreeNode, right: TreeNode) extends TreeNode {}
It’s OK to add methods to the trait if they would be shared by the case classes. (It would be difficult to use this tree example, because that would lead us to the field of recursive data types.)
trait NDArray {
  def rank: Int
  def isScalar = {
    rank == 0
  }
}

case class Scalar(value: Double) extends NDArray {
  def rank: Int = 0
}

case class Matrix(elems: List[Any]) extends NDArray {
  def rank: Int = {
    elems.headOption match {
      case Some(x: NDArray) => 1 + x.rank
      case None => 1
      case Some(_) => 1
    }
  }
}

Matrix(List(4)).rank // => 1
Matrix(List(Matrix(List(5)))).rank // => 2

Scalar(5).isScalar // => true
Matrix(List(4)).isScalar // => false

Avoid class level values

It’s a sign that you are about to add an unwanted dependency which will be difficult to inject/mock later. A typical usage to avoid is reading configuration values in the middle of some method.

case class BadGreeting(firstName: String, lastName: String) {
  val person = Person(firstName, lastName)
  val location = Configurator getConfigValue "greeting.location"

  def greetWith(greeting: String) = {
    greeting + ", " + person.fullName + " in " + location
  }
}

// That should be refactored to this class
case class GoodGreeting(person: Person, location: String) {
  def greetWith(greeting: String) = {
    greeting + ", " + person.fullName + " in " + location
  } 
}

Pass an argument object instead of too many arguments

The rules so far prefer explicit to implicit. It may lead to a loooong list of arguments, though. The cure for this is to create a case class for those arguments. It’s a matter of personal taste how many arguments you consider too many. I would say, don’t have more than three.

Monday, November 25, 2013

Programming languages with a historical perspective


There are many thousands of programming languages from the most widely used Java or C to the arcane or forgotten ones, like Euphoria or Ada.  If I want to write their history, I'd have to exclude most of them and select only a few.  But which ones to select, what should be the organizing principle?

I could pick the most popular languages of all time.  Or I could get a list of popular languages of each year and take the top few.  I would probably get a different list depending on the source of the statistics.  A language can be popular in the academic world with many articles and publications dealing with it and without a real presence in applications -- that was the case with Haskell until a few years ago.  Some languages are widely used in a business setting, but they won't show up in a listing of open source projects.

And why select only popular languages.  They probably have a similar story, because they are winners in a similar field.  Java and C# have a lot in common, at least technically speaking.  It may be interesting though to see if they have a different history.  But there are little-known languages which introduced some feature, but somehow didn't make it to become mainstream, like Factor, a modern, stack-based language.

It naturally gives the idea to get a list of programming paradigms and select some representatives for them.  So we could have some object-oriented and some functional languages, sprinkled with some stack-based and vector-based ones.  The list could be balanced by the type systems, so for example object-orientations would be represented by statically typed Java or C# and dynamically typed Python or Ruby.

My aim is to reflect the diversity of languages and the ideas behind them.  But I also want to show what became popular.