Infinity: Easier Than You Think. Infinitely.

Spaghettified musings on software

  • December 2017
    S M T W T F S
    « Jun    
     12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31  

Archive for the ‘Clojure’ Category

Does Groovy Know You Are Seeing Clojure?

Posted by gdjsky01 on 2010/05/01

With all due credit to Venkat Subramaniam for the paraphrased title of this posting.

I’m not sure exactly when I decided to learn Clojure. I know I’d heard about it as one of four JVM languages with a lot of buzz in 2009 (yes I know there are other JVM languages). At the time of  ‘discovery’, I was in New Orleans at last October’s (2009) SpringOne/2GX swooning with others over our love of Groovy and all things Groovy. The other three I am thinking of are a Ruby clone JRuby, a weird language called Scala, and Clojure. Yes I am aware calling Scala weird is a bit of the pot and tea kettle syndrome but I find Scala to be the C or APL syntax of the JVM languages. All things considered, in my not so humble opinion, there is no other language I would rather code with than Groovy. It’s just the most natural and powerful progression from Java. Maybe that is controversial, but since this is my blog, it’s my opinion.

Now I am a bit of a language junkie and always have been since I was a tyke in 1979 coding on a TRS-80 Model 1 in Basic and Z-80 assembler. I’ve toyed around with, or coded for a good living in, Z-80, 6502, 68000, x86 assembler, Modula 2, Pascal, Forth, C, C++, Java, Ruby ,Groovy, and now Scheme (a tad) and Clojure. Pretty decent list if I do say so myself. Oh and sitting on my bookshelf is a book on Erlang. However I can say with some certainty: In the intervening 30 years since starting out on a TRS-80 Model 1 nothing has been more difficult in terms of solving even the most trivial of problems than learning Clojure.

Of course there is a good chance this has nothing to really do with Clojure at all. It is really Functional Programming (FP) that is giving me fits. After all, if you take away FP, learning Clojure is just learning Lisp (it’s Clojure’s immutable paradigms that differ from Lisp – as far as I can tell). I have been doing pretty well with the “Little Schemer” for learning a dialect of Lisp. But alas, I don’t find that translates into Clojure. Not sure why. For two months, I’ve been reading blogs, reading MEAPs (Clojure in Action and The Joy of Clojure), and reading source.

At first reading Clojure was the problem (and still is to some extent – reading is not writing) as I had no Lisp or Scheme exposure. The only thing I knew about Lisp was the oft repeated refrain that truly great programmers know Lisp is the secret weapon. Like Paul Graham’s Beating the Averages post. Did I believe it? Do I believe it? I suppose I did believe it and I did not care. There was much more money in Java and C++ than Lisp, so why worry about that I am using so-called second rate languages. (A strawman there but you know what I mean.) I am in this profession to make a living, not impress people with the tools I use.

Do I still believe it? Umm… not right this minute. I am having such a heck of a time coding anything beyond Hello World in Clojure I have begun to wonder if only certain level guru’s can ever ‘get it’. Notice I am not making a distinction between coding in Clojure/Lisp and Functional Programming. The reason is as far as I can ascertain in the Clojure world, they go hand-in-hand. Imperative Programming in Clojure is really fighting the language. So one could say I really bit off way more than maybe I should have. On one hand I decided to learn something about Functional Programming and on the other decided Clojure would facilitate that because you are virtually forced to immerse yourself in FP from the start. Or maybe it was the other way around. Maybe it was Clojure making me discover FP.

Either way I took on two totally unknowns and for two months now I have paid a mental price for it. It has been really frustrating. The simplest imperative programming solutions don’t even give me a hint, a clue, as to an approach of how to solve the same problem in Clojure/FP without a lot of mutable state. Take a simple problem we use at my employer to get a small perspective on possible new hires and how they approach solving problems in Java: This problem is to take a vector of intra-day stock prices for some particular stock (numbers) and determine the maximum profit you could have made buying that day and selling that day. Simple stuff in an imperative language. You simply keep track of the minimum value, the profit, and replace the minimum whenever the next value is less the current minimum.

Well my dear readers… I could not for the life of me figure that out in Clojure/FP. Now remember I’ve not written ANY Clojure or done any FP. Just read about it. This was my ‘do something real’, sort of  a Hello World.

“What’s the big deal?”, all you expert FP’ers (or even novice) FP’ers are saying. Yeah thats the thing, I have no idea what the big deal is. Just could not find the approach. Or the correct higher order function(s) to use. Just could not figure out how to keep track of two things (minimum and profit) without a mutable variable someplace. Frankly, maybe at age 51 you can not teach an old dog of 30 years, this new trick.

To this day I did not really figure it out on my own. Instead I casually mentioned the challenge to my local friendly Scala enthusiast. He took up the cause and came up with something like this

A.foldLeft((Math.MAX_INT,0))((s,curr)=>(Math.min(curr,s._1),Math.max(curr-s._1,s._2)))._2

Now you begin to see how stupid I was feeling. Not only did he solve the problem, he solved it in a line of code that fit in a tweet on Twitter with room to spare.

The tuple was what gave me the idea of using a structure. And I guess I did solve it. It’s not pretty, and it’s way more than one line, but it appears to pass my tests.


(def closing-prices '(23 24 21 23 45 33 22 1 33 4 2 23)
;;(def no-profit-closing-prices '(23 21 20 19 18 17 16 15 14 13 1 0))
;;(def closing-prices '(23 24 20 19 18 17 16 15 14 13 1 0))

(defstruct values :min :profit)

(defn calc-profit [current-values next-val]
    ;;(println (current-values :min) (current-values :profit) next-val)
    (let [mini (min (:min current-values) next-val)
          profit (max (:profit current-values) (- next-val mini))]
        (assoc current-values :min mini :profit profit)))

(defn find-profit [coll]
    (let [v (struct-map values :min (Integer/MAX_VALUE) :profit -1)]
        (reduce calc-profit v coll)))

(:profit (find-profit closing-prices))

Of course my greatest fear is you’ll post a comment showing me a single line of Clojure that does the trick. 😉

So why subject myself to this self-inflicted torture?

  1. I believe Rich Hickey is right. More cores not higher clock frequencies are the near future. FP is really a boon in concurrent coding as you can more easily reason about the code’s behavior with multiple threads.
  2. I almost never see a really great object hierarchy in OO languages. They start out small and clean and grow to crap and cruft. Not in 20 years of OOP have a seen a really great object hierarchy (yes a logical fallacy but still true in my case). Indeed most of us now use composition, aggregation, and delegation, not inheritance. In FP you have to use composition. It is all about composing functions from other functions.
  3. Its a challenge. Different way of thinking. And maybe secretly I want to join that elite illuminati of Lisp engineers…

But Groovy is soooo much easier! Will Clojure win my heart…

Advertisements

Posted in Clojure, Coding, Groovy | 31 Comments »