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

make {a,b} give better-typed arrays [original title: make [a,b] non-concatenating] #2488

Closed
nolta opened this issue Mar 7, 2013 · 15 comments
Labels
kind:breaking This change will break code needs decision A decision on this change is needed
Milestone

Comments

@nolta
Copy link
Member

nolta commented Mar 7, 2013

It's redundant with [a;b], plus it creates the following trap for the unwary:

julia> { [1,2], [3,4] }
2-element Any Array:
 [1, 2]
 [3, 4]

julia> [ [1,2], [3,4] ]
4-element Int64 Array:
 1
 2
 3
 4
@JeffBezanson
Copy link
Sponsor Member

Thought of a reason not to do this: [1:n] would give a 1-element array of range instead of the expanded range vector we now expect.

@nolta
Copy link
Member Author

nolta commented Mar 8, 2013

Ah, good point. But that's also a degenerate comprehension, so maybe we could let people write [for 1:n] instead.

@JeffBezanson
Copy link
Sponsor Member

Probably a better option is to make {} give better-typed arrays, and not always Any arrays. {} can default to an Any array, and you can also use Any[] if you need to.

nolta added a commit that referenced this issue Jul 20, 2013
@kmsquire
Copy link
Member

@timholy
Copy link
Sponsor Member

timholy commented Dec 11, 2013

Overall I think improving the typing of {} is perhaps the best solution. But presumably it's obvious to everyone that we'd break some things that currently work:

A = {[1,2]}
push!(A, "Hello")

@kmsquire
Copy link
Member

With the exception of Jeff's example above, I find the syntax for concatenation sketchy. More than once I've struggled to easily create arrays of arrays because I forget that I need to attach the type.

For consistency, I would really prefer that anything with [] never concatenates (even for [1:5]), and that we find another way to expand 1:5 to [1,2,3,4,5].

@cdsousa
Copy link
Contributor

cdsousa commented Dec 12, 2013

Very personally, I like {} to behave like a Python list, i.e., an Any array.

Let me do a suggestion. Instead of the current behavior of [], maybe it could be something like:

[A, B, C, ...] new array
[A B C ...] hcat
[A; B; C; D; ...] vcat
[A B; C D; ...] hvcat

[1:5] could be changed to [1:5...] which, in fact, already works.

This is just another idea, I'm pretty aware that it would break a lot of stuff, and probably it would not cover all use cases.

OTHO improving the typing of {} will possibly break must less things, which could be fixed by attaching Any.

EDIT: Ok, sorry, I discovered now that @nolta's branch does exactly what I'd described.

@cdsousa
Copy link
Contributor

cdsousa commented Dec 12, 2013

I'll try to show the problem the concatenating [a,b] creates to me.
I have something like:

A = spzeros(3)
B = spzeros(3)
Cs = [spzeros(3) for i in 1:2]
Ds = [spzeros(3) for i in 1:2]

I want to put all sparse matrices into a single (typed) array of sparse matrices.

If I do

[Cs, Ds]

it is ok, it returns an array of sparse matrices.

However,

[[A], [B], Cs, Ds]

tries to concatenate and thus gives a dimension mismatch.

Doing

[A, B, Cs..., Ds...]

gives a 18x3 sparse matrix, not an array of sparse matrices. And

{A, B, Cs..., Ds...}

gives an array of sparse matrices, but the type is lost.

Currently I see no way to do what I want without having to specify the type SparseMatrixCSC{Float64,Int64} somewhere. Sure, this is not a big deal, but AFAIK Julia is supposed to create typed code without one having to care about types except for the multiple dispatch, am I wrong?

@JeffBezanson
Copy link
Sponsor Member

No, you have a good point. I think we all feel that [a,b] concatenating is an evil inherited from a certain other language.

@cdsousa
Copy link
Contributor

cdsousa commented Dec 25, 2013

Meanwhile, I was able to workaround the issue by using a function

array{T}(args::T...) = T[args...]

that enables me to do

array(A, B, Cs..., Ds...)

to obtain what I desired without having to explicitly write the type.

nolta added a commit that referenced this issue Jan 8, 2014
@cdsousa
Copy link
Contributor

cdsousa commented Feb 6, 2014

Sorry to ask again: will these changes eventually land in master? I getting array{T}(args::T...) = T[args...] defined everywhere (maybe I use too much arrays of arrays :)

@timholy
Copy link
Sponsor Member

timholy commented Feb 6, 2014

@cdsousa: just FYI there is so much awesome stuff being worked on in base Julia these days that this probably hasn't crested to the top of anyone's priority list yet. There's no predicting when it will, and I wouldn't be surprised if it took longer than you'd like. If you need it, your best bet might be to dive in and implement it yourself, and submit a pull request.

@filmackay
Copy link

I like the [1:5...] syntax - presumably making [1:5] being a single cell array with a Range object in it. Then you could do [1:5, 2:6] with two Range1 objects etc.

@cdsousa
Copy link
Contributor

cdsousa commented Feb 6, 2014

Thanks @timholy! My question was put since I saw that there were commits in some branch about this issue, but no PR so far. I was wondering more about if this will get implemented than when. Only after, I saw in another issue #3737 that there is a shared desire to change the current behavior, so I can guess that the answer is yes:) Anyway, I'm very happy there is so much work being put into Julia, this issue is just a detail.

@timholy
Copy link
Sponsor Member

timholy commented Feb 6, 2014

I hadn't noticed the commit, thanks for clarifying.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:breaking This change will break code needs decision A decision on this change is needed
Projects
None yet
Development

No branches or pull requests

7 participants