Live data from Hacker News

My Objection to Array#sum

github.com

21–30 of 65 posts

Re: My Objection to Array#sum

#21
post #17

I agree with you. That being said, I suspect that this turns out to be a cultural debate more than anything else. Remember, Ruby is a freedom language. Ruby could eliminate many of the issues you raise by being strictly typed, but of course that'd defeat the purpose. The whole thing is a question of trust. Do you trust clients enough to give them the syntactic sugar of Array#sum even if their arrays may not all be st…

> The whole thing is a question of trust. Do you trust clients enough to give them the syntactic sugar of Array#sum even if their arrays may not all be strictly summable? I agree that Ruby should embrace Freedom, but that does not mean that all choices programers make freely are good ones. This is not about whether programmers accidentally call #sum on arrays that cannot be summed. It is about whether, when I look at…

It is about whether, when I look at the methods implemented by Array, it describes what arrays do or what arrays sometimes do or may do once in a while.

Sure. I think it's in Ruby's culture for people to write ultra-cute convenience methods and DSLs for this sort of thing, even if it makes it possible for someone to write code that doesn't make semantic sense.

I actually think that Array#sum is the least objectionable in a single project where summing the elements may be common, maybe objectionable in ActiveSupport where every Rails project gets it whether they sum arrays or not, and absolutely wrong in Ruby's core libraries where every Ruby programmer will get it.

Agree 100%. Arrays in Ruby core shouldn't be summing, they should be injecting.

Re: My Objection to Array#sum

#22

Why is [1,"two"].sum any different from 1 + "two"? That is, 1.respond_to?(:+) is always going to be true, and yet sometimes sending the + message to a number will give a type error. I don't buy into this idea of interface as binary - that if you respond_to? the message, it's always appropriate, and if you don't, it's not. Interfaces are something you look at when you're writing the program, and so they are interprete…

The difference between [1, "two"].sum and 1 + "two" is that in the second case you are passing "two" to 1's :+ method, that's an argument error, it doesn't depend on 1's state. In the first case you are not giving any argument to the method, so you shouldn't get an error. From the point of view of the array's user the array is now in an invalid state and that's not something the array should have allowed to happen.

Re: My Objection to Array#sum

#23

Not all arrays can be summed, but they all claim to respond to #sum. This is extremely broken. This is how I felt when I first saw Array#sum. But then I took a few hi- But then I tried it a few times. And now I can quit anytime I want. I think String#titlecase is correct though. Not all arrays can be summed, but all strings can be titlecased, including part codes.

But does String#titlecase do the right thing for ß? :)

But the point isn't that String#titlecase can't do the right thing here. I assume there is an implementation of titlecase that will work with ß. But I can't think of an Array#sum that will work for [1, "two"].

Of course your :) might have meant you were being funny, then I just totally missed your point and explained something you already know.

Re: My Objection to Array#sum

#24
post #20
post #10

Earlier quoted context omitted.

The thing is, they aren't methods. They really aren't. They don't operate on an object using the object's local data. They are generic functions that use certain defined interfaces that many objects define. "list.join(str)" and "str.join(list)" are not the same . The list.join syntax only works for lists, but str.join takes any sequence , which is anything that implements the sequence protocol, including lists, dicts…

Well join should be on sequence instead of list then. To me it seems unnatural to see join on string because string feels more 'basic' than a sequence, so I would expect the sequence to know about strings rather than the opposite. But the argument against join on string is not as strong as the argument against sum on array.

This is such a non-issue. Really. The parent posted the reasoning behind the decision, that reasoning is sound. Your disagreement is purely aesthetic, there's simply no practical reason why the current way is wrong. Please just accept that this is how it is, and stop complaining about it. Please?

Re: My Objection to Array#sum

#25
post #20

Earlier quoted context omitted.

Well join should be on sequence instead of list then. To me it seems unnatural to see join on string because string feels more 'basic' than a sequence, so I would expect the sequence to know about strings rather than the opposite. But the argument against join on string is not as strong as the argument against sum on array.

This is such a non-issue. Really. The parent posted the reasoning behind the decision, that reasoning is sound. Your disagreement is purely aesthetic, there's simply no practical reason why the current way is wrong. Please just accept that this is how it is, and stop complaining about it. Please?

Python is intended to be aesthetically pleasing in some sense, so I don't think aesthetic objections to some of its features are unwarranted.

Re: My Objection to Array#sum

#26
post #4

Calling [1,2,3].inject(0) {|sum, ii| sum + ii } has a cleaner smell, but it's a lot more typing. I wonder if the solution might be to have all arrays support sum (in the responds_to() sense) only if they can can actually perform the operation. Thus [1, 2, 3].respond_to?(:sum) => true [1, [2, 3]].respond_to?(:sum) => false I can come up with an O(1) way to do this where we assume that an array does respond to sum, and…

