SE-0105: Removing Where Clauses from For-In Loops


(William Shipley) #1

I’m against removing “where" from “for/in”. I use it in my code and I think it aids readability quite a bit. In the example:

for x in theArray where x % 2 == 1 { print (x) }
I think it’s artificially confusing because the print is on the same line. If we break the line we see the “where” at the end of the line and it reads like the English I would use to tell someone what this loop is doing:

for x in theArray where x % 2 == 1 {
...
To me this reads very clearly: I’m looping through some values BUT I want to skip some, now here’s what I’m going to do with these values. Using “guard” for this purpose adds unnecessary lines of code and also allows for the (common in my experience!) bug of accidentally using “break” or “return” inside the guard instead of “continue”. Also, guard / continue just doesn’t read like a filter.

Having the filtering/where logic (eg: what I’m _iterating_ over) separated from the body of the loop (eg: what i’m _doing_ to those objects) is one of my favorite things about Swift.

Yes, we could also do that with “filter” followed by “forEach”, but then it would read totally backwards and I don’t always want that. (I mean, at this point “for/in blah” could be considered syntactic sugar for "blah.forEach {}” but I still want "for/in".)

for x in theArray where x % 2 == 1 { print (x) }
while let x = anArray.popLast() where x % 2 == 1 { print(x) }
In this example case the “while” is only unclear to me because Swift has the odd thing where it does pattern matching using “let” as well as using let in a plain old assignment, and it’s hard to know which is which. I could argue that it’s also unclear why I can’t type “let x = anArray popLast where x % 2 == 1” by itself on a line and have x be an optional. (I would have liked it if we used “match” as a keyword instead of “let” when we’re doing patterns, but there you go.)

-Wil


(Erica Sadun) #2

I have used odd-even examples a lot when presenting this concept, and inevitably the response
is "Whoa, that's cool". What I'm missing are more challenging real-world use-cases to justify
the construct, and an exploration of why the challenging cases would not need debugger
support at that point.

My concern (and I am happy to be corrected) is that any code that becomes slightly more
complex loses the beauty and readability and hinders debugging at the same time.

-- E

···

On Jun 23, 2016, at 7:34 PM, William Shipley via swift-evolution <swift-evolution@swift.org> wrote:

I’m against removing “where" from “for/in”. I use it in my code and I think it aids readability quite a bit. In the example:

for x in theArray where x % 2 == 1 { print (x) }


(Brandon Knope) #3

Maybe something like this?

let calendar = Calendar.current()

for date in dates where calendar.isDateInToday(date) {
    //process date only in today
}

VS.

for date in dates {
    guard calendar.isDateInToday(date) else { continue }
    
}

The where keeps the body of the for loop uncluttered so it can focus *just* on what's important: processing dates that are only in a certain day.

Also, let's pretend someone comes along later and decides to add some code to this loop:

for date in dates {
    /** Anything here is using an untested date **/
    /** Some programmer comes along later and adds unrelated
       * date handling code...or mistakenly adds code here **/

    guard calendar.isDateInToday(date) else { continue }
}

The where tells that this loop was intended to only deal with certain dates and enforces it. Guard only guards against it if code is added after it.

With the where clause it is:
- self-documenting
- must be changed if you want a different behavior, preventing unintended mistakes later

I don't want to say this is a "more" challenging example of filtering, but I do think it can show its expressiveness.

Brandon

···

Sent from my iPad

On Jun 23, 2016, at 10:14 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

On Jun 23, 2016, at 7:34 PM, William Shipley via swift-evolution <swift-evolution@swift.org> wrote:

I’m against removing “where" from “for/in”. I use it in my code and I think it aids readability quite a bit. In the example:

for x in theArray where x % 2 == 1 { print (x) }

I have used odd-even examples a lot when presenting this concept, and inevitably the response
is "Whoa, that's cool". What I'm missing are more challenging real-world use-cases to justify
the construct, and an exploration of why the challenging cases would not need debugger
support at that point.

My concern (and I am happy to be corrected) is that any code that becomes slightly more
complex loses the beauty and readability and hinders debugging at the same time.

-- E

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


(William Shipley) #4

Here are some of my real-world examples:

        for modelUUIDAndInterfaceElement in modelUUIDsToInterfaceElements where !usedInterfaceElements.contains(modelUUIDAndInterfaceElement.1) {

        }

        for anchor in wall.anchors where boundsRect.contains(anchor.origin) {

        }

        for otherWall: Wall in self where otherWall != wall && !removedWalls.contains(otherWall) {

        }

        for wall in self as Set<Wall> {
            for otherWall in self as Set<Wall> where otherWall != wall {

            }
        }

        for wall in self as Set<Wall> where !checkedWalls.contains(wall) {

        }

(x2 on that one)

        for otherPieceOfFurnitureNode in localFurnitureModelUUIDsToInterfaceElements!.values where otherPieceOfFurnitureNode !== pieceOfFurnitureNode {

        }

        for lineSegmentObject in wallRelatedLineSegments where remainingLineSegments.contains(lineSegmentObject) {

        }

        for colinearLineSegmentObject in remainingLineSegments where colinearLineSegmentObject.angle.isEssentially(infiniteLineAngle: lineSegmentObject.angle) {

        }

I think this is basically as many as are found on all of github?

-W


(Russ Bishop) #5

Here are two that are shipping right now.

for (key, tile) in self._cache where tile.tintColor != self.tintColor { }

for innerArray in actualValue where innerArray.contains(expectedElement) { }

Russ

···

On Jun 23, 2016, at 7:14 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

On Jun 23, 2016, at 7:34 PM, William Shipley via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I’m against removing “where" from “for/in”. I use it in my code and I think it aids readability quite a bit. In the example:

for x in theArray where x % 2 == 1 { print (x) }

I have used odd-even examples a lot when presenting this concept, and inevitably the response
is "Whoa, that's cool". What I'm missing are more challenging real-world use-cases to justify
the construct, and an exploration of why the challenging cases would not need debugger
support at that point.

My concern (and I am happy to be corrected) is that any code that becomes slightly more
complex loses the beauty and readability and hinders debugging at the same time.

— E


(Xiaodi Wu) #6

Here are some of my real-world examples:

        for modelUUIDAndInterfaceElement in modelUUIDsToInterfaceElements
where !usedInterfaceElements.contains(modelUUIDAndInterfaceElement.1) {

Not a practitioner of 80-character line limits, I take it?

···

On Fri, Jun 24, 2016 at 12:59 AM, William Shipley via swift-evolution < swift-evolution@swift.org> wrote:

        }

        for anchor in wall.anchors where boundsRect.contains(anchor.origin)
{

        }

        for otherWall: Wall in self where otherWall != wall &&
!removedWalls.contains(otherWall) {

        }

        for wall in self as Set<Wall> {
            for otherWall in self as Set<Wall> where otherWall != wall {

            }
        }

        for wall in self as Set<Wall> where !checkedWalls.contains(wall) {

        }

(x2 on that one)

        for otherPieceOfFurnitureNode in
localFurnitureModelUUIDsToInterfaceElements!.values where
otherPieceOfFurnitureNode !== pieceOfFurnitureNode {

        }

        for lineSegmentObject in wallRelatedLineSegments where
remainingLineSegments.contains(lineSegmentObject) {

        }

        for colinearLineSegmentObject in remainingLineSegments where
colinearLineSegmentObject.angle.isEssentially(infiniteLineAngle:
lineSegmentObject.angle) {

        }

I think this is basically as many as are found on all of github?

-W

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


(Erica Sadun) #7

Thank you for collecting and sharing these.

I suspect both of us look at these and say "Ah yes, this supports exactly what I've been saying".

-- E

···

On Jun 23, 2016, at 11:59 PM, William Shipley <wjs@mac.com> wrote:

Here are some of my real-world examples:

        for modelUUIDAndInterfaceElement in modelUUIDsToInterfaceElements where !usedInterfaceElements.contains(modelUUIDAndInterfaceElement.1) {

        }

        for anchor in wall.anchors where boundsRect.contains(anchor.origin) {

        }

        for otherWall: Wall in self where otherWall != wall && !removedWalls.contains(otherWall) {

        }

        for wall in self as Set<Wall> {
            for otherWall in self as Set<Wall> where otherWall != wall {

            }
        }

        for wall in self as Set<Wall> where !checkedWalls.contains(wall) {

        }

(x2 on that one)

        for otherPieceOfFurnitureNode in localFurnitureModelUUIDsToInterfaceElements!.values where otherPieceOfFurnitureNode !== pieceOfFurnitureNode {

        }

        for lineSegmentObject in wallRelatedLineSegments where remainingLineSegments.contains(lineSegmentObject) {

        }

        for colinearLineSegmentObject in remainingLineSegments where colinearLineSegmentObject.angle.isEssentially(infiniteLineAngle: lineSegmentObject.angle) {

        }

I think this is basically as many as are found on all of github?

-W


(David Rönnqvist) #8

We’ve also got two occurrences in our closed source, production code:

for (predicate, callback) in predicatesAndCallbacks where predicate(typedEvent) {
    callback(typedEvent)
}

and:

for conversation in conversations where conversation.state == .Established { }

They’re both quite simple and short, but I find them very readable (and I find the first one quite elegant). That said, it wouldn’t be much trouble for us to rewrite these using guard statements or any other construct.

- David

···

On 27 Jun 2016, at 00:47, Russ Bishop via swift-evolution <swift-evolution@swift.org> wrote:

On Jun 23, 2016, at 7:14 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Jun 23, 2016, at 7:34 PM, William Shipley via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I’m against removing “where" from “for/in”. I use it in my code and I think it aids readability quite a bit. In the example:

for x in theArray where x % 2 == 1 { print (x) }

I have used odd-even examples a lot when presenting this concept, and inevitably the response
is "Whoa, that's cool". What I'm missing are more challenging real-world use-cases to justify
the construct, and an exploration of why the challenging cases would not need debugger
support at that point.

My concern (and I am happy to be corrected) is that any code that becomes slightly more
complex loses the beauty and readability and hinders debugging at the same time.

— E

Here are two that are shipping right now.

for (key, tile) in self._cache where tile.tintColor != self.tintColor { }

for innerArray in actualValue where innerArray.contains(expectedElement) { }

Russ
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(William Shipley) #9

I don’t understand why anyone wouldn’t just let Xcode do the wrapping for most cases. I’ll add newlines if I think it adds to clarity, but in general I don’t want to code like i’m still on a Wyse WY-50.

-W

···

On Jun 23, 2016, at 11:04 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

Not a practitioner of 80-character line limits, I take it?


(Sean Heber) #10

I’ll share some of mine from a single game project. Note this hasn’t been converted to Swift 3 and this is not all of them - just a varied sampling:

for location in random.sample(map, density: 0.007) where map.allowsGrassAt(location) && !map.hasGrassAt(location) {
}

for location in type.designatedLocations where location.z == Global.cameraZ && !locations.contains(location) {
}

for location in region where location.z == mouseLocation.z {
}

for location in path where location.z == Global.cameraZ {
}

for below in location.below.cardinals where contains(below) && hasSurfaceAt(below) {
}

for neighbor in location.cardinals where contains(neighbor) && isRampAt(neighbor) && !isFloorAt(neighbor.above) {
}

for neighbor in cardinals where contains(neighbor) && !isSolidAt(neighbor) {
}

for console in consoles.reverse() where console.hitTest(vector) {
}

And these 2 made good use, IMO, of “if-where” but I think that’s no longer in Swift 3? :confused:

if let there = debugClickedSurfaceAt, here = mouseSurface where Global.debugPathTest {
}

if let here = mouseAt where Global.debugWalkNeighbors {
}

l8r
Sean

···

On Jun 24, 2016, at 8:24 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

Thank you for collecting and sharing these.

I suspect both of us look at these and say "Ah yes, this supports exactly what I've been saying".

-- E

On Jun 23, 2016, at 11:59 PM, William Shipley <wjs@mac.com> wrote:

Here are some of my real-world examples:

        for modelUUIDAndInterfaceElement in modelUUIDsToInterfaceElements where !usedInterfaceElements.contains(modelUUIDAndInterfaceElement.1) {

        }

        for anchor in wall.anchors where boundsRect.contains(anchor.origin) {

        }

        for otherWall: Wall in self where otherWall != wall && !removedWalls.contains(otherWall) {

        }

        for wall in self as Set<Wall> {
            for otherWall in self as Set<Wall> where otherWall != wall {

            }
        }

        for wall in self as Set<Wall> where !checkedWalls.contains(wall) {

        }

(x2 on that one)

        for otherPieceOfFurnitureNode in localFurnitureModelUUIDsToInterfaceElements!.values where otherPieceOfFurnitureNode !== pieceOfFurnitureNode {

        }

        for lineSegmentObject in wallRelatedLineSegments where remainingLineSegments.contains(lineSegmentObject) {

        }

        for colinearLineSegmentObject in remainingLineSegments where colinearLineSegmentObject.angle.isEssentially(infiniteLineAngle: lineSegmentObject.angle) {

        }

I think this is basically as many as are found on all of github?

-W

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


(Erica Sadun) #11

Here are some of my real-world examples:

        for modelUUIDAndInterfaceElement in modelUUIDsToInterfaceElements where !usedInterfaceElements.contains(modelUUIDAndInterfaceElement.1) {

Not a practitioner of 80-character line limits, I take it?

80-character line limits aren't why these examples are problematic for me.
Other than a few positive examples like this wall.anchors one,

         for anchor in wall.anchors where boundsRect.contains(anchor.origin) {

most of these read as if there is too much logic stuffed into a single line:

for otherWall: Wall in self where otherWall != wall && !removedWalls.contains(otherWall) {

        for otherPieceOfFurnitureNode in localFurnitureModelUUIDsToInterfaceElements!.values where otherPieceOfFurnitureNode !== pieceOfFurnitureNode {

        for lineSegmentObject in wallRelatedLineSegments where remainingLineSegments.contains(lineSegmentObject) {

        for colinearLineSegmentObject in remainingLineSegments where colinearLineSegmentObject.angle.isEssentially(infiniteLineAngle: lineSegmentObject.angle) {

-- E

···

On Jun 24, 2016, at 12:04 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Fri, Jun 24, 2016 at 12:59 AM, William Shipley via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:


(Patrick Smith) #12

I’ve never quite understood why people are so strict about keeping to this?

···

On 24 Jun 2016, at 4:04 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

Not a practitioner of 80-character line limits, I take it?


(Tony Arnold) #13

I wasn’t going to be +1 guy, but “+1”:

I use where pretty heavily across both `if let` and in `for … in` loops.

I find both really readable when formatted, and I’d be disappointed to see them go.

I’m super annoyed that I missed (see “wasn’t paying attention during”) the review of SE-0099 because I would have loved to see `where` remain usable — it reads better than a comma and forces an order to things that made a lot of sense to me.

thanks,

Tony

···

On 27 Jun 2016, at 18:15, David Rönnqvist via swift-evolution <swift-evolution@swift.org> wrote:

We’ve also got two occurrences in our closed source, production code:

for (predicate, callback) in predicatesAndCallbacks where predicate(typedEvent) {
    callback(typedEvent)
}

and:

for conversation in conversations where conversation.state == .Established { }

They’re both quite simple and short, but I find them very readable (and I find the first one quite elegant). That said, it wouldn’t be much trouble for us to rewrite these using guard statements or any other construct.

- David

On 27 Jun 2016, at 00:47, Russ Bishop via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Jun 23, 2016, at 7:14 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Jun 23, 2016, at 7:34 PM, William Shipley via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I’m against removing “where" from “for/in”. I use it in my code and I think it aids readability quite a bit. In the example:

for x in theArray where x % 2 == 1 { print (x) }

I have used odd-even examples a lot when presenting this concept, and inevitably the response
is "Whoa, that's cool". What I'm missing are more challenging real-world use-cases to justify
the construct, and an exploration of why the challenging cases would not need debugger
support at that point.

My concern (and I am happy to be corrected) is that any code that becomes slightly more
complex loses the beauty and readability and hinders debugging at the same time.

— E

Here are two that are shipping right now.

for (key, tile) in self._cache where tile.tintColor != self.tintColor { }

for innerArray in actualValue where innerArray.contains(expectedElement) { }

Russ
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

----------
Tony Arnold
+61 411 268 532
http://thecocoabots.com/

ABN: 14831833541


(TJ Usiyan) #14

I think that we should change it to `if. Inline filtering is useful, even
if it isn't used much at present but the inconsistency doesn't help
adoption.

···

On Fri, Jun 24, 2016 at 11:06 AM, Sean Heber via swift-evolution < swift-evolution@swift.org> wrote:

I’ll share some of mine from a single game project. Note this hasn’t been
converted to Swift 3 and this is not all of them - just a varied sampling:

for location in random.sample(map, density: 0.007) where
map.allowsGrassAt(location) && !map.hasGrassAt(location) {
}

for location in type.designatedLocations where location.z ==
Global.cameraZ && !locations.contains(location) {
}

for location in region where location.z == mouseLocation.z {
}

for location in path where location.z == Global.cameraZ {
}

for below in location.below.cardinals where contains(below) &&
hasSurfaceAt(below) {
}

for neighbor in location.cardinals where contains(neighbor) &&
isRampAt(neighbor) && !isFloorAt(neighbor.above) {
}

for neighbor in cardinals where contains(neighbor) && !isSolidAt(neighbor)
{
}

for console in consoles.reverse() where console.hitTest(vector) {
}

And these 2 made good use, IMO, of “if-where” but I think that’s no longer
in Swift 3? :confused:

if let there = debugClickedSurfaceAt, here = mouseSurface where
Global.debugPathTest {
}

if let here = mouseAt where Global.debugWalkNeighbors {
}

l8r
Sean

> On Jun 24, 2016, at 8:24 AM, Erica Sadun via swift-evolution < > swift-evolution@swift.org> wrote:
>
> Thank you for collecting and sharing these.
>
> I suspect both of us look at these and say "Ah yes, this supports
exactly what I've been saying".
>
> -- E
>
>> On Jun 23, 2016, at 11:59 PM, William Shipley <wjs@mac.com> wrote:
>>
>> Here are some of my real-world examples:
>>
>> for modelUUIDAndInterfaceElement in
modelUUIDsToInterfaceElements where
!usedInterfaceElements.contains(modelUUIDAndInterfaceElement.1) {
>> …
>> }
>>
>> for anchor in wall.anchors where
boundsRect.contains(anchor.origin) {
>> …
>> }
>>
>> for otherWall: Wall in self where otherWall != wall &&
!removedWalls.contains(otherWall) {
>> …
>> }
>>
>> for wall in self as Set<Wall> {
>> for otherWall in self as Set<Wall> where otherWall != wall {
>> …
>> }
>> }
>>
>> for wall in self as Set<Wall> where
!checkedWalls.contains(wall) {
>> …
>> }
>>
>> (x2 on that one)
>>
>> for otherPieceOfFurnitureNode in
localFurnitureModelUUIDsToInterfaceElements!.values where
otherPieceOfFurnitureNode !== pieceOfFurnitureNode {
>> …
>> }
>>
>> for lineSegmentObject in wallRelatedLineSegments where
remainingLineSegments.contains(lineSegmentObject) {
>> …
>> }
>>
>> for colinearLineSegmentObject in remainingLineSegments where
colinearLineSegmentObject.angle.isEssentially(infiniteLineAngle:
lineSegmentObject.angle) {
>> …
>> }
>>
>>
>> I think this is basically as many as are found on all of github?
>>
>> -W
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Charlie Monroe) #15

Ditto, screens can handle more than 80 chars per line nowadays (and it's even quite a few years since I've last seen a display with <1024 horizontal resolution). It's not a good idea to write a line from one end of a screen to the other on a 27'' display, but 80 chars is really insane.

80 chars is useful to keep for readability of documentation, but not in code.

···

On Jun 24, 2016, at 11:25 AM, Patrick Smith via swift-evolution <swift-evolution@swift.org> wrote:

I’ve never quite understood why people are so strict about keeping to this?

On 24 Jun 2016, at 4:04 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Not a practitioner of 80-character line limits, I take it?

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


(Brandon Knope) #16

And these 2 made good use, IMO, of “if-where” but I think that’s no longer in Swift 3? :confused:

if let there = debugClickedSurfaceAt, here = mouseSurface where Global.debugPathTest {
}

if let here = mouseAt where Global.debugWalkNeighbors {
}

Just for completeness, these will now be:

if let there = debugClickedSurfaceAt, let here = mouseSurface, Global.debugPathTest {
}

if let here = mouseAt, Global.debugWalkNeighbors {
}

Not too sure if this is any clearer ¯\_(ツ)_/¯

···

On Jun 24, 2016, at 11:06 AM, Sean Heber via swift-evolution <swift-evolution@swift.org> wrote:

l8r
Sean

On Jun 24, 2016, at 8:24 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

Thank you for collecting and sharing these.

I suspect both of us look at these and say "Ah yes, this supports exactly what I've been saying".

-- E

On Jun 23, 2016, at 11:59 PM, William Shipley <wjs@mac.com> wrote:

Here are some of my real-world examples:

       for modelUUIDAndInterfaceElement in modelUUIDsToInterfaceElements where !usedInterfaceElements.contains(modelUUIDAndInterfaceElement.1) {

       }

       for anchor in wall.anchors where boundsRect.contains(anchor.origin) {

       }

       for otherWall: Wall in self where otherWall != wall && !removedWalls.contains(otherWall) {

       }

       for wall in self as Set<Wall> {
           for otherWall in self as Set<Wall> where otherWall != wall {

           }
       }

       for wall in self as Set<Wall> where !checkedWalls.contains(wall) {

       }

(x2 on that one)

       for otherPieceOfFurnitureNode in localFurnitureModelUUIDsToInterfaceElements!.values where otherPieceOfFurnitureNode !== pieceOfFurnitureNode {

       }

       for lineSegmentObject in wallRelatedLineSegments where remainingLineSegments.contains(lineSegmentObject) {

       }

       for colinearLineSegmentObject in remainingLineSegments where colinearLineSegmentObject.angle.isEssentially(infiniteLineAngle: lineSegmentObject.angle) {

       }

I think this is basically as many as are found on all of github?

-W

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

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


(L Mihalkovic) #17

I’ve never quite understood why people are so strict about keeping to this?

especially considering how many who do have never seen a vt100 terminal

···

On Jun 24, 2016, at 11:25 AM, Patrick Smith via swift-evolution <swift-evolution@swift.org> wrote:

On 24 Jun 2016, at 4:04 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

Not a practitioner of 80-character line limits, I take it?

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


(Xiaodi Wu) #18

Of course, to each their own style--I certainly wouldn't want Swift to
force everyone to write lines of certain lengths. But 80-character lines is
a common style, and I would say that a corollary of "to each their own" is
that Swift's grammar should be usable and useful whether or not you adhere
to such style choices.

If the chief advantage of `where` is that it (quoting someone above) allows
one to "understand as much as possible about the control flow of the loop
from a single line of code," then we ought perhaps to question its
appropriateness when the majority of its benefits [by which I mean, based
on your examples and Sean's, more than half of the instances in which it is
used] cannot be realized in a very common coding style.

···

On Fri, Jun 24, 2016 at 6:37 AM, William Shipley <wjs@mac.com> wrote:

On Jun 23, 2016, at 11:04 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

Not a practitioner of 80-character line limits, I take it?

I don’t understand why anyone wouldn’t just let Xcode do the wrapping for
most cases. I’ll add newlines if I think it adds to clarity, but in general
I don’t want to code like i’m still on a Wyse WY-50.


(Xiaodi Wu) #19

Here are some of my real-world examples:

        for modelUUIDAndInterfaceElement in modelUUIDsToInterfaceElements
where !usedInterfaceElements.contains(modelUUIDAndInterfaceElement.1) {

Not a practitioner of 80-character line limits, I take it?

80-character line limits aren't why these examples are problematic for me.

Sorry, I'm going to selfishly interject here to clarify what I meant by
that question to Wil.

I was not implying that his code was problematic for me--far be it from me
to critique Wil's code or style, a task for which I'm not qualified. And
I'm truly appreciative that Wil was willing to share his code so that we
could learn about the use of `where` in closed-source contexts.

The point I was trying to bring up was that a purported advantage of
keeping `where` is moot for those who *do* observe line limits, which
includes the Swift stdlib itself as well as (IIUC) house style at Google,
Microsoft, etc.

···

On Fri, Jun 24, 2016 at 4:33 PM, Erica Sadun <erica@ericasadun.com> wrote:

On Jun 24, 2016, at 12:04 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Fri, Jun 24, 2016 at 12:59 AM, William Shipley via swift-evolution < > swift-evolution@swift.org> wrote:

Other than a few positive examples like this wall.anchors one,

         for anchor in wall.anchors where boundsRect.contains(anchor.
origin) {

most of these read as if there is too much logic stuffed into a single
line:

for otherWall: Wall in self where otherWall != wall && !removedWalls.

contains(otherWall) {

        for otherPieceOfFurnitureNode in
localFurnitureModelUUIDsToInterfaceElements!.values where
otherPieceOfFurnitureNode !== pieceOfFurnitureNode {

        for lineSegmentObject in wallRelatedLineSegments where
remainingLineSegments.contains(lineSegmentObject) {

        for colinearLineSegmentObject in remainingLineSegments where
colinearLineSegmentObject.angle.isEssentially(infiniteLineAngle:
lineSegmentObject.angle) {

-- E


(Charlie Monroe) #20

If the `where` keyword were to stay in the language, how would you feel about extending it? One major argument is that it is not as powerful as guard or if. How about something like this was allowed:

for text in self.texts where let data = text.data(usingEncoding: NSASCIIEncoding) {
  /// Do something with data or text
}

···

On Jun 24, 2016, at 5:06 PM, Sean Heber via swift-evolution <swift-evolution@swift.org> wrote:

I’ll share some of mine from a single game project. Note this hasn’t been converted to Swift 3 and this is not all of them - just a varied sampling:

for location in random.sample(map, density: 0.007) where map.allowsGrassAt(location) && !map.hasGrassAt(location) {
}

for location in type.designatedLocations where location.z == Global.cameraZ && !locations.contains(location) {
}

for location in region where location.z == mouseLocation.z {
}

for location in path where location.z == Global.cameraZ {
}

for below in location.below.cardinals where contains(below) && hasSurfaceAt(below) {
}

for neighbor in location.cardinals where contains(neighbor) && isRampAt(neighbor) && !isFloorAt(neighbor.above) {
}

for neighbor in cardinals where contains(neighbor) && !isSolidAt(neighbor) {
}

for console in consoles.reverse() where console.hitTest(vector) {
}

And these 2 made good use, IMO, of “if-where” but I think that’s no longer in Swift 3? :confused:

if let there = debugClickedSurfaceAt, here = mouseSurface where Global.debugPathTest {
}

if let here = mouseAt where Global.debugWalkNeighbors {
}

l8r
Sean

On Jun 24, 2016, at 8:24 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

Thank you for collecting and sharing these.

I suspect both of us look at these and say "Ah yes, this supports exactly what I've been saying".

-- E

On Jun 23, 2016, at 11:59 PM, William Shipley <wjs@mac.com> wrote:

Here are some of my real-world examples:

       for modelUUIDAndInterfaceElement in modelUUIDsToInterfaceElements where !usedInterfaceElements.contains(modelUUIDAndInterfaceElement.1) {

       }

       for anchor in wall.anchors where boundsRect.contains(anchor.origin) {

       }

       for otherWall: Wall in self where otherWall != wall && !removedWalls.contains(otherWall) {

       }

       for wall in self as Set<Wall> {
           for otherWall in self as Set<Wall> where otherWall != wall {

           }
       }

       for wall in self as Set<Wall> where !checkedWalls.contains(wall) {

       }

(x2 on that one)

       for otherPieceOfFurnitureNode in localFurnitureModelUUIDsToInterfaceElements!.values where otherPieceOfFurnitureNode !== pieceOfFurnitureNode {

       }

       for lineSegmentObject in wallRelatedLineSegments where remainingLineSegments.contains(lineSegmentObject) {

       }

       for colinearLineSegmentObject in remainingLineSegments where colinearLineSegmentObject.angle.isEssentially(infiniteLineAngle: lineSegmentObject.angle) {

       }

I think this is basically as many as are found on all of github?

-W

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

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