Thursday, August 15, 2013

A Journey to the Kingdom of Verbs

HRH, DGR Terra Nominem, greetings

Your Grace. In furtherance of your desire to establish diplomatic relations with our neighbors, I have traveled to the Kingdom of Verbs to meet with Queen Repl. I fear that our potential for commerce is limited. They follow exceedingly strange customs, which I shall attempt to relay by anecdote.

To all appearances Queen Repl is the sole permanent inhabitant of the land. She creates minions from pure thought, and these minions exist solely at her discretion. The queen will create complex hierarchies of these minions to fulfill a task, and when the task is complete, the minions disappear. While some of the minions are given names, those names describe but do not define them; each minion is a unique entity, created for a single purpose.

The method by which these minions interact is also exceedingly strange; it took me months to understand it. While we follow the dictum of “tell, don't ask,” they abide by “ask, and you shall receive.” And while we use diverse techniques such as Queues and Busses to decouple Producers and Consumers, they know exactly whom to ask for a service and do not look elsewhere.

Data is a topic that is rarely discussed in this land; indeed, at times it seems almost a taboo. In some cases, when asked for data, a minion will go so far as to create another minion to provide the answer, rather than speaking directly. I can only imagine this as dedication to Platonism: there is an ideal, and there are forms of that ideal, and minions work with the forms while the ideal remains unknowable. Again, it seems uncommonly strange to us, but appears to work for them.

However, this attitude toward data left me with a question: whence comes inputs to the land, and where goeth outputs? Or is the land truly inward facing, minions performing actions without effect? The answer to this question, as you might surmise, was critical to my ability to engage the Queen.

I found the answer to this question in the monadii. They go by various names, but their role is to provide minions with an ultimate source and sink for data. At first, I thought they were like the Flappers of Laputa, standing in the background to make their masters aware of the outside world. As time passed, I realized that they also were bound by the dictum of the land, and only spoke when spoken to. It was my great fortune to learn that there was a minion responsible for listening to the monadii and asking the Queen to interpret their words.

To bring my story to a close, and not waste more of your precious time, I was able to establish contact with two of these monadii, who then provided my bona fides to the Queen and returned her reply to me. While I do not know what form of intercourse our two countries can engage, I am hopeful that Nouns and Verbs will find common ground.

I look forward to my next assignment, the Land of Inference. Your most humble servant,

(signed) Reginald, extends Diplomat, implements Plenipotentiary

Tuesday, August 13, 2013

Thoughts on Unvarying Variables and One-Instance Classes

Closures scare me. There, I've said it, now the cool kids won't speak to me. Which is strange, because the cool kids all seem to be into functional programming, and I see full-fledged closures as the antithesis of functional programming. Perhaps we are using different closures.

Clearly, definitions are in order, and my definition of a closure starts with it being a function that has the characteristics of an object: it can be referenced by a variable and passed as an argument to another function. But my definition doesn't stop there. Critically, a closure has unrestricted access to variables defined in its enclosing scope.

Here's an example of a closure in action (if you don't have Go installed, you can paste this into the Go Tour to run it). Everything here happens in the main thread, but I could create a goroutine to run either function, or I could pass these functions into other functions.

package main

import "fmt"

func main() {
    x := 0

    f1 := func() {
        x += 1
    }

    f2 := func() {
        x += 2
    }

    f1()
    f2()
    
    fmt.Println("x = ", x)
}

Some people will see this and say “well, I'd never use closures this way!” I'll act as devil's advocate by saying that sometimes — sometimes — using closures this way is incredibly useful. But not often. And, unfortunately, I've seen a lot of closures used in exactly that way, often unintentionally. And that's what scares me.

For a long time I thought that my fear was simply a fear of unbridled mutability. Indeed, the first version of this post (drafted several years ago but never published) started with the following:

Var, huh! Good God, y'all, what is it good for?

That, and the title, were just too good to discard with the rest of the text. If you're too young to get the reference, don't worry; it isn't really the cause of my fear.

For the last few weeks I've been discussing my fear with friends, and I've arrived at a better reason: closures create an ad hoc class, whose methods are conjoined solely by the fact that they share common variables. As a person who believes that object-oriented programming has something useful to offer, I find this deeply disturbing. It violates several principles of object-oriented design, not least being the single responsibility principle.

But worse, in my mind, is that the methods so conjoined don't have a name. They are simply actions that happen to know about the same Thing. OK, I realize that some people scorn the idea that all Things should have names. Perhaps those same people name all of their variables a1, a2 and so on. Personally, I stopped doing that when I stopped programming in BASIC.

