[swift-evolution] Rekindling: "Extending declaration scope to condition for `repeat { } while ()"

Xiaodi Wu xiaodi.wu at gmail.com
Sat Jun 10 08:30:46 CDT 2017


Well, IMO, if that change was intentional, it’s the original change that
warrants a full-fledged proposal. Without it, I think it’d be justified to
call this a regression and file a bug!
On Sat, Jun 10, 2017 at 09:29 Gor Gyolchanyan <gor at gyolchanyan.com> wrote:

> Yeah. So, what's the official process for these kinds of things? I imagine
> it would warrant a full-fledged proposal, would it?
>
>
> On Jun 10, 2017, at 4:26 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
> I did not realize that change occurred with `do {}`! That seems like it
> should be a regression, given that previously there was explicitly a fix-it
> to rewrite naked `{}` to `do {}`.
> On Sat, Jun 10, 2017 at 09:06 Gor Gyolchanyan <gor at gyolchanyan.com> wrote:
>
>> 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.wu at 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 at 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 <gor at 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 <panajev at 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 at 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 at 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 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/20170610/86770ce1/attachment.html>


More information about the swift-evolution mailing list