Proposal: Add function SequenceType.find()

I would prefer a label on the first parameter, since you're not finding the NSButton type but instead elements having the type of NSButton.

subviews.find(havingType: NSButton.self, matching: { $0.state == NSOnState })

To comply with the guidelines I would expect a phrase like

subviews.findElement(havingType: NSButton.self, matching: { $0.state == NSOnState })
subviews.find(instanceOf: NSButton.self, matching: { $0.state == NSOnState })

-Thorsten

···

Am 18.02.2016 um 20:36 schrieb Trent Nadeau via swift-evolution <swift-evolution@swift.org>:

On Thu, Feb 18, 2016 at 4:37 AM, Marco Masser via swift-evolution <swift-evolution@swift.org> wrote:

On 2016-02-18, at 00:46, Kevin Ballard via swift-evolution <swift-evolution@swift.org> wrote:

Alternatively you can write

    subviews.lazy.flatMap({ $0 as? NSButton }).find({ $0.state == NSOnState })

Just to reiterate my point: I very much prefer the version without any casts. I just think this is much clearer and doesn’t put the burden of thinking about accidental memory and speed overhead (when forgetting the “lazy”) on the caller every time:

subviews.find(NSButton.self, matching: { $0.state == NSOnState })

Also, there’s the goal of Swift being easy to learn. Which line do you think is easier to explain to newcomers?

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

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

I would prefer a label on the first parameter, since you're not finding the NSButton type but instead elements having the type of NSButton.

subviews.find(havingType: NSButton.self, matching: { $0.state == NSOnState })

To comply with the guidelines I would expect a phrase like

subviews.findElement(havingType: NSButton.self, matching: { $0.state == NSOnState })
subviews.find(instanceOf: NSButton.self, matching: { $0.state == NSOnState })

A funny thing just happened—I was writing some Swift, needed something like `find`, remembered this thread, copied it in, andt ehn realized I wanted to find-and-cast at the same time. Here's what I ended up doing:

extension SequenceType {
    func find<U>(@noescape finder: Generator.Element throws -> U?) rethrows -> U? {
        for elem in self {
            if let returnValue = try finder(elem) {
                return returnValue
            }
        }
        return nil
    }
    
    func find(@noescape predicate: Generator.Element throws -> Bool) rethrows -> Generator.Element? {
        return try find { try predicate($0) ? $0 : nil }
    }
}

Then the code that used it ended up being:

        var bitmap = representations.find { $0 as? NSBitmapImageRep } ?? makeNormalizedBitmapRep()

Which I think is about as nice as I could've hoped for.

···

--
Brent Royal-Gordon
Architechies

A version specifically for dealing with downcasts seems very special purpose to this particular use case, especially when you can just use flatMap.

-DW

···

On Feb 18, 2016, at 2:01 PM, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

Am 18.02.2016 um 20:36 schrieb Trent Nadeau via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

I would prefer a label on the first parameter, since you're not finding the NSButton type but instead elements having the type of NSButton.

subviews.find(havingType: NSButton.self, matching: { $0.state == NSOnState })

To comply with the guidelines I would expect a phrase like

subviews.findElement(havingType: NSButton.self, matching: { $0.state == NSOnState })
subviews.find(instanceOf: NSButton.self, matching: { $0.state == NSOnState })

-Thorsten

On Thu, Feb 18, 2016 at 4:37 AM, Marco Masser via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 2016-02-18, at 00:46, Kevin Ballard via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Alternatively you can write

    subviews.lazy.flatMap({ $0 as? NSButton }).find({ $0.state == NSOnState })

Just to reiterate my point: I very much prefer the version without any casts. I just think this is much clearer and doesn’t put the burden of thinking about accidental memory and speed overhead (when forgetting the “lazy”) on the caller every time:

subviews.find(NSButton.self, matching: { $0.state == NSOnState })

Also, there’s the goal of Swift being easy to learn. Which line do you think is easier to explain to newcomers?

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

--
Trent Nadeau
_______________________________________________
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 <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Indeed. I quite like the second version.

···

On Thu, Feb 18, 2016 at 4:01 PM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 18.02.2016 um 20:36 schrieb Trent Nadeau via swift-evolution < > swift-evolution@swift.org>:

I would prefer a label on the first parameter, since you're not finding
the NSButton type but instead elements having the type of NSButton.

subviews.find(havingType: NSButton.self, matching: { $0.state == NSOnState
})

To comply with the guidelines I would expect a phrase like

subviews.findElement(havingType: NSButton.self, matching: { $0.state
== NSOnState })
subviews.find(instanceOf: NSButton.self, matching: { $0.state
== NSOnState })

-Thorsten

On Thu, Feb 18, 2016 at 4:37 AM, Marco Masser via swift-evolution < > swift-evolution@swift.org> wrote:

