-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enumerable#sum(&)
fails with certain block arguments
#15317
Comments
Enumerable#sum(&)
fails with heterogeneous enumerablesEnumerable#sum(&)
fails with certain block arguments
To fix this issue, Instead, we could split the paths in b499bb2 contains the above described changes. Running |
Unlike Different variants of
235f1bf contains the above suggested changes. |
1) Flag the use of `sum(&)` with non-additive types at run-time. 2) Flag uses of `sum()` with strings with a compile-time warning. Eventually, change this warning into an error.
I don't think it makes sense to special-case The purpose of |
Note that the fact that this doesn't work protects people from using a quadratic complexity operation with tons of allocations instead of the linear operation which is |
@straight-shoota My first comment was about exploring the use of dedicated paths in As described in the latter half of my second comment, like @oprypin, I think that a better solution is to disallow the use of With regards to disallowing the use of |
Note: This comment is a "thinking out loud" comment. Here are three reasons why I think we should not add
As I write this comment, I am thinking we could drop |
@rvprasad I do not follow what's the issue with adding
That's fine. They are different concepts and use different roads to reach the same result.
Please note that 3rd party code could define types that add with
I fail to see why missing commutativity should be a reason to disallow summing up. The semantics of the
The @oprypin Efficiency is a valid concern, however I don't think the API should stand in the way of applying a generic concept to some use case just because there's a different, more efficient implementation available. This limits the general expressiveness, and performance isn't always paramount. We can of course try to optimize implementations like |
We must not be blinded by this coincidental sharing of the
I fail to see why it wouldn't be a reason to disqualify this. I think it must always hold that Anyway, I 100% agree with @rvprasad #15317 (comment). |
Let me rephrase:
Commutativity doesn't even hold for numerical types when integer and floating point arithmetics mix. [-1, 1, 0.3].sum(0) # => 0.3
[1, 0.3, -1].sum(0) # => 0.30000000000000004 |
@straight-shoota I think there are two aspects to this issue: technical and non-technical. On the technical front, I think adding However, my concerns are on the non-technical (language/library design) front: why provide identical ways to accomplish a task?
Regarding the situation where third party code defines domain types that can be added with Overall, I believe every language/library designs are subjective/opinionated. So, I think I am asking if such redundancy aligns with opinions/principles that inform the Crystal's design. That said, I am On a lighter note, I am reminded of a quote from Jurassic Park: Your scientists were so preoccupied with whether they could, they didn’t stop to think if they should. :) |
@straight-shoota Based on the below fragments, I believe the issue that you observed is due to the quirks of floating point arithmetic in Crystal (or in general). puts -1 + 1 + 0.3 # => 0.3
puts 1 + 0.3 - 1 # => 0.30000000000000004
puts 0.3 - 1 # => -0.7
puts -1 + 0.3 # => -0.7
puts 0.3 - 1 + 1 # => 0.30000000000000004
puts -1 + 0.3 + 1 # => 0.30000000000000004 |
That is only a technicality. Ideologically, addition of numbers is commutative and people mostly use it as if it is. @rvprasad regarding the latest comment, @straight-shoota understands the cause of it but he underlines this aspect anyway. |
Bug Report
Enumerable.sum(&)
should succeed as long as the block argument transforms the elements into values into types that supports addition. This pattern would be common when summing heterogeneous enumerables such as arrays and tuples. However, it fails in the following code snippet.Expected output:
ab
(similar to the output ofd.join
)Actual output:
Crystal version: 1.14.0
The text was updated successfully, but these errors were encountered: