Thoughts on Saint Augustine, Rust vs Golang. Complexity, verbosity, and other matters.
I’ve always enjoyed reading Mr. Augustine of Hippo, particularly “Confessions.” Ahead of his time in many ways. Although, you have to be into that sort of thing to find such topics interesting. It can be sort of dry, drawn out, verbose, and not for the faint of heart. Much like learning new programming languages. I’ve been messing with Golang
off and on and here and there. Recently I added Rust
to that list, more out of curiosity and to see what’s new in the world.
I’ve spent a lot of time thinking about the theology of programming in the space of Data Engineering. It’s such a wide area that encompasses so many different skills, Data Engineering that is. Why do we do what we do, write what we write? Like Augustine I see both old and new all around me, some things change, but many things stay the same.
People find hills like Python
, Scala
, Golang
, Rust
, and then promptly decide to die on them. I enjoy different things simply because of the way they teach you things about yourself and the world.
What I like about St. Augustine and Golang.
I love Augustine because he was ahead of this time, would say things as he saw them, and outspoken about his beliefs.
“… man, but a particle of Thy creation; man, that bears about him his mortality.”
– Confessions
I’ve found myself drawn to Golang
for the same reason. It’s verbose enough to make you think about what you are doing. For example, if I want to make use of a map
to hold words and counts, I must do the following.
Yet, to simply open a file, it’s as easy as this. One would almost think they were using Python
if you were daydreaming a bit.
Using Golang and Rust to understand Augustine, and each other.
I’ve been perusing the Rust docs for a while now, simply trying to understand what all the huff and puffing is about. It’s made me very curious about how Rust
compares and deals with things compared to Go
. Personally, I could care less which is faster, which is more this or that, I just like to simply contemplate the simple things in life, like reading a book, and perchance counting the words in that book.
So, that’s what I set about to do. Read the wonderful Confessions
, which text file can be had off of the Gutenberg project. I wanted to do something quite basic, read a text file and count the occurrences of said words. Should be a relatively simple way to compare both Golang
and Rust
, how they approach problems, and maybe little tools they provide to make life easier. Who knows.
Reasoning about problems in Golang
I’m always very curious about how a language somehow forces you into thinking into certain patterns, or anti-patterns, how our past experiences as programmers and engineers fit into those thought patterns. I find myself drawn to more procedural and functional types of code munging. I’ve written many a OOP class in my day, some them just because, and some of them useful.
I enjoy Golang
because I’m not drawn to OOP, the never-ending classes and their inheritance is the bane and a virus that has spread quickly into the minds and fingertips of weakened programmers.
I don’t think Augustine was weak, and neither is Golang
. That being said, how do I reason about reading Confessions and counting the words. This is how I reason, simple and straightforward.
I shall simply read the text file.
And with an altogether, too large of a function, I will read the file line by line, break up the lines into words, throw some words out, then start counting the occurrences of a word inside a map
.
The wonderful bufio
package provides a Scanner
which is a buffered interface for reading files.
“Successive calls to the Scan method will step through the ‘tokens’ of a file, skipping the bytes between the tokens. The specification of a token is defined by a split function of type SplitFunc; the default split function breaks the input into lines with line termination stripped. “
Golang docs
What a nice and wonderful little feature this Scanner
is. for scanner.Scan()
to wind my way through each line of Confessions
, how convenient. Even more interesting is the strings
package and it’s NewReplacer
, this little strangeness will give us a Replace
functionality to swap out pieces of text for other ones.
But, probably the most delightful piece I used from the strings
package is the Fields
function. To split my line into an slice
of those substrings broken by whitespace. What a helpful little bugger. Hat’s off to you Fields
.
Finally, keeping track of the number of times a word shows up with a map
is quite delightful, word_count[word]++
, doesn’t it feel nice to write that? Printing some of the results, of words that occurred more than 100
times. See GitHub for full code.
Reasoning about problems in Rust
New things are hard, and I’m trying to think, was it harder to pick up Rust
or … maybe … Scala
? I can’t quite place my finger on it but Rust
seemed a little strange to me. I think for me … it made me think too much, a little too verbose. HashMap
s, Vector
s, I mean what’s the deal with let
anyways? Just seemed strange.
I guess when I look back or think about the code now, it’s probably not as horrible as I thought it would be in my mind. I guess when you read about a language replacing C++
… I start getting a little eye twitch. What could I possibly need with such power? Probably nothing.
I mean, reading a simple file, not so bad eh?
I mean, by George, that BufReader
, doesn’t that little devil look like a Golang
bufio.Scanner
? Maybe Rust
isn’t so bad after all, start a new BufReader
, from a File
. Maybe I could get used to this after all.
What next, what next? A Vector
perchance? Smells like a list
from Python
or something, probably heresy to say that or something I suppose. I’m sure a vector
is special, I mean everyone is special these days. What about a fancy HashMap
, again, someone from the cornfields like me, I just like dictionaries, call it a HashMap
if you want.
I mean, the rest of the code is what it is.
I do have to say, a lot of for
loops running around there Rust
my friend. There are some strange things I didn’t understand about Rust
. It has to do with Enums
, for example, the returned object
or result
from reading the file is a Enum
result. So apparently doing strange things like let Ok(mut ln) = line {
is a necessity. Strangeness always finds me.
Honestly, I couldn’t have been happier when I saw this line.
Good on you ole’ Rust
, good on you. Having nice String
operations like replace
for ease of use is just wonderful. There is hope for this world yet I see. I mean for crying out loud, did you see this line? for word in ln.split_whitespace() {
??? Even a split_whitespace()
and all, I just might have to change my tune about Rust
. Probably not.
It’s still too verbose for my liking. I mean what about using the HashMap
as my word counter?
I mean that’s a little much, isn’t it? I mean even in Golang
a simple word_count[word]++
get’s the job done. I guess things could always be worse, at least that’s what my mother always said. You can get my full code here on GitHub.
Musings
I honestly thought Golang
and Rust
were very similar. I do seem to gravitate towards Golang
a little more, I find it less verbose and it feels like my first cousin, while Rust
feels like my third. I find it no surprise I rarely find Rust
or Golang
in day-to-day data engineering tasks, content, blogs, articles, and the like.
I mean if you’re writing tools for Data Engineers to use, then maybe Golang
or Rust
would become useful, but it still seems like Java
and Scala
have their claws in that pretty well sunk in deep. Hope springs eternal though. Will I keep playing around with both languages, probably Golang
, Rust
I’m not so sure, but who knows.
What would poor Augustine think of me using his Confessions
to learn things and to formulate my own theology of solving problems like word counters? He wouldn’t mind I don’t think.