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

disallow scalars in cat? #34395

Open
JeffBezanson opened this issue Jan 15, 2020 · 5 comments
Open

disallow scalars in cat? #34395

JeffBezanson opened this issue Jan 15, 2020 · 5 comments
Labels
arrays [a, r, r, a, y, s] breaking This change will break code needs decision A decision on this change is needed
Milestone

Comments

@JeffBezanson
Copy link
Member

The cat functions are currently very permissive:

julia> vcat([1], :a)
2-element Array{Any,1}:
 1
  :a

This can lead to confusion when non-array collections are passed and mysteriously treated as scalars, e.g.

julia> vcat([1], keys(Dict()))
2-element Array{Any,1}:
 1
  Any[]

So a similar situation to what we had before in broadcast. We should make the corresponding change to cat and require all arguments to be array-like somehow.

@JeffBezanson JeffBezanson added needs decision A decision on this change is needed breaking This change will break code arrays [a, r, r, a, y, s] labels Jan 15, 2020
@JeffBezanson JeffBezanson added this to the 2.0 milestone Jan 15, 2020
@JeffBezanson JeffBezanson changed the title disallow scalars in cat disallow scalars in cat? Jan 15, 2020
@tkf
Copy link
Member

tkf commented Jan 15, 2020

How do you handle [1; 2], [[1]; [2]], etc.?

@BioTurboNick
Copy link
Contributor

BioTurboNick commented Oct 17, 2020

Coming from my issue #38019 documenting a few of these oddities, concatenating scalars along one dimension seems like a reasonable function of cat.

To this issue, if cat is defined only for arrays, maybe it's okay that non-array collections are treated like scalars?

Worth noting that in Julia 1.5, the example in the OP is less confusing:

vcat([1], keys(Dict()))
#=
2-element Array{Any,1}:
 1
  Base.KeySet for a Dict{Any,Any} with 0 entries
=#

@goretkin
Copy link
Contributor

If I'm following, disallowing "scalars" (i.e. values of type eltype) would avoid this terribly inconsistent situation:

julia> vcat([(1,), (2,)], (3,))
3-element Vector{Tuple{Int64}}:
 (1,)
 (2,)
 (3,)

julia> vcat([[1,], [2,]], [3,])
3-element Vector{Any}:
  [1]
  [2]
 3

To concatenate one element, one can then use a one-element value, such as [x]. It would be nice, however, to have a generic spelling for concatenating one element to a static-sized array, such that the resulting size is inferred correctly.

@Seelengrab
Copy link
Contributor

Seelengrab commented Oct 29, 2021

This came up on zulip today, with the following example:

how can these have the same result?

julia> struct Foo end;

julia> vcat([1,2,3], [Foo()])
4-element Vector{Any}:
1
2
3
Foo()

julia> vcat([1,2,3], Foo())
4-element Vector{Any}:
1
2
3
 Foo()

The docstring of vcat and hcat are very sparse on details about what happens and what is expected of their input - should this be documented (albeit with a warning that it will be removed in a future version of julia)?

@knuesel
Copy link
Member

knuesel commented Feb 3, 2022

This also causes confusion with reduce, see here and here:

julia> typeof(reduce(vcat, [[1], [2]])) == typeof(reduce(vcat, [[1]]))
true

julia> typeof(reduce(vcat, [1, 2])) == typeof(reduce(vcat, [1]))
false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arrays [a, r, r, a, y, s] breaking This change will break code needs decision A decision on this change is needed
Projects
None yet
Development

No branches or pull requests

6 participants