I have written a new, small Clojure program to compare this month’s and last month’s insurance report. This is similar to a project I did a year ago, except it involves one report our personnel department gets once a month, not two different reports.
The program involves using Clojure’s jdbc interface, and is very much a typical database report that could have been written in Perl, or if the database had been Informix, in Informix 4GL. There’s nothing special about the program, except the code base was already in Clojure, and I wanted to keep the code base the same.
The only roadblock I ran into was setting status from the result of certain difference tests between last and this month, like whether a record wasn’t there this month, last month, whether or not the insurance product or premium had changed, or if someone had gone from an active to a retired status.
I tried figuring out a way to have a let binding contain return status from these different tests, so that these status values could be written into the report. After a while, I settled on a ref and dosync to set one global flag, so that later on in the program, had their been no errors, an appropriate message could be written to the file.
I don’t know whether I crossed into the mutable dark force, but, for one, I’m not convinced that carefully used mutable variables are a bad thing, especially, if you’ve designed the rest of your program not to take these shortcuts, because of coding laziness. Can you tell I’ve absorbed guilt from Clojure’s being immutable?
I do not think of Python or Java as functional languages, and I have written a medium-sized project in Python and sustained the configuration application for Vinca’s old CoStandbyForWindows. Haskell is labelled a pure functional language, and the word pure is sometimes used as if Haskell were organic food. Yet, both Python and Java (and perhaps other languages) seem to be caught up in the new functional craze. I am basing my theory on seeing a lot of new books cropping up, while looking for a good algorithm descriptive meta language.
Using Clojure on three small projects taught me that I had to re-orient my mind radically for Clojure’s almost pure functional approach versus the traditional C/Java/VB modifiable, iterative loop approach. For example, you’ve received two water bills with estimated reads. Finally, you get an electronic endpoint associated with your account and/or get a verified meter read into the water department. You have -170 ccfs to credit across two, successive, estimated 100ccf bills. The bills are calculated by binning consumption into three tiers, 0-30ccf, 31-60ccf, and 61+ccfs. When the account is credited, the credit has to be applied starting at the highest tier at which the original bill was generated.
The code I had to re-write was written in Informix 4GL, definitely an imperative language. How I would model this algorithm functionally would be an interesting exercise. Is it worth it to provide 4GL with functional extensions to the language? The program runs in a single process, and works against a database — Informix SE — that itself is protected by and supports synchronization primitives.
Now, I see there are types being added to Clojure. I cannot comment, having never worked on a large symmetrical multi-processing team responsible for a social media site or similarly complex project. I can understand why ascertaining the correct type is important. Are adding functional features to Java going to make the language better or people want to implement in it more?
I remember when Java was introduced, and a programmer allocating memory was not a good thing. C++ chugged right along, and C was almost universally adopted for device driver work, at least on Windows. Those languages are still being used, and there is a lot of useful Java code out there; at least the companies that paid for that code think so.
The best I can do is keep reading what is out there, whether I agree or not, lest I be lost in the swirl of the latest attempt of the holy grail of never having a program encounter errors.
I have only two small Clojure projects, and other than writing tools on which nothing major depends, these projects will probably be the only ones in my current position. The rest will be done in Web languages and Perl. So, I enjoy a chance to enhance the Clojure projects.
I do not know why, and am not aware of any conscious prejudice, but writing Clojure code encourages me to create small functions, and external Clojure projects, like a utility project containing various odds and ends to handle sequences, time/date manipulation, and other useful stuff.
I have written enough Perl and Python code to appreciate what those languages do, but, for some reason, my functions tend to be longer and wider in definition than my Clojure functions.
I remember my first introduction to Unix. It was at Harvard Extension in a Programming C in Unix course. I don’t even believe Minix had been invented yet, let alone Linux. Basically, my introduction to programming in Unix involved writing small, tight, do-one-thing-well programs — the programs assumed to be written in C — and tie those programs together with shell scripts. How true all that was, but appreciating its realization was to take nearly my entire career.
As I now maintain a two-year old Clojure program and a four-year old water AMR system. written in Python, it seems the choice of language is not what matters, but how everything was designed and implemented. It doesn’t hurt that Python encourages simple, clean function design and the creation and inclusion of modules, or that Clojure and leiningen highly encourage module design using projects, with their resulting name spaces and underlying directories. However, it all seems to be boil down to how I was taught to implement logic more than anything else.
My position represents either a sub-department or department of one. There is only one person in our municipality doing my kind of work, and a very knowledgeable consultant works with me. As my retirement looms in the next few years, I do not want to be known as someone who left a tangled mess. After all, more than a decade ago, I inherited just that because of the untimely passing of my predecessor, another one-person band. The mess was undocumented, uncommented Informix 4GL source code, virtually no build, no source code control, and no systems documentation.
The consultant with whom I work wants to standardize on the implementation language we use, and I agree with him. We haven’t chosen Perl because we think it is the best, but because a lot of people know it, and it works well for standalone and web applications. In our opinion, it doesn’t beat PHP for the web, but in a dual role works well for CGI and command-line, unattended applications.
After learning Clojure, I would rather write in it, even after having invested a store/forward configuration/meter reads system in Python. But, there is that trying to standardize thing I mentioned previously. So, I am going to take the advice I saw on one of the bulletin boards to someone just starting out. Write something and show it.
What I write will be tools on which someone coming into my job won’t have to maintain or reproduce, at least at the start. The rest of it, including a MySQL database crawler to keep the number of daily reads manageable at 14M rows of data, will be done in Perl. All of the people who said Clojure would affect my thinking even if I only learned it and never used it much were not kidding. My problem with Clojure is having to use something else. I guess that is a good thing for Clojure.
This post isn’t about language bashing. If you inherit a large body of code, say for a tax billing system, you realize you won’t be re-writing any of that code anytime soon, especially if you don’t know RECAP from January 1 Owners or Excise Service Warrants from Urgent Parking Notices.
Because it was here to stay, at least for a while, I learned to like Informix 4GL. I have pushed the language to its limits, including blowing the stack, evidenced by cursors never reaching the end of their working sets. I prefer other languages, like Clojure, Perl, and Python, but we’re making a cost-saving decision now to go back to well-worn and tested 4GL programs for generating water liens (for unpaid water bills) rather than re-writing everything in a language we deem “better”.
Instead, this is post is about the musings of Scala and Python, and how one achieves as close to pure functional programming with these languages. I have written a major project in Python, and know a reasonable amount about the language. I’ve had only a slight peak at the Scala for the Impatient (a very good read by the way), and am by no means an expert, let alone even knowledgeable. With Haskell and Clojure, your variables are always immutable. In Clojure you could defeat immutability by using and modifying a ref.
Can you achieve enough immutability with tuples in Python for it to be considered functional, and whether or not you can achieve immutability enforcing the use of
in Scala programs? Over the years, I have worked for well-run development groups, and despite good management and team interaction, not everything could be enforced, especially with coding style, and definitely when defining objects when C++ first began to be a viable programming language.
I will continue to dabble in Clojure, write major new programs in Perl, and maintain the old 4GL software, and somewhere keep thinking about immutability.