-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
map(f, c) return type #15342
Comments
S = Set([1,2,3])
mapS = map(x-> x^2, S)
Z = Set{Int64}(mapS) # or whatever you want
# or more compactly
Z = Set{Int64}(map(x-> x^2, S)) |
I agree that we should use the same logic for the element type of the output container that we do for Arrays (ie, use the tightest type that can fit all the elements). For the other point, I think I agree that you want map to send sets to sets, even though there is no formal reason for that. That's more up for discussion I guess. |
Insofar as |
Well actually, you would end up losing the information of how many elements in the original set were mapped to a given element in the transformed set. |
And a similar issue regarding dicts: #5794 |
I'll echo others: I think it's desirable for map to take sets to sets. Certainly this was the behavior I intuitively expected. But more than that, in math notation like {f(x) | x \in S} is very common and represents a set; the most natural way to express this in Julia code would seem to be Edit: below Stefan points out the new generator syntax, which is perhaps a more natural way of expressing the set comprehensions and thus weakens my argument that map should obviously take sets to sets. It would also be nice to get detailed typed sets out, not Set{Any}. Naively I would think that if map applied to an array doesn't lose type information, neither should map applied to a set. See this recent post (mine) on julia-users for an example: https://groups.google.com/forum/#!topic/julia-users/qyDWkutI9AY |
Note that with the recently introduced generator syntax, you can express set comprehensions like so: Set(f(x) for x in S) That is very close to the mathematical set comprehension notation. (Historical note: we originally used |
There seems to be an agreement that |
Feel free to make a pull request with suggestions to improve the docs. But it's not that easy to do since the behavior is currently inconsistent: sometimes the type is preserved (like for tuples, strings, bit arrays), but the fallback is to return an |
This should definitely be documented for 0.4. For the future, having map on set produce a set seems like reasonable behavior, but I'm much more concerned about having a coherent overall policy. So the question is what is the general behavior of map on all kinds of collections and how can we implement it generically. The issues @JeffBezanson referenced are working towards such a framework. |
Ok, I will make a pull request for the documentation change when I get back from vacation next weekend. Regarding the general behavior of |
That would be terribly annoying. Better continue returning an array in that case. I don't see it as a problem since this behavior is quite predictable: it only depends on the type of the input, so it's unlikely to go unnoticed during development/testing. |
Disallowing |
|
It does make some kind of sense to map sets to sets, but I too wonder which kind of collection types would get this special treatment and which would continue to produce array results. It would be nice to say that we currently have a simple rule that
But sets are even more different in that they are not ordered or indexable. Maybe there should be another function for mapping an iterable into a set. It would have been nice to have a version of |
It could be useful to allow specifying the return container type to |
It's important to have a Finally, there's the obvious case to be made for |
I'm just wary of all the trouble we've had with trying to preserve array types for array operations using |
I'm surprised to hear that |
I see. I've encountered the same problem at other occasions. My solution So One could wrap this into the definition of -erik On Saturday, March 5, 2016, Milan Bouchet-Valat notifications@github.com
Erik Schnetter schnetter@gmail.com |
Another thing to consider is how to handle I'm not sure it will be easier with |
The simplest case of a Personally, I favour the restriction that all collections passed to Yes, passing multiple sets to |
this is a possible fix for #15342 type-accumulating Dict constructor
this is a possible fix for #15342 type-accumulating Dict constructor
this is a possible fix for #15342 type-accumulating Dict constructor
this is a possible fix for #15342 type-accumulating Dict constructor
this is a possible fix for #15342 type-accumulating Dict constructor
…traits make HasEltype and HasLength the default this is a possible fix for #15342 type-accumulating Dict constructor some tests for type accumulation in `map` and `Dict`
…traits make HasEltype and HasLength the default this is a possible fix for #15342 type-accumulating Dict constructor some tests for type accumulation in `map` and `Dict`
…traits make HasEltype and HasLength the default this is a possible fix for #15342 type-accumulating Dict constructor some tests for type accumulation in `map` and `Dict`
This issue seems "fixed"? Although the new behavior have caused other issues. Ref #15789. |
I was surprised to find that
map(identity, Set([1, 2]))
returns anArray
. Further, even if I writemap(identity, Set{Int}([1, 2]))
, the result is anArray{Any, 1}
.The documentation for
map
states:I expected "transform collection" to mean that the result is a collection of the same outer type as
c
. Of course, since "transform collection" is not defined exactly, this is not promised here. But from the documentation, it is a bit difficult to understand what to expect ofmap
s return value.To find out what exactly is going to happen when I call
map
I have to do something like@which map(f, c)
to find out which method will be called, and then I actually need to read the source. In my case (map(identity, Set())
) that ismap(f, iters...) at abstractarray.jl:1092
, which creates aresult = []
and returns it later on. The comment here says "generic map on any iterator" (shouldn't that say "iterable with defined length"?), and this seems to be the fallback case formap
.Proposals:
map
documentation should be changed to something along the lines of "Returns an iterable over the values obtained by applyingf
to each element in collectionc
." (If anyone relies on the result being anArray
in the general case, they should wrap the call withcollect
.)isa(c, Array{T, N})
), these special cases should be listed in the documentation.Set
s.I would be willing to do this myself, but wanted to ask for opinions first.
The text was updated successfully, but these errors were encountered: