-
-
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
0.5-style comprehensions #16622
0.5-style comprehensions #16622
Conversation
So will there be another breakage in the next (or later) release cycle to return a different type (or raise an error) for empty case? |
end | ||
end | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:-)
What fixed this part? As of yesterday weren't you thinking you'd have to special-case 2d to avoid a regression? |
I'm not sure. It might also be ok to give an error in the empty case. That's certainly safest, I just don't have a good handle on how important empty comprehensions are.
Not sure; I haven't run the benchmark in 2 weeks. The generated code is definitely really different now. There are many more SROA variables. (test case #15402 (comment)) |
@@ -977,7 +977,7 @@ X = [ i+2j for i=1:5, j=1:5 ] | |||
@test X[2,3] == 8 | |||
@test X[4,5] == 14 | |||
@test isequal(ones(2,3) * ones(2,3)', [3. 3.; 3. 3.]) | |||
@test isequal([ [1,2] for i=1:2, : ], [1 2; 1 2]) | |||
# @test isequal([ [1,2] for i=1:2, : ], [1 2; 1 2]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a note that this (undocumented / unused / unknown) syntax is gone now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I was just going to bring that up for discussion. Unfortunately there's a bigger problem: this is hitting the infinite-recursion-via-codegen issue --- is there an issue for that? I was just trying to find it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure it has an issue number, although I couldn't find it just now either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found it: #16201. It was closed.
What to do with the little-acknowledged n-d comprehension syntax, |
Is |
It prevents comprehensions from becoming vectors of vectors which are awkward to use in julia (compared to arrays), so the functionality is useful. |
Had I known about it I would have used it a couple of times when I have resorted to hcat([some comprehension producing a vector of vectors]...) kind of solutions. |
You can always do |
Maybe I was unclear. I was talking of the situation of having a comprehension producing a vector of vectors similar to julia> [[1, 2] for i = 1:3]
3-element Array{Array{Int64,1},1}:
[1,2]
[1,2]
[1,2] but actually wanting these collected in a matrix, which can be done with julia> hcat([[1, 2] for i = 1:3]...)'
3x2 Array{Int64,2}:
1 2
1 2
1 2 Had I known about the multidimensional comprehension syntax I would instead have done julia> [[1, 2] for i = 1:3, :]
3x2 Array{Int64,2}:
1 2
1 2
1 2 for a shorter solution, without splatting a possibly arbitrarily long vector. But I agree that the syntax is obscure and I would be as happy using a function instead. |
I didn't know about that syntax, but I've felt the need for an equivalent of |
I'm not aware of any so I ended up writing my own in On Tue, May 31, 2016 at 4:54 PM, Milan Bouchet-Valat <
|
Could be good to have something like this in Base. |
Basically this can be covered by collecting a
seems pretty clear and does not create unnecessary intermediates of the ranges in this case. |
|
||
'comprehension | ||
(lambda (e) | ||
(expand-forms (lower-comprehension #f (cadr e) (cddr e)))) | ||
(if (any (lambda (x) (eq? x ':)) (cddr e)) | ||
(error "N-d comprehension syntax has been removed")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only if some of the indices were colons, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what (if (any (lambda (x) (eq? x ':)) (cddr e))
checks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant the error message should be more specific (I can at least read some scheme)
e53df0f
to
07a076a
Compare
Passing CI! Get excited! |
for a in drop(argtypes,1) | ||
if !(isa(a,Const) || (isType(a) && !has_typevars(a.parameters[1]))) | ||
return false | ||
end | ||
end | ||
|
||
if f === return_type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just adding a breadcrumb here that I'm still not sure if this is sound. Also, with the way this is currently being used, I expect it will tend to obscure any type errors, meaning this is probably very poorly tested right now.
some generally-applicable changes from #16622
@JeffBezanson on this branch, with |
A comprehension always returns an |
That makes sense. Thanks, sorry for the noise. |
Looks like Appveyor was a 32-bit failure related to some kind of GitError. Needs a rebase. |
this removes `static_typeof` and `type_goto` fixes #7258
…ents this removes an extra layer of wrapping with `IteratorND` add some inline declarations for `Generator` iteration remove unused `IteratorND` type
this implements the "Steve Johnson compromise": - non-empty comprehensions don't depend on inference at all - in the empty case, we use either Union{} or the inferred type - therefore there is no regression in type precision in cases where we can infer a leaf type add Core.Inference.return_type This computes a return type (at compile time if possible) in a way that handles recursive dependencies in inference.
this also uses the new lowering for typed comprehensions, allowing all comprehensions on unknown-length iterables (fixes #1457)
I've looked at some of the regressions identified by nanosoldier. One issue is #17342. Another issue is that the comprehension body is not always inlined. If we want, that can (probably) be easily fixed by inserting an Since comprehension expressions tend to be small, it's surprising that they might not be inlined. #17340 has an example of some unexpectedly-large IR from small code, when indexing a LinSpace. |
I think the causes of the (few) regressions here are well-understood and we'll be able to address them in the RC period, so I'll merge this now. |
This could be it! I no longer see a regression in 2d comprehensions. I also implemented @stevengj 's approach, using inference only in the empty case to avoid type inference regressions.
This also makes comprehensions shape-preserving, i.e.
[2x for x in rand(2,2)]
gives a 2d result.Todo:
product(itr1, itr2)
#16437