generic function called recursively not compiling


(Ray Fix) #1

I filed rdar://27700622 <rdar://27700622> and attached a playground. Any workaround magic I can do here?

func quickSort<Element: Comparable>(_ input: [Element]) -> [Element] {
    if input.count < 2 {
        return input
    }
    let pivot = input.first!
    let left = input.dropFirst().filter { $0 <= pivot }
    let right = input.dropFirst().filter { $0 > pivot }

    // Does not compile with (Swift 3pre) Xcode 8 b1,2,3,4
    // Does compile with (Swift 2.2) Xcode 7.3
    return quickSort(left) + [pivot] + quickSort(right)
}

quickSort([3,5,1,2])

Error:
//Playground execution failed: error: quicksort.playground:11:22: error: cannot convert value of type '[Element]' to expected argument type '[_]'
//return quickSort(left) + [pivot] + quickSort(right)
// ^~~~


(Kevin Nattinger) #2

Looks like a bug in the type inference system to me, but I’ll let someone with a better knowledge of the compiler confirm. Meanwhile, you can work around by explicitly casting any of the pieces of the return statement to `[Element]` or using a temporary for one or more of them.

    let middle = [pivot]
    return quickSort(left) + middle + quickSort(right)

    return quickSort(left) as [Element] + [pivot] + quickSort(right)

    return quickSort(left) + ([pivot] as [Element]) + quickSort(right)

···

On Aug 4, 2016, at 9:02 AM, Ray Fix via swift-users <swift-users@swift.org> wrote:

I filed rdar://27700622 <rdar://27700622> and attached a playground. Any workaround magic I can do here?

func quickSort<Element: Comparable>(_ input: [Element]) -> [Element] {
    if input.count < 2 {
        return input
    }
    let pivot = input.first!
    let left = input.dropFirst().filter { $0 <= pivot }
    let right = input.dropFirst().filter { $0 > pivot }

    // Does not compile with (Swift 3pre) Xcode 8 b1,2,3,4
    // Does compile with (Swift 2.2) Xcode 7.3
    return quickSort(left) + [pivot] + quickSort(right)
}

quickSort([3,5,1,2])

Error:
//Playground execution failed: error: quicksort.playground:11:22: error: cannot convert value of type '[Element]' to expected argument type '[_]'
//return quickSort(left) + [pivot] + quickSort(right)
// ^~~~

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


(Dave Abrahams) #3

Hi Ray,

I don't know why, but the type checker is obviously falling over here.
This works around it:

  return quickSort(left) as [Element] + [pivot] + quickSort(right)
                         ^^^^^^^^^^^^

HTH,

···

on Thu Aug 04 2016, Ray Fix <swift-users-AT-swift.org> wrote:

I filed rdar://27700622 <rdar://27700622> and attached a playground.
Any workaround magic I can do here?

func quickSort<Element: Comparable>(_ input: [Element]) -> [Element] {
    if input.count < 2 {
        return input
    }
    let pivot = input.first!
    let left = input.dropFirst().filter { $0 <= pivot }
    let right = input.dropFirst().filter { $0 > pivot }

    // Does not compile with (Swift 3pre) Xcode 8 b1,2,3,4
    // Does compile with (Swift 2.2) Xcode 7.3
    return quickSort(left) + [pivot] + quickSort(right)
}

quickSort([3,5,1,2])

Error:
//Playground execution failed: error: quicksort.playground:11:22: error: cannot convert value of type '[Element]' to expected argument type '[_]'
//return quickSort(left) + [pivot] + quickSort(right)
// ^~~~

--
-Dave


(Adriano Ferreira) #4

Hey Ray,

Feel free to take a look at the swift-3 branch of this repo <https://github.com/adrfer/Sort/tree/swift-3>, too. There are several quick sort implementations there, from classic to Swift-y!

Cheers,

— A

···

On Aug 4, 2016, at 12:02 PM, Ray Fix via swift-users <swift-users@swift.org> wrote:

I filed rdar://27700622 <rdar://27700622> and attached a playground. Any workaround magic I can do here?

func quickSort<Element: Comparable>(_ input: [Element]) -> [Element] {
    if input.count < 2 {
        return input
    }
    let pivot = input.first!
    let left = input.dropFirst().filter { $0 <= pivot }
    let right = input.dropFirst().filter { $0 > pivot }

    // Does not compile with (Swift 3pre) Xcode 8 b1,2,3,4
    // Does compile with (Swift 2.2) Xcode 7.3
    return quickSort(left) + [pivot] + quickSort(right)
}

quickSort([3,5,1,2])

Error:
//Playground execution failed: error: quicksort.playground:11:22: error: cannot convert value of type '[Element]' to expected argument type '[_]'
//return quickSort(left) + [pivot] + quickSort(right)
// ^~~~

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