Skip to content

Conversation

@rfourquet
Copy link
Member

A similar constructor exists for Dict. This allows

julia> Set(1, 2, 3)
Set([2, 3, 1])

I'm not sure if it's best to define this for each concrete type (i.e. Set, IntSet, ...) or for AbstractSet as I did here.

@rfourquet rfourquet added the collections Data structures holding multiple items, e.g. sets label Jun 22, 2017
@cstjean
Copy link
Contributor

cstjean commented Jun 22, 2017

I feel like it will lead to subtle bugs.

Set() === Set()
Set([1]) === Set([1])
Set([1], [1])  === Set([[1]])
Set(x...) === ? # type-unstable

Dict doesn't have that issue because it only accepts a vararg of Pair.

We could do the same with Set/set as with Tuple/tuple: define Set(iterable) and set(elements...). Although set feels more like a verb than a noun.

@rfourquet
Copy link
Member Author

Is it really (technically) type unstable though? But I agree this can be confusing that the behavior is different for 1 or more elements. I just found it a bit frustrating that it was not possible pass directly the elements (when more than 1) as arguments of Set (which is unused syntax till now).

@rfourquet rfourquet added the needs docs Documentation for this change is required label Jun 23, 2017
@nalimilan
Copy link
Member

The difference is that it's less of an issue for Dict since you can distinguish Pair arguments from other types. Here the ambiguity is more serious.

@cstjean
Copy link
Contributor

cstjean commented Jun 23, 2017

Is it really (technically) type unstable though?

f(x) = Set(x...)
@code_warntype f([[1,2]])

Granted, one would presumably not write Set(x...) when Set(x) works just as well.

@StefanKarpinski
Copy link
Member

This is how we used to do this and we changed it intentionally so that all collections are constructed by passing them an iterable which yields the elements to be contained. You have to pick one since otherwise Set([1]) can either mean the Set{Int} containing the integer 1 or the Set{Vector{Int}} containing the Int-vector [1]. The current scheme is initially less intuitive, but allows lovely things like Set(2^k for k=1:n) to create an Int-set of squares up to n, for example. IMO, that far outweighs the slight annoyance of having to write Set([1,2,3]) instead of Set(1,2,3).

@StefanKarpinski
Copy link
Member

StefanKarpinski commented Jun 26, 2017

One option would be for the constructor to take any number of iterables and then include all of the things all of them yield. The fact that numbers are iterable would mean that Set(1,2,3) would do what you want; of course, it would meant that Set([1,2],[3]) == Set([1,2,3]) which might be quite surprising to people.

@rfourquet
Copy link
Member Author

One option would be for the constructor to take any number of iterables and then include all of the things all of them yield

I really like this idea, which enables the multi-arguments constructors by extending the 1-arg version in a regular way, thanks!

@rfourquet rfourquet changed the title allow construction of Set from list of elements: Set(elts...) allow construction of Set from list of iterators: Set(itr...) Jul 4, 2017
base/intset.jl Outdated
very large integers), use [`Set`](@ref) instead.
# Examples
```
Copy link
Member

Choose a reason for hiding this comment

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

jldoctest?

Copy link
Member Author

@rfourquet rfourquet Jul 4, 2017

Choose a reason for hiding this comment

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

Yes good idea, will do.

@rfourquet
Copy link
Member Author

Stefan's idea seems pretty solid to me, I don't see any drawback to adding the possibility to have multiple iterators in the constructor. Would anyone be opposed to this change? this would be ready to go on my end.

@rfourquet rfourquet removed the needs docs Documentation for this change is required label Jul 4, 2017
@cstjean
Copy link
Contributor

cstjean commented Jul 4, 2017

it would mean that Set([1,2],[3]) == Set([1,2,3]) which might be quite surprising to people.

Or Set(1, [2], [[3]], "bat") == Set([1,2,[3], 'b', 'a', 't'])

@rfourquet
Copy link
Member Author

rfourquet commented Jul 4, 2017

Or Set(1, [2], [[3]], "bat") == Set([1,2,[3], 'b', 'a', 't'])

I'm not chocked by such a behavior:

  1. there is already Set("bat") == Set('b', 'a', 't')`,
  2. we already have union(1, [2], [[3]], "bat") == union([1,2,[3], 'b', 'a', 't']): so with this PR, we would get Set(itr...) == Set(union(itr...)) which makes sense for me.

@StefanKarpinski
Copy link
Member

I think the real problem with the idea is that people will see code that does Set(1, 2, 3), producing a set containing the ints 1, 2 and 3 and conclude that Set(a, b, c) will produce a set containing a, b and c – which is not generally the case. I'm not sure how much worse that is than the fact that Set(1) already has this issue.

@JeffBezanson
Copy link
Member

I find this a bit confusing, and I also dislike that it only applies to sets. We should only do this if we want all collection constructors to work like this (tricky, since it still conflicts somewhat with Dict constructors). Instead, we could add a vararg method to union! (one already exists for union).

@rfourquet
Copy link
Member Author

There is something similar for arrays with [a; b; c;], which behaves similarly to the proposed Set constructor here (admitedly, this is a less direct constructor). I would be willing to implement this change for other collections. For Dict, I don't see yet the problem, but Dict(itr...) = Dict(flatten(itr) would seem to work. I already have a private branch with union! accepting a vararg, but was waiting first for this PR to be sorted out.

I'm not sure how much worse that is than the fact that Set(1) already has this issue.

This will be subjective at that point! but I find it confusing to indeed have Set(1) returning Set([1]) but not being able to specify more than one element in this way.

@JeffBezanson
Copy link
Member

I still find it bizarre for Collection(a, b, c) to expect a, b, and c to be iterable and concatenate them. Does any other language do that? While we still have [a; b] syntax, concatenating behavior was not super popular and we should probably have less of it instead of more.

@rfourquet
Copy link
Member Author

Closing, since the benefit is not huge and the current trend is to use constructor syntax to specify different kinds of initialization, so at the very least we should wait that the general design for collection constructors matures before going with thiss.

@rfourquet rfourquet closed this Dec 7, 2017
@DilumAluthge DilumAluthge deleted the rf/set-ctor branch March 25, 2021 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

collections Data structures holding multiple items, e.g. sets

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants