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 <[email protected]> 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
> <[email protected] <mailto:[email protected]>> 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 <[email protected]
> <mailto:[email protected]>> 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 <[email protected]
>>> <mailto:[email protected]>> 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
>>> <[email protected] <mailto:[email protected]>> 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
>>>>> <[email protected] <mailto:[email protected]>> 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
>>>>> [email protected] <mailto:[email protected]>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> [email protected] <mailto:[email protected]>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>
> _______________________________________________
> swift-evolution mailing list
> [email protected] <mailto:[email protected]>
> https://lists.swift.org/mailman/listinfo/swift-evolution
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution