Skip to content
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

2.0: Don't iterate Matrix #51043

Closed
jariji opened this issue Aug 24, 2023 · 7 comments
Closed

2.0: Don't iterate Matrix #51043

jariji opened this issue Aug 24, 2023 · 7 comments
Labels
breaking This change will break code speculative Whether the change will be implemented is speculative
Milestone

Comments

@jariji
Copy link
Contributor

jariji commented Aug 24, 2023

Almost always when I iterate a matrix it's a typo for eachrow(m) or eachcol(m). If I want to do it on purpose, I'd prefer to use a non-allocating iterator denoted vec(m) or eachval(m).

@jishnub jishnub added speculative Whether the change will be implemented is speculative breaking This change will break code labels Aug 25, 2023
@mikmoore
Copy link
Contributor

mikmoore commented Aug 25, 2023

Wouldn't this be really annoying for writing generic functions? The boilerplate seems awful. For example, a function like

function mysum(x)
	s = zero(eltype(x))
	for xx in x
		s += xx
	end
	return s
end

would need the extra methods

mysum(x::AbstractArray) = mysum(vec(x))
mysum(x::AbstractVector) = invoke(mysum, Tuple{Any}, x)

just to be sure that an AbstractArray was not iterated unless it was an AbstractVector. I imagine we'd end up needing this boilerplate on a lot of functions just to "undo" such a change. I'm also not convinced vec is zero-cost. Linear indexing into an IndexCartesian() style array requires divrem calculations to compute the Cartesian index.

Without some really compelling arguments, I think we're better off leaving it to the user to remember to eachcol when they want it.

@KristofferC
Copy link
Member

What's 2.0?

@jariji
Copy link
Contributor Author

jariji commented Aug 25, 2023

I'm also not convinced vec is zero-cost.

Explicitly creating an iterator shouldn't require any more cost than doing it implicitly. If vec doesn't currently do that then it can be changed or eachval can be introduced.

Wouldn't this be really annoying for writing generic functions?

sum(m::AbstractArray) = reduce(+, eachval(m))

@mbauman
Copy link
Member

mbauman commented Aug 25, 2023

This would need a larger philosophy of "what's an array" around it for motivation, I'd think. Currently, our arrays are collections of their items, and that's the rationale that underpins many of their behaviors (including this as well as other things like linear indexing and JuliaLang/LinearAlgebra.jl#42).

In any case, "what's 2.0?" is the best question here. :)

@mikmoore
Copy link
Contributor

mikmoore commented Aug 25, 2023

I assume "2.0" refers to this as a proposal for Julia v2.0 since this is obviously breaking.

I could see this making sense if we divorced the linear-algebraic concepts of "vectors, matrices, and tensors" from "n-dimensional arrays." Linear algebraic objects would likely just be trivial wrappers over n-dimensional arrays, but their behavior would diverge. For example, linear indexing into a 2-dimensional array can maybe make sense but linear indexing into (or iterating) a "matrix" does not. The multiplication of two matrices is defined but two arrays should either implement the element-wise product or no product at all (although still permitting .*, in either case). I would be very open to such a distinction. But as long we define the iteration of a "vector" to iterate its elements, we should do the same for "matrices" and "tensors."

@Jollywatt
Copy link
Contributor

One of the many uses of linear iteration for Arrays is having

B = [f(x) for x in A]

result in an array the same shape as A. I think not having Arrays be linearly iterable would be spectacularly bad.

@LilithHafner LilithHafner added this to the 2.0 milestone Aug 26, 2023
@timholy
Copy link
Member

timholy commented Aug 28, 2023

I really don't think this is a good idea; for one, it would break 99% of the code in JuliaImages. Should this really be on the 2.0 milestone? Or even remain open?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking This change will break code speculative Whether the change will be implemented is speculative
Projects
None yet
Development

No branches or pull requests

8 participants