On 2016-02-18, at 00:46, Kevin Ballard via swift-evolution < >> swift-evolution@swift.org> wrote:

Alternatively you can write

    subviews.lazy.flatMap({ $0 as? NSButton }).find({ $0.state ==
NSOnState })

Just to reiterate my point: I very much prefer the version without any
casts. I just think this is much clearer and doesn’t put the burden of
thinking about accidental memory and speed overhead (when forgetting the
“lazy”) on the caller every time:

subviews.find(NSButton.self, matching: { $0.state == NSOnState })

Also, there’s the goal of Swift being easy to learn. Which line do you
think is easier to explain to newcomers?

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

--
Trent Nadeau

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

--
Trent Nadeau

Thanks! The second version is my favorite, too.

-Thorsten

···

Am 18.02.2016 um 22:02 schrieb Trent Nadeau <tanadeau@gmail.com>:

Indeed. I quite like the second version.

On Thu, Feb 18, 2016 at 4:01 PM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 18.02.2016 um 20:36 schrieb Trent Nadeau via swift-evolution <swift-evolution@swift.org>:

I would prefer a label on the first parameter, since you're not finding the NSButton type but instead elements having the type of NSButton.

subviews.find(havingType: NSButton.self, matching: { $0.state == NSOnState })

To comply with the guidelines I would expect a phrase like

subviews.findElement(havingType: NSButton.self, matching: { $0.state == NSOnState })
subviews.find(instanceOf: NSButton.self, matching: { $0.state == NSOnState })

-Thorsten

On Thu, Feb 18, 2016 at 4:37 AM, Marco Masser via swift-evolution <swift-evolution@swift.org> wrote:

On 2016-02-18, at 00:46, Kevin Ballard via swift-evolution <swift-evolution@swift.org> wrote:

Alternatively you can write

    subviews.lazy.flatMap({ $0 as? NSButton }).find({ $0.state == NSOnState })

Just to reiterate my point: I very much prefer the version without any casts. I just think this is much clearer and doesn’t put the burden of thinking about accidental memory and speed overhead (when forgetting the “lazy”) on the caller every time:

subviews.find(NSButton.self, matching: { $0.state == NSOnState })

Also, there’s the goal of Swift being easy to learn. Which line do you think is easier to explain to newcomers?

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

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

--
Trent Nadeau

Yep, you are right. That looks better.

···

On 2016-02-18, at 22:02, Trent Nadeau <tanadeau@gmail.com> wrote:

Indeed. I quite like the second version.

On Thu, Feb 18, 2016 at 4:01 PM, Thorsten Seitz <tseitz42@icloud.com <mailto:tseitz42@icloud.com>> wrote:

Am 18.02.2016 um 20:36 schrieb Trent Nadeau via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

I would prefer a label on the first parameter, since you're not finding the NSButton type but instead elements having the type of NSButton.

subviews.find(havingType: NSButton.self, matching: { $0.state == NSOnState })

To comply with the guidelines I would expect a phrase like

subviews.findElement(havingType: NSButton.self, matching: { $0.state == NSOnState })
subviews.find(instanceOf: NSButton.self, matching: { $0.state == NSOnState })

-Thorsten

If I’m not mistaken, this works OK as long as you only want to find something of a specific type. Maybe I’m missing something here, but to add some kind of predicate (e.g. checking for bitsPerPixel == 8), this would lead to code like this:

var bitmap: NSBitmapImageRep? = representations.find {
    if let bitmap = $0 as? NSBitmapImageRep where bitmap.bitsPerPixel == 8 {
        return bitmap
    }
    return nil
} ?? makeNormalizedBitmapRep()

… whereas my original version would look like this:

var bitmap = representations.find(NSBitmapImageRep.self) { $0.bitsPerPixel == 8 } ?? makeNormalizedBitmapRep()

The point of my proposed method is to filter for a *subtype* of Generator.Element and apply a given predicate only to those that match that subtype, then return the an instance of that subtype or nil.

Again, maybe I’m missing something here?

···

On 2016-02-18, at 23:13, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

A funny thing just happened—I was writing some Swift, needed something like `find`, remembered this thread, copied it in, andt ehn realized I wanted to find-and-cast at the same time. Here's what I ended up doing:

extension SequenceType {
   func find<U>(@noescape finder: Generator.Element throws -> U?) rethrows -> U? {
       for elem in self {
           if let returnValue = try finder(elem) {
               return returnValue
           }
       }
       return nil
   }

   func find(@noescape predicate: Generator.Element throws -> Bool) rethrows -> Generator.Element? {
       return try find { try predicate($0) ? $0 : nil }
   }
}

Then the code that used it ended up being:

       var bitmap = representations.find { $0 as? NSBitmapImageRep } ?? makeNormalizedBitmapRep()

Which I think is about as nice as I could've hoped for.