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

RFC: Concatenating iterator #16708

Closed
wants to merge 1 commit into from
Closed

Conversation

mschauer
Copy link
Contributor

@mschauer mschauer commented Jun 1, 2016

An iterator that concatenates the elements of its argument, see #16622 . For example

julia> collect(Base.concat((i:i+2 for i in 1:4)))
3×4 Array{Int64,2}:
 1  2  3  4
 2  3  4  5
 3  4  5  6

It produces the elements in the same order as flatten. To determine the shape of the children it peaks at the first element of the argument. This implementation works for iterators which have the HasShape trait. Iterators with HasLength trait can be incorporated in a next step if the proposed design is sound.


function Concat(c)
s = start(c)
done(c, s) && error("argument to Concat(it) must contain at least one element")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw(ArgumentError("argument to Concat must contain at least one element")) would be more consistent with other iterator constructor error conditions

@mschauer mschauer force-pushed the concat branch 2 times, most recently from 04c2732 to 32c3cd4 Compare June 3, 2016 12:06

import Base.concat

@test collect((concat((i:i+10 for i in 1:3)))) == [1:11 2:12 3:13]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could write it like this collect(concat(i:i+10 for i in 1:3)) wouldn't you?

@JeffBezanson
Copy link
Member

Thinking about this some more, I'm not sure it adds much value over Flatten since it can only concatenate along trailing dimensions. It's also not good practice to call start before the user of the iterator, which may point to an inherent difficulty with n-d concatenation via iterators. Instead we might want a function f(itr, dim) that concatenates the elements of itr along a specified dimension. I'm not yet sure what to call this though.

@mschauer
Copy link
Contributor Author

mschauer commented Jun 3, 2016

The one thing what I found is nice about having a iterator implementing this (at the cost of peeking at the first element) is that it combines well with other iterators. Concatenation along a different dimension becomes

julia> collect(concat(zip([1:3,1:3]...)))
2×3 Array{Int64,2}:
 1  2  3
 1  2  3

and concatenation two levels deep is concat(concat(...)) etc

@mschauer
Copy link
Contributor Author

mschauer commented Jun 9, 2016

Maybe it is not an atypical situation that information about length becomes known as soon as the iterator got started and not before -- and that is all what is needed in collect, something like a length(itr, state)-function.

@Keno
Copy link
Member

Keno commented May 9, 2019

Is there a utility of having this as a shaped iterator as opposed to just reduce(hcat, (i:i+2 for i in 1:4))? In any case, I'm gonna close this since it's written against the old iterator protocol. If this is to be revived, it can be a new PR (with the new iteration protocol) or go in a package.

@Keno Keno closed this May 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants