This morning I finally finished up the problem of the demand time series time-shifting: a simple left-shift of the sequence:
(defn shift-left
"Do a simple left-shift for the sequence of 'n' items"
[coll n]
(seq (into (vec (drop n coll)) (vec (take n coll)))))
and this works wonderfully:
(def a '(1 2 3 4 5 6))
(shift-left a 3)
=> (4 5 6 1 2 3)
Nice little function to have. Interestingly, the way this works is entirely different than a very similar function:
(defn shift-left-no-vec
"Do a simple left-shift for the sequence of 'n' items"
[coll n]
(into (drop n coll) (take n coll)))
This guy doesn't convert the drop and take sequences to vectors, and the result is interestingly different:
(def a '(1 2 3 4 5 6))
(shift-left-no-vec a 3)
=> (4 5 6 3 2 1)
seems the into function when operating on a sequence pulls from the end and not the beginning, or something odd. The drop and take looked good in the REPL, but there's something about these sequences that messes things up. So I used vectors and then made it back into a sequence at the end.
When I tried to test this in the larger system I realized that there were tons of problems in the code that had been written by my teammate. There were poorly thought out arty functions for updating the data - not hard to fix, but it took a little time. There were really poorly designed insert methods that wouldn't properly strip out the existing id values from a source data set for it to be inserted as a new data set without errors - again, not too hard to fix, but it was thoughtless.
Then there's the one that probably bugs me the most because it's brought about by clojure the language and the clojure guru that's really setting the design and namespaces for the project. Circular references. Clojure can't deal with them.
OK, if you're in a single namespace, you can say:
(declare foo)
and then use it and later in the same namespace say:
(defn foo
[x]
(* x x))
but if you need to have two methods in two namespaces, and there are require directives set up to have one include the other, then you're hosed. No way around it.
Now I'm no language designed - OK, I did it long ago, and it wasn't nearly this complex, but the point is this seems like a horrible oversight. Unless, the assumption I'm working under is faulty. Maybe the point is that the designers didn't expect to have 50 namespaces like we have. Maybe they expected 5. In that case, this all goes away. If I were to collapse a few namespaces, that would fix things up.
But then my clojure guru would not approve.
This is what's really beginning to bug me - good languages like ruby spoiled by the tubists culture. Ditto here. Don't be a math prude - don't try to design the namespaces before you know you need them. Arguably, in a C++ project, I'd lay out directories as I knew I'd need them - but only a minimal set. This is something that just goes to bad design, and since I'm a total newbie, this is on my guru. He didn't even see it coming.
I want to learn clojure, and ruby, and then use them as I'd use C++ - with the features I see I need, and how I'd use it. But I'm getting the feeling that that's not how this is going. I'm being shown a limited set of the features in clojure and that's all he wants to use. I get it. I'm not sure I'd want someone to be doing template meta-programming in their first C++ project, but it's still a little unsettling.