Named classes, when used properly, provide a way to decompose a program into clearly bounded units of functionality. The methods in the class are all related in common purpose to provide that functionality. And again, used properly, names are an important part of this decomposition; if you see that a frob is getting fribbled, your attention turns immediately to the Fribbilator (or maybe the FrobManager, but definitely not the Bargulator). With closures, and their ad hoc relationships, your task becomes much harder: you might have to walk the entire codebase.

Does this mean I reject closures? No, of course not, not even closures that make use of their ability to mutate enclosing state; as I said, sometimes that's useful. But my fear — which I now name Caution — makes me ask the following question as I'm coding: “should this be a closure or a class?”

Friday, August 2, 2013

Where Do I Want to Go?

TLDR: The title is a pun.

In the past year or so I've been looking at different languages, trying to gain a sense of what I might do “after Java.” My investigations have been cursory, as they must be: adopting a (bad) Matrix reference, I don't think you can truly know a language until you have fought with it. But maybe you can get a sense of whether it's worth fighting. So here are the languages I've considered, and my impressions:

Scala
Many of my colleagues believe that Scala is the best “JVM language”; we're doing several projects with it, and offer several classes in the language. I like some of the ideas that it incorporates, especially the clear delineation between mutable and immutable data (and a strong preference for the latter).

But … it's ugly. My first impression of Scala was that it had too many symbolic operators. As I kept seeing it, my impression changed: it had too many features and ideas, period. And based on discussions with my colleagues, there isn't an easy path to learning the language: you need to program idiomatically from day one.

That said, it looks like Scala will be the next language that I use professionally, probably within the next few months. Maybe my opinion will change.

Clojure
I don't get LISP, and the people who claim to get it always seem a bit too religious to me (not merely religious, but too religious). Perhaps I will be enlightened if anyone can explain exactly why macros are different from any other interpreter — or for that matter, any type of code generation. For now, however, Clojure (as the most-commercial LISP) isn't in my future.
Groovy
Why isn't Groovy more popular than it is? Of the features that I listed in my previous post, Groovy has everything except a concurrency story. It's easy to write, runs on the JVM, can interact directly with Java libraries, and offers some neat features of its own. Yet the only people who seem to use it are those who adopted Gradle as their build tool.

It was while I was trying to learn Gradle that I decided Groovy wasn't for me. To truly understand Gradle, you need to understand the Groovy approach to building DSLs by blending functions and blocks into a seamless whole. It's quite impressive once you figure it out. But, like Scala, there's no easy path to knowledge. The path from “Hello, World” to idiomatic Groovy involves a quantum leap.

And the documentation, quite frankly, sucks. It's a bunch of disconnected wiki pages that assume you know what you're looking for before you look for it. Perhaps not so bad on its own, but I believe it belies the approach to Groovy's language design: it's trying to be the new Perl.

Ruby
I've worked a bit with Ruby. It's nice, but I don't find myself wanting to devote the next section of my career to being a “Ruby developer.”
JavaScript
Does JavaScript have a future outside of the browser? I don't think so, Node.js notwithstanding. I think the biggest issue is the lack of library support: if I want a feature that's not part of the core language I need to write it myself. It's much like C++ before the STL (and while JQuery is great for interacting with the DOM, it's not a general-purpose library).

I also make far too many typos to be a happy JavaScript programmer. Making this worse, most of the frameworks that I've used swallow exceptions.

Erlang
Erlang is a strange language; it's very obvious that it started life as a rules engine. It has some extremely interesting features, such as list comprehensions that are closer to a database query than anything you'll find elsewhere. And most important, it has a notion of “shared nothing,” message-passing concurrency that I like.

But … it's a strange language. Actually, the way that I often describe it is “primitive,” designed to solve the problems of the 1980s. There's heavy emphasis on buffer manipulation, while strings are treated as lists of (ISO8859-1!) characters. I'm seeing ever more projects that use it, but I think there are better alternatives.

Python
Python is a beautiful language: every time I get to use it, I smile. Unfortunately, as far as I can tell (based on not-so-regular attendance at the local Python Users' Group), it's confined to scripting and “need it now and not tomorrow” programs. It also doesn't have a good (to me) concurrency story.
Go
Go has many of the features that I consider important, and it has an impressive pedigree (Kernighan and Pike). It does have some strange quirks, which will be the topic of future posts. And it's a young language, still evolving; code written today may need to be rewritten tomorrow.

That said, Go seems to make the most sense for my future. Like Java, it was a language created for a clear purpose (concurrent back-end applications), and I happen to think that the future mainstream will be concurrent. Better then to have a language that was designed for that purpose, rather than one that has concurrency bolted on.

Coming up: my adventures in learning Go.