Open schlichtanders opened 3 years ago
I can totally see why this would be convenient.
Here Pair
is not treated specially by dictionary()
; we iterate the argument and from those elements we then get the first and second thing as key and value. This way we can use (key, value)
tuples that come from zip
for example.
Currently this means that dictionary((a => b) => (c => d))
already has a meaning equivalent to dictionary([a => b, c=> d])
(so there are two elements with keys a
and c
). Specialising on Pair
would make this example become a single-element dictionary with key (a => b)
.
So two points I would make are:
The second point is why this was not implemented yet. I'm not sure whether to favour convenience or neatness here. If anyone has an opinion it would be appreciated.
thank you very much for the detailed insights.
Can you explain a bit more why 2. could become a problem here when constructing a Dictionary
?. I guess that if you need fast dictionary construction, you just switch to one of the other constructors anyway, because your probably rather have a list of pairs or keys and values separately.
I guess dictionary(:a => 1, :b => 2)
would in most of the cases only be used when creating a Dictionary for example purposes, where convenience is indeed very powerful to attract new users.
would in most of the cases only be used when creating a Dictionary for example purposes
Yeah, exactly, while an extra []
is only two characters - dictionary([:a => 1, :b => 2])
. Take Array
or Vector
for example, there's no multiple-value constructor there. There is however a literal syntax for arrays; along the same lines I'd love to have {:a = 1, :b = 2}
or something like that in the future, but I'm not sure how feasible that is.
Can you explain a bit more why 2. could become a problem here when constructing a Dictionary?
For example. one concern is that you could get sharp edges when you do dictionary(iter...)
and iter
happens to have exactly one thing, and it triggers some slightly different logic to when there are two or more things. I'm not sure if my worries are well-founded or imagined.
Yeah, exactly, while an extra
[]
is only two characters
indeed and at least for me these two characters feel that much unnecessary that I am looking for another constructor which I may have overlooked to support the plain interface. That is what happened to me, not sure about how this generalizes to other users, but I guess at least some will stumble mentally.
another good argument: Base.Dict probably had a discussion as well about whether they want to safe these two characters for convenience. They decided that it is worth. In addition people are now even used to having it.
dictionary(iter...)
Say iter = [:a => 1]
, an iterator of Pairs. then with the new Pair support, dictionary(iter...)
and dictionary(iter)
would return the same.
Only when you have an iterator of something not supported but still iterable, and having an iterable as the one and only element. What could this be? Tuples?
looking at Tuples and Dict shows that there actually is a safe-guard for this
julia> Dict((:a,1), (:b,2))
ERROR: MethodError: no method matching Dict(::Tuple{Symbol, Int64}, ::Tuple{Symbol, Int64})
julia> Dict((:a,1))
ERROR: ArgumentError: Dict(kv): kv needs to be an iterator of tuples or pairs
julia> Dict((i for i in 1:2)) # apparently this check even applies to (some?) iterators
ERROR: ArgumentError: Dict(kv): kv needs to be an iterator of tuples or pairs
would such safe-guards be enough to solve your doubts?
Potentially.
Perhaps one way to explain it is this: the way it is currently defined in terms of interfaces (iterate
) with no reference to concrete types at all, which is generally how I try to design generic functions in Julia (as I think that’s how you create generic & composable code).
In this case I worry that we “should” have a third construction function, which is varargs, roughly from_pairs(kvs…)
.
just getting to know
Dictionaries
the very first thing which feels uncomfortable when coming fromBase.Dict
is that there is no support for something likeDict(:a => 1, :b => 2)
.If I understand the interfaces correctly, this would be rather easy to add to the
dictionary
function, because so far it only supports a single argument call with something iterable.Is there anything preventing the support of
dictionary(:a => 1, :b => 2, ...)
?