This does of course not apply if you use a deliberately restricted language that has just one type of collection traversal, in that case you are better off with varargs, as n*1 < n+1.
2 is a code smell
11–20 of 33 posts
Re: 2 is a code smell
#12What about sub-vectors? That smells like a 2 to me... I'd rather call fold or foldr myself and KNOW how it handled more than 2 arguments. I'd rather do it for add-vectors too, just so it was consistent. You have to define primitives somewhere. Even if what you call elsewhere is some fluffy handle-everything function. At the very least, I wouldn't call it a smell.
(Of course, the objection to data having only two things doesn't hold either if it's a recursive data type -- cons lists, binary trees, etc... -- but you know what I mean.)
Re: 2 is a code smell
#13If a co-worker told me that my function was "code smell" because it took 2 arguments, I would tell him that he needs more important things to worry about.
Re: 2 is a code smell
#14Reminds me of zip, zip3, zip4, etc. in Haskell.
Re: 2 is a code smell
#15I do think the author has a point, but to me the logical complexity progression for a piece of code is:
1. Make it work in the "1" case.
2. If necessary, make it work in the "2" case.
3. If necessary, make it work in the "n" case (n variable).
I find this particularly useful for larger decisions: I can make this work right now if I add this tiny little wart? No problem. Another thing came up and a similar wart is required? Ok, I guess. A third? Time to find the structure that my code is telling me about and refactor to expose it.
Re: 2 is a code smell
#16I try to be very pedantic about having the most terse, yet readable code possible in my application. This probably means that if, for now, I only need to know how to add two vectors, I will only include a function that adds two vectors and no more. I do realize there's hidden structure there waiting to be exposed, but programming is largely about elaborating the useful structures. If the author's examples had been in…
Re: 2 is a code smell
#17 def dot(v1, v2):
return sum(i * j for i, j in zip(v1, v2))
Very functional, very pretty, very straightforward. But it was slow, both in CPython and PyPy. A bit of bytecode analysis and profiling later, we realized that unrolling would be faster by several orders of magnitude. So I checked this in: def dot2(u, v):
return u[0] * v[0] + u[1] * v[1]
def dot3(u, v):
return u[0] * v[0] + u[1] * v[1] + u[2] * v[2]
And the bottleneck went away. From the Zen of Python: "Practicality beats purity."Re: 2 is a code smell
#18This is pretty much an instance of the good old "zero, one, infinity" rule. http://www.catb.org/jargon/html/Z/Zero-One-Infinity-Rule.htm...
This article restricts itself to a context where following "zero, one, infinity" results in simpler, more concise code. This is a good restriction. In general, following "zero, one, infinity" will often put you at odds with YAGNI.
If the code is simpler then I don't see how YAGNI comes into play. Why would you do something that is both more complicated and less amenable to future needs?
Re: 2 is a code smell
#19Since we've already descended into anecdotal territory, lemme drop an anecdote. I had a dot-product function which turned out to be a hotspot in some numerical code. The original function looked something like: def dot(v1, v2): return sum(i * j for i, j in zip(v1, v2)) Very functional, very pretty, very straightforward. But it was slow, both in CPython and PyPy. A bit of bytecode analysis and profiling later, we real…
http://docs.scipy.org/doc/numpy/reference/generated/numpy.do...
Re: 2 is a code smell
#20Since we've already descended into anecdotal territory, lemme drop an anecdote. I had a dot-product function which turned out to be a hotspot in some numerical code. The original function looked something like: def dot(v1, v2): return sum(i * j for i, j in zip(v1, v2)) Very functional, very pretty, very straightforward. But it was slow, both in CPython and PyPy. A bit of bytecode analysis and profiling later, we real…