Yeah, that's why I mentioned a big **if** at the end. I love the `do { }` 
construct or variable isolation purposes and logical grouping, but 
unfortunately, Swift 4 has made it a lot uglier, by making it an error in its 
current form:

do {
        let a = "123"
        print(a)
} // error: missing `while`, also use `repeat` instead

The workaround is to do this:

do {
        let a = "123"
        print(a)
};

It might seem like a little change, but this really really bugs me for some 
reason. I always felt like semicolons in Swift should never be mandatory and 
should only be used for writing multiple statements on the same line.

Overall, I agree that this isn't a big enough reason to change the syntax for. 
Let's just make the `do { }` great again instead.

> On Jun 10, 2017, at 3:33 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> _Every_ addition to the basic syntax of the language is, by definition, high 
> cost. The bar for additions to the standard library is already very high; the 
> bar for additions to control flow syntax would be extraordinarily high.
> 
> The proposed use case here is far from the original topic of repeat {} while, 
> which is unique because the condition lexically follows the loop.
> 
> For those loops in Swift where it is possible to declare variables in the 
> condition, these live in a magical middle scope that is intuitive to use but 
> also an exception to the rule of thumb that scopes are surrounded by braces. 
> As I wrote earlier, it is possible to manually create an analogous scope by 
> surrounding any loop with do {}. Any addition to the language would have to 
> be vastly superior to this currently possible alternative, and I seriously 
> doubt it is possible to invent such a thing because anything shorter than the 
> four letters in “do {}” would also obscure the existence of the middle scope 
> being created.
> 
> 
> On Sat, Jun 10, 2017 at 08:05 Goffredo Marocchi via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> If it is low cost and people do not come up with regressions/high cost + 
> negative impact scenarios then I would say go full steam ahead. It does 
> address an annoying scenario.
> 
> Sent from my iPhone
> 
> On 10 Jun 2017, at 12:04, Gor Gyolchanyan <g...@gyolchanyan.com 
> <mailto:g...@gyolchanyan.com>> wrote:
> 
>> Not much, I think. The `where` clause already exists, conditional `let` and 
>> `var` binding already exists. It'd take loosening up conditional binding 
>> rules a bit and expanding the lexical structure to include `let` and `var` 
>> bindings in `repeat`.
>> 
>>> On Jun 10, 2017, at 2:01 PM, Goffredo Marocchi <pana...@gmail.com 
>>> <mailto:pana...@gmail.com>> wrote:
>>> 
>>> Quite interesting :), what impact would it have on the compiler?
>>> 
>>> Sent from my iPhone
>>> 
>>> On 10 Jun 2017, at 11:46, Gor Gyolchanyan via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> I think a better way of achieving this would be to use the already 
>>>> existing `where` keyword in loops. The way it works right now is as 
>>>> follows:
>>>> 
>>>> let many = [1, 2, 3, 4, 5]
>>>> for each in many where each % 2 == 0 {
>>>>    print("found an even number: \(each)")
>>>> }
>>>> 
>>>> Unfortunately, unlike all other conditional scopes, `where` does not allow 
>>>> `let` and `var` bindings in it, so I'd suggest we add ability to do that:
>>>> 
>>>> let many: [Int?] = [1, 2, nil, 3, 4, nil, 5]
>>>> for each in many where let number = each {
>>>>    print("found a non-nil number: \(number)")
>>>> }
>>>> 
>>>> Or, more interestingly:
>>>> 
>>>> for each in many where let number = each, number % 2 == 0 {
>>>>    print("found a non-nil even number: \(number)")
>>>> }
>>>> 
>>>> And in case of a while loop:
>>>> 
>>>> var optional: Int? = 1
>>>> while let nonoptional = optional {
>>>>    if nonoptional >= 10 {
>>>>            optional = nil
>>>>    }
>>>>    optional = nonoptional + 1
>>>> }
>>>> 
>>>> But this is only for optional unpacking, so another addition would be to 
>>>> allow any `let` and `var` bindings in conditional scopes without them 
>>>> contributing to the condition itself:
>>>> 
>>>> while let a = 0, a < 10 {
>>>>    a += 1
>>>>    print(a)
>>>> }
>>>> 
>>>> And finally, allow these bindings in `repeat`:
>>>> 
>>>> repeat let a = 0 {
>>>>    a += 1
>>>>    print(0)
>>>> } while a < 10
>>>> 
>>>> I think **if** the core team would consider this a worthwhile addition, 
>>>> this would be a less invasive and more intuitive way of achieving what you 
>>>> want.
>>>> 
>>>>> On Jun 10, 2017, at 1:31 PM, Haravikk via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> Not sure if my e-mail didn't go through or if discussion just fizzled 
>>>>> out; one other benefit if we ever move to a proper message board is we 
>>>>> might gain the ability to bump topics. Anyway, I'll resend my message 
>>>>> just in case:
>>>>> 
>>>>> 
>>>>> 
>>>>> Just to add my thoughts, as I like the idea of adding the variables to 
>>>>> the start somehow, but was wondering if might make sense to have a 
>>>>> keyword such as "using", but allow it on all block statements, like-so:
>>>>> 
>>>>>   // Original use-case of repeat … while
>>>>>   repeat using (var i = 0) {
>>>>>           // Do something
>>>>>   } while (i < 20)
>>>>> 
>>>>>   // for … in demonstrating combination of using and where
>>>>>   for eachItem in theItems using (var i = 0) where (i < 20) {
>>>>>           // Do something either until theItems run out or i reaches 20
>>>>>   }
>>>>> 
>>>>>   // Standard while loop
>>>>>   while let eachItem = it.next() using (var i = 0) where (i < 20) {
>>>>>           // As above, but with an iterator and a while loop and 
>>>>> conditional binding to also stop on nil
>>>>>   }
>>>>> 
>>>>>   // Closure with its own captured variable
>>>>>   let myClosure:(Int) -> Int = using (var i = 0) { i += 1; return i * $0 }
>>>>> 
>>>>>   // If statements as well
>>>>>   if somethingIsTrue() using (var i = 0) where (i < 20) {
>>>>>           // Do something
>>>>>   }
>>>>> 
>>>>>   // Or even a do block; while it does nothing functionally new, I quite 
>>>>> like it aesthetically
>>>>>   do using (var i = 0) {
>>>>>           // Do something
>>>>>   }
>>>>> 
>>>>> Unifying principle here is that anything created in the using clause 
>>>>> belongs to the loop, conditional branch etc. only, but exists outside the 
>>>>> block itself (thus persisting in the case of loops and closures). I quite 
>>>>> like the possible interaction with where clauses here as a means to avoid 
>>>>> simple inner conditionals as well.
>>>>> 
>>>>> Basically the two clauses can work nicely together to avoid some common 
>>>>> inner and outer boilerplate, as well as reducing pollution from throwaway 
>>>>> variables.
>>>>> 
>>>>> Only one I'm a bit iffy on is the closure; I'm trying to avoid declaring 
>>>>> the captured variable externally, but I'm not convinced that having using 
>>>>> on its own is clear enough?
>>>>> 
>>>>> Anyway, just an idea!
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to