I started writing this in response to a post on a mailing list.
Basic idea behind the original post: I have a few decks of cards. I know that card seven in deck 12 tells me where I can start to find the 2 cards I can actually care about in decks x and y.
There's some personal stuff mixed into the middle of the career advice, so it seemed worth capturing the silliness that goes on in my head here.
I'm assuming the original poster wasn't just a troll.
There's a definite learning curve here.
Learn to spot these patterns.
Along with all the others. There's probably a Lifetime Achievement Goal for this one.
When you do something like (first xs) or (nth xs 3)...think about it!
Are you really just accessing the first element of a sequence?
I
know that seems to be the "clojure idiomatic way." And, honestly, I
think a lot of lisp literature probably supports this sort of approach.
It's *great* if you're processing a seq by recursing over head/tail.
But...is that what you're really doing?
And,
seriously, is there *ever* a really good reason to call nth in the
middle of general-purpose code? (Yes, I know common lisp gurus *love*
cadadar, but it gives this lesser mortal a headache just thinking about
it).
In your case, it isn't. Or we wouldn't be having this conversation.
Personally,
I haven't found a better solution to your dilemma than combing through
the source code and looking for smelly parts like this.
One good
(cross-language) rule of thumb I've run across is "If it happens
once...OK. If it happens a second time, start being suspicious. If you
see this pattern a third time, it's time to move it to an accessor
method kind of thing."
I have the fresh wounds to be aware: I
spent a good chunk of time today taking a namespace file that had grown
too big for me to handle and splitting it out into multiple pieces. This
meant a lot of digging through source code and updating specs for new
namespaces. I'm still trying to figure out how this part actually works
in clojure 1.9. I probably should have checked out Cursive again, and I
haven't gotten further than installing CIDER 0.15.
There's another angle here that makes me suspicious.
Is what you're doing really complex enough to warrant "several thousand" lines of code?
I'm not saying it isn't!
I
have absolutely no basis for judgement here beyond gut instinct. And no
room to judge...I wouldn't pass this next check by any measure. I'm
just asking questions here.
How good is your unit test coverage?
How good are your commented-out REPL tests? Or maybe you moved those
elsewhere to keep from polluting your production code base. (I'd
personally rather see them right in the middle of what I'm testing as
examples of how to call the code I'm testing, but I think I'm in a slim
minority here).
I'm sorry for the long circle around your actual question.
If
you have "lots of irrelevant stuff" that turn up when you search your
code base for [first second nth]...what have you been doing?
If
you've been slinging together a bunch of unrelated data structures into
linked lists and expecting magic to come out the other end, then I feel
your pain. Welcome to the real world. It doesn't work that way.
If
you can pick apart the bits and pieces where you've been doing the same
thing over and over again, you might be doing things that are easy to
extract. Hmm...I'm calling (first (second (nth x 7))) a lot, to get to
the same thing. I'll write a function that does this instead and then
spend as much time as I can digging through my code to search for that
pattern to refactor it to call that function instead.
Personally,
I've never had any luck letting my editor do that step for me. It
either finds a ton of false positives that breaks everything when I try
to run my code in production, or it misses a ton of false negatives that
leaves me wondering why I invested the time installing that editor in
the first place. (Don't take my experience here as worthwhile: my
experience is about 3 years out of date).
But, really, if you're
doing the (-> x (nth 7) second first) sort of pattern often enough
that you have to wonder whether you were looking for your uncle's
telephone number or your sister's twitter feed...there's a bigger
picture problem in your code base.
Figure that one out again. Recurse.
========================
Personal historical perspective that doesn't add anything, except my personal amusement and possible historical interest:
I've
been working with a couple of C++ developers on a python project, and
they've complained many times about this sort of thing.
I wish I
had a better answer than "What did you expect was going to happen?" In a
lot of ways, it feels like when I was doing C++ and everyone around me
threw away days tracking down N-1 errors on their array accesses because
STL vectors were just too slow/complicated.
It seems like there are probably XKCDs about this. If there aren't, the captions should be:
C gives you enough rope to shoot yourself in the foot. C++ gives you enough rope to blow your entire leg off.
With great power comes great responsibility.
No comments:
Post a Comment
Thanks for leaving a comment! We love to hear from you!