[1, [2, 3]].respond_to?(:sum) => false I elided a discussion about this case from the post. For some arrays, a recursive sum is semantically valid. For other arrays a recursive sum is not semantically valid, and it is not a simple case of knowing whether all of the leaf elements respond to :+. So again, trying to implement this in the Array class doesn't work because containers are implementation rather than interfac…

Reminds me of Kent Pitman's article about, among other things, why there's no generic deep-copy in Lisp: http://www.nhplace.com/kent/PS/EQUAL.html

His answer is similar: just because you know the structure of something doesn't mean you know anything about its semantics.

Because of this, I'm tending to believe that adding more strong-typing to languages is a losing battle, though I admit this raises more questions than answers.

Re: My Objection to Array#sum

#27
post #20
post #10

Earlier quoted context omitted.

The thing is, they aren't methods. They really aren't. They don't operate on an object using the object's local data. They are generic functions that use certain defined interfaces that many objects define. "list.join(str)" and "str.join(list)" are not the same . The list.join syntax only works for lists, but str.join takes any sequence , which is anything that implements the sequence protocol, including lists, dicts…

Well join should be on sequence instead of list then. To me it seems unnatural to see join on string because string feels more 'basic' than a sequence, so I would expect the sequence to know about strings rather than the opposite. But the argument against join on string is not as strong as the argument against sum on array.

That's just the thing: there is no sequence class in Python. There's only a sequence concept. A sequence is any object that implements a particular interface. Strings aren't more basic than the concept of a sequence in Python; strings are a type of sequence.

See http://docs.python.org/library/stdtypes.html#iterator-types and http://docs.python.org/library/stdtypes.html#http://docs.pyt...

Re: My Objection to Array#sum

#28
post #17

I agree with you. That being said, I suspect that this turns out to be a cultural debate more than anything else. Remember, Ruby is a freedom language. Ruby could eliminate many of the issues you raise by being strictly typed, but of course that'd defeat the purpose. The whole thing is a question of trust. Do you trust clients enough to give them the syntactic sugar of Array#sum even if their arrays may not all be st…

Disclaimer: I'm not a Rubyist.

I think saying "Ruby is a freedom language" is a cop-out for foregoing good design. It excuses us from having to think through if the design makes sense, because we can always throw up our hands and say "Ruby is a freedom language." But I also think that's not an entirely true statement: Ruby doesn't let programmers jump to any random line of code. (I did find a neat module that implemented gotos and labels, but I think it only works at proc granularity, not line granularity.) It doesn't let programmers muck with the the stack frames or manage their own memory.

The reason for these non-freedoms is that past experience has shown us that in some domains, some language features are high risk, low yield. I see the freedom of Ruby as a chance to experiment with many different ideas for language design, and the practical value of that is the languages we design in the future will have those lessons baked in. But by defaulting to the idea that it's a "freedom language," we resist learning.

I say this as a non-Rubyist. I wanted to learn a dynamically typed language, and I chose Python. I don't have the time now to delve deeply into two languages. So I'm commenting on this as an observer, but I'm an observer who sees the value in Ruby, and potential implications to future languages.

Re: My Objection to Array#sum

#29
post #25

Earlier quoted context omitted.

This is such a non-issue. Really. The parent posted the reasoning behind the decision, that reasoning is sound. Your disagreement is purely aesthetic, there's simply no practical reason why the current way is wrong. Please just accept that this is how it is, and stop complaining about it. Please?

Python is intended to be aesthetically pleasing in some sense, so I don't think aesthetic objections to some of its features are unwarranted.

This isn't one of the 'some'.

http://en.wikipedia.org/wiki/Color_of_the_bikeshed

Re: My Objection to Array#sum

#30
post #20

Earlier quoted context omitted.

Well join should be on sequence instead of list then. To me it seems unnatural to see join on string because string feels more 'basic' than a sequence, so I would expect the sequence to know about strings rather than the opposite. But the argument against join on string is not as strong as the argument against sum on array.

This is such a non-issue. Really. The parent posted the reasoning behind the decision, that reasoning is sound. Your disagreement is purely aesthetic, there's simply no practical reason why the current way is wrong. Please just accept that this is how it is, and stop complaining about it. Please?

That was my point when I started the thread. The Python decision is objectively justified for technical reasons. Yet a large number of people viscerally feel it's wrong. I blame human irrationality - but then, programming languages are meant for humans, so shouldn't they accommodate our irrationality? Otherwise, you get something like Haskell. ;-)

BTW, there are other cases where Python has gone the other way. Multiline lambdas, for instance. The case against multiline lambdas is essentially that they look ugly - they let you embed an indentation-sensitive block in what might be a parenthesized expression, which means you need some dangling delimiters. But they're certainly useful, as Scheme/Lisp/Ocaml/etc. have shown.

It's similar to the compare-constants-from-the-left idiom in languages where assignment is a valid expression (notably C). If you always write "if (NULL == foo)" instead of "if (foo == NULL)", you eliminate a whole class of bugs. But I've seen very few programmers do this, because it "feels" wrong to a lot of people.

Post reply on HN