-
Notifications
You must be signed in to change notification settings - Fork 28
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
SIP-59 - Multiple assignments #73
Conversation
|
||
(x, a(0)) = (false, 1337) | ||
(x, a(1)) = f | ||
((x, a(1)), b(2)) = (f, 9000) |
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.
This "nested tuple only" structure here is a bit odd IMO
We don't really have anywhere else in the Scala language where we have "nested tuples only". Scala has things like:
- Patterns, which can be nested tuples or extractors
- Expressions, which can be tuples, or function calls
- Some places where we have flat lists only, e.g.
val a, b, c = Value
I wonder if it's possible to generalize this a bit to accept arbitrary patterns? At least then this will "look like" a pattern, so it's similar to other things in Scala? Or if not, e.g. due to syntactic conflict, we should document it in the Alternatives
section
def b = a | ||
var x = false | ||
|
||
(x, a(0)) = (false, 1337) |
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 are the limits of the a(...)
syntax?
(x, a("key")) = (false, "value") // Non-integer literals?
val i = 10
(x, a(i)) = (false, 1337) // Integer non-literals?
(x, a(i * 137)) = (false, 1337) // Non-trivial Expressions?
(x, a(1, 2)) = (false, 1337) // Multi-dimensional `update` assignment?
(x, a(foo.bar.qux(1))) = (false, 1337) // Looking up an array by index and using it in the assingment?
From what I understand, all these examples should just work 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.
The proposal does not suggest any restriction should apply. If a(x) = rhs
is legal scala, then (a(x), b) = (rhs, 2)
is also legal no matter what kind of expression is substituted for x
.
(x, a(0)) = (false, 1337) | ||
(x, a(1)) = f | ||
((x, a(1)), b(2)) = (f, 9000) | ||
(x) = Tuple1(false) |
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.
Should we just prohibit Tuple1
assignments? I feel like there are sufficiently few places where people actually want a Tuple1
that we do not need to support it. We can also add it later if it turns out to be really necessary, so might be good to keep our options open for the initial proposal
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 agree. Also, when it's "really needed", one can always write ._1
on the right-hand-side instead, with the same evaluation order.
var x = false | ||
|
||
(x, a(0)) = (false, 1337) | ||
(x, a(1)) = f |
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.
would it be perhaps more simple if it were only syntactically "tuple literal" expression on the left and right, then you can check for arity match in the parser, and perform rewrites in desugar before typechecking. Otherwise here you must introduce pattern match extraction on f
which is more complex.
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 think allowing tuple-typed values on the RHS is not truly-necessary, but it's definitely a nice-to-have, so even if it adds a bit more implementation complexity I think we should try to do it.
Having to manually unpack tuples to say (x, a(1)) = (f._1, f._2)
just sounds awfully verbose and counter-intuitive, especially since (f._1, f._2)
is meant to be the same as f
in most other contexts
I like this proposal in general. I've hit all the pain points in my own experience. Scala has always been a hybrid language, and the way the immutable multiple-assignment with There are some subtleties around the implementation, especially around evaluation order, but from a UX perspective I think we should definitely have this. |
Proof of concept implementation is in progress (see here). |
We discussed this SIP during today's meeting. Although we did not vote on it yet, there is broad consensus that we want to accept it. We have two pieces of feedback regarding the somewhat open questions. Overall, the committee would be in favor of:
|
The compiler is allowed to ignore this procedure and generate different code for optimization purposes as long as it can guarantee that such a change is not observable. | ||
For example, given two local variables `x` and `y`, their assignments in `(x, y) = (1, 2)` can be reordered or even performed in parallel. |
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.
Here the committee would prefer stronger wording: that there be a guarantee that no closure is actually allocated in the implementation. The closures are only mentioned to make the behavior clear.
The SIP committee voted today to accept this SIP at the Design stage, modulo the comments from last meeting (just above). |
No description provided.