[swift-evolution] [swift-evolution-announce] [Review] SE-0099: Restructuring Condition Clauses
Xiaodi Wu
xiaodi.wu at gmail.com
Sat May 28 08:14:01 CDT 2016
Perhaps, but it is a much bigger change and a different proposal topic
entirely. Given how variable declarations work now, Erica's proposed syntax
to replace where clauses is the most elegant solution, IMO.
On Sat, May 28, 2016 at 04:15 Goffredo Marocchi via swift-evolution <
swift-evolution at swift.org> wrote:
> This I would not cry about. In other languages they are more of a source
> of pain than anything else.
>
> Sent from my iPhone
>
> > On 28 May 2016, at 09:10, David Hart via swift-evolution <
> swift-evolution at swift.org> wrote:
> >
> > Yet another alternative: would it be possible to disallow commas as
> variable declaration separators and use them for condition clause
> separators again:
> >
> > let a = 4, b = 8 // becomes illegal and requires to separate them on two
> lines
> >
> > if a > 4, let c = foo(), let d = bar(), c != d { // now comma is not
> ambiguous anymore
> > }
> >
> > David.
> >
> >>> On 28 May 2016, at 08:25, Brent Royal-Gordon via swift-evolution <
> swift-evolution at swift.org> wrote:
> >>>
> >>> Let me answer in another way that speaks to my background which isn't
> in compiler theory: The use of && may produce cognitive overload between
> the use in Boolean assertions and the use in separating condition clauses.
> >>
> >> Yes, which is quite intentional on my part. The `if` statement requires
> that all of its clauses succeed; if pattern matching and optional testing
> were boolean expressions, you would use `&&` to link them with each other
> and with boolean tests. The fact that these are *not* boolean expressions
> is a mere artifact of Swift's implementation.
> >>
> >> I think our best solution is to make Swift act as though these *are*
> boolean expressions, but ones that can only be used in a limited way: they
> can only be `&&`ed, because they bind variables that have to be made
> available in specific blocks. In other words, I think we should paper over
> the compiler limitations preventing these things from working as expected.
> >>
> >> (Actually, it might be interesting to allow `!let` and `!case`
> statements which are available in the `else` branches of the control
> structures they're used in, but that's a different story...)
> >>
> >> ***
> >>
> >> If you'll permit me to go sort of "mad dream" here for a moment, I can
> actually sort of see a way to do a lot of this in the standard library.
> Imagine if the `let` and `case` clauses in a conditional produced a type
> like this:
> >>
> >> enum PatternMatchingResult<BoundValues> {
> >> case failed
> >> case succeeded (BoundValues)
> >> }
> >>
> >> `BoundValues` would be the values, if any, extracted through the
> pattern matching operation. Then you could define operators like these:
> >>
> >> func && <T, U>(lhs: PatternMatchingResult<T>, rhs: @autoclosure ()
> -> PatternMatchingResult<U>) -> PatternMatchingResult<(T, U)> {
> >> guard case .succeeded (let lhsValue) = lhs else {
> >> return .failed
> >> }
> >> guard case .succeeded (let rhsValue) = rhs() else {
> >> return .failed
> >> }
> >> return .succeeded (lhsValue, rhsValue)
> >> }
> >>
> >> func && <T>(lhs: PatternMatchingResult<T>, rhs: @autoclosure () ->
> Boolean) -> PatternMatchingResult<T> {
> >> guard case .succeeded = lhs else {
> >> return .failed
> >> }
> >> guard rhs() else {
> >> return .failed
> >> }
> >> return lhs
> >> }
> >>
> >> func && <U>(lhs: Boolean, rhs: @autoclosure () ->
> PatternMatchingResult<U>) -> PatternMatchingResult<U> {
> >> guard lhs else {
> >> return .failed
> >> }
> >> return rhs()
> >> }
> >>
> >> And then transform this:
> >>
> >> guard
> >> x == 0 && a == b && c == d &&
> >> let y = optional, w = optional2, v = optional 3 &&
> >> z == 2
> >> else { ... }
> >>
> >> Into something like this (where `?` is a sort of "anonymous capture
> slot"):
> >>
> >> guard case let .success (y, w, v) = (
> >> x == 0 && a == b && c == d &&
> >> Pattern(.some(?), .some(?), .some(?)).result(ofMatchingAgainst:
> (optional, optional2, optional3)) &&
> >> z == 2
> >> )
> >> else { ... }
> >>
> >> Resolving to:
> >>
> >> guard case let PatternMatchingResult.success (y, w, v) = (
> >> (&&)( // (Boolean, PatternMatchingResult) ->
> PatternMatchingResult
> >> x == 0,
> >> (&&)( // (Boolean, PatternMatchingResult) ->
> PatternMatchingResult
> >> a == b,
> >> (&&)( // (Boolean, PatternMatchingResult) ->
> PatternMatchingResult
> >> c == d,
> >> (&&)( // (PatternMatchingResult, Boolean) ->
> PatternMatchingResult
> >> Pattern(.some(?), .some(?),
> .some(?)).result(ofMatchingAgainst: (optional, optional2, optional3)),
> >> z == 2
> >> )
> >> )
> >> )
> >> )
> >> )
> >> else { ... }
> >>
> >> The `Pattern` type shown here is notional, not an actual thing that
> would exist as a first-class entity—although that *would* be rather nice to
> have eventually...
> >>
> >> --
> >> Brent Royal-Gordon
> >> Architechies
> >>
> >> _______________________________________________
> >> swift-evolution mailing list
> >> swift-evolution at swift.org
> >> https://lists.swift.org/mailman/listinfo/swift-evolution
> >
> > _______________________________________________
> > swift-evolution mailing list
> > swift-evolution at swift.org
> > https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160528/27da2b40/attachment.html>
More information about the swift-evolution
mailing list