I’ve been wanting for some time to delve into functional programming (FP). As I’m sure I’ve said eleventy-billion-and-one times, I got a taste of some FP patterns in Ruby and JavaScript, and Python to a lesser extent. Well, now I have: I’ve been reading Learn You a Haskell for Great Good!.
You are currently browsing the archive for the Coding category.
So what languages do I think offer the best prospects for high-productivity coding buttressed by strong typing? Maybe it says something about what my opinion is worth that I’m not so sure about one of the two languages I was putting forward.
Still, this is as good as time as any to talk about the first one. Lately I’ve spent some time with the Go programming language.
Go
If I had to sum up Go in my own words, I’d call it the spiritual successor to C, with modern sensibilities. It has concise and lightweight syntax. It’s memory safe (read: garbage-collected) and strongly typed. It has powerful concurrency primitives at the language level. It has a unique approach to interfaces where they are actually orthogonal to data types, not unlike Haskell’s typeclasses. It has first class functions and lexical closures. And it has a rich standard library.
Although Go doesn’t ship with a REPL or interpreter, there are some projects out there. However, there’s also http://play.golang.org/. As far as I’m concerned, this is close enough to a REPL that I’ve found it extremely useful for prototyping, testing out a package from the Go standard library, and I’ve even written code I’ve ended up keeping later.
Go threads the needle between providing a strongly typed language which is more productive than C++ and orders of magnitude less verbose and clunky than Java. It’s more performant than your average scripting language, yet the standard library is just as rich and easy to use. I would probably not go back to Python except for ~100 line helpers, or glue code which is just above shell scripts in terms of complexity.
It’s tough to pick good examples for some rough comparison that aren’t already covered in the Go docs. But here’s one of my hobby-horses, something which is easy in some scripting languages.
Processing command output
This is trivially easy in shell scripts, and shell scripts were made for processing text. Perl makes it approximately as easy, and as Ruby borrows so much from Perl, it’s similarly easy.
In Python 2.x, it’s terrible. I’d rather not write this in C++ or Java.
Here’s how you run a simple command in Go and capture its output:
// exec lives under the os/exec package
out, err := exec.Command("foo", "--bar", "baz").Output()
out is the output, an array of bytes. You’ll want to split it in lines and iterate over it, treating it as (say) an id and a username along with it.
lines := bytes.Split(out, '\n')
for _, line := range lines {
// Split by spaces.
fields := bytes.Fields(line)
fmt.Println("id is %v. username is %v.", fields[0], fields[1])
}
Notice the lack of type declarations. Most of the time you use := to declare and initialize at once, which ends up feeling a lot like Python or Ruby. The difference is that the Go compiler infers types based on return values and the like, granting the benefit of type checking.
Further reading
I could come up with more examples. I’m trying not to! That’s because you’re better off playing with something like the Go tour. Trust me: you might think it a bit silly at first, but there are exercises and the app will test your solution. It’s very good.
The Go site is rather good, as well. There’s [a Go tutorial] wherein you write a wiki which is worth your time. You should read Effective Go if you’ve decided you’re actually serious about it.
Today I took a relatively big step in terms of my coding workflow. I purchased a license for Sublime Text 2 and immediately began using it as my full-time code editor.
Tags: st2, sublimetext2, vim
Once upon a time, I started to learn programming in C++. It turns out that it’s hard (for some value of “hard”) to do a lot of basic things in C++. As a budding programmer, I spent more time struggling to make myself understood to the compiler than writing code.
When I was introduced to Python, suddenly programming was fun again. It was hard to imagine going back to anything like C++ when I could become so productive so quickly with Python.
I held to this view for a very, very long time. I appreciated how languages like C++ or Java would be useful for writing “serious” applications, but I didn’t write that stuff. That was for other people.
In the last year or so, I’ve gradually come to believe that a strong type-checking system AND a high-productivity language ought not and are not mutually exclusive. The corollary is that I will consider carefully before I use a scripting language for anything more than a thousand or so lines.
Oh, god. I still have a bunch of rant left in me. So here we go, Internet: yet another angry rant to add to the pile.
Sometimes, in the course of one’s life, one is left with a one-off task. In this case, I needed to call a binary a whole lot of times, and do something with the output each time. The details aren’t important; I just needed to write a wrapper script for this binary, do a modest amount of processing on it, and then output the result to a file. This is a pretty common task, one to which the command line in general and *nix in particular is well-suited.
Now, for various reasons, I prefer not to do this via shell scripts. I don’t have a hard and fast rule for when or why. Unless you routinely write shell scripts (I don’t), you’ll inevitably spend a bunch of time looking stuff up that you looked up, oh, six months ago. Or at least I do. I don’t enjoy it, so if I can’t do it with a few commands, maybe one loop or so, then I prefer to use a scripting language. I have the advantage of better/clearer failure modes and simpler syntax and I feel like I’m learning something more powerful and more widely applicable in the process.
I’ve been coding lately, and fortunately or unfortunately, it’s Java. I hadn’t done much Java before I started working on this current project; my experience before this was with C++ in college, a bunch of Python, a splash of Ruby, a bunch of JavaScript, and a very small pinch of Objective-C/CocoaTouch.
It’s JavaScript and Ruby that’ve influenced me most lately. Functional patterns in particular have attracted my attention. I really dig stuff like this in Ruby:
open('somefile').readlines.each do |x| print x end
And then I spent a whole boatload of time in JavaScript, where you get to do stuff like this:
var someArray = [1, 4, 2, 3, 5]; goog.array.forEach(arr, function (e, i, a) { console.log("Here's a number: " + e); });
What I really dig about this pattern is passing in a function where I can do whatever I like. The factory pattern becomes much simpler. We can pass this around to whoever:
var url = "/foo"; var reqFactory = function() { var req = new Request(); req.setUrl(url); req.addHeader("baz", "quux"); return req; };
The current conundrum involves implementing some kind of retry logic. In one case, I need to build a new request each time the request fails. In another case, I just want to retry for a certain subset of exceptions. In yet another case, if I make the request and it doesn’t have what I want, I want to re-issue it.
In Java, it’s— it’s messy. I don’t know what the Java-esque way of doing it is, quite frankly. I find myself wanting to create a Retrier interface which defines an onSuccess, onFailure, and a doRetry method.
I’m not sure what each method should return; what if I want to be able to return whatever it is that we got from the request? Do I create a wrapper class w/generics? I think this is how it works in the Kingdom of Nouns. The nouns just keep proliferating.
The one thing I think Java has going for it is anonymous inner classes. I feel like the way files and classes proliferate in Java is nuts, and being able to keep the implementation of such as a Retrier close to where it’s used seems like a win. It’s a one-off, right? A whole class & implementation & file devoted to it feels like it’s belaboring the point.
I’m sure at some point I’ll figure it out and/or get used to it. In the meantime, every time I want to add a layer of abstraction, it feels like massive overkill. I almost wrote up code samples for the above but it turned out to be too much effort. I can’t be as glib with it, at least not yet. Oh well.
Tags: FP, java, javascript, ruby