pattern matching on variable-sized data type

Hello,

I would like to suggest an additive evolution to Swift that might be in scope of phase 1 of Swift 4 (because it might have an impact on the ABI).

The idea is to extend the pattern matching abilities of Swift to enable a recursive programming style that’s very common in languages such as Lisp, ML, or Prolog on a collection that is processed as a list. By analogy to ML, Swift could do that on tuples, or on arrays, or on any similar, perhaps new, data type. This would allow the following for example:

func listOfDifferenceOfListElements (list: List<Int>) -> Int {
    
    switch list {
    case 〘〙: {
        return 〘〙
        }
    case 〘 let a 〙: {
        return 〘 a 〙
        }
    case 〘 let a, let b ⫸ let tail 〙: {
        return 〘 a-b 〙 ⋙ sumDifferenceOfListElements(tail)
        }
    }
}

Where I deliberately used unusual Unicode characters to denote syntax that would need to be invented:

- 〘〙 to denote the list-like data structure. It would be old style parenthesis if we wanted that to be Swift’s tuple, or the usual bracket if it was arrays
- ⫸ to pattern-match the tail of the list, i.e. the list composed of any and all elements following whatever has been pattern-matched so far
- ⋙ to denote a list append operator.

If we wanted the list data-type to be tuples, this would require the ability to build longer tuples from existing ones, i.e. build (a, b, c) from a and (b, c), or from (a) and (b, c) (appending tuples). Array seems more suitable, however.

So this post is to assess the interest in such a feature. Also note that while I have tried to have an occasional look at this mailing list in the past, due to its overwhelming volume, I may very well have missed a similar discussion in the past. In that case, I would appreciate a pointer.

As someone who developed Lisp and Prolog software professionally in a rather distant past, with an ever renewed sense of wonder, I would very much love to be able to use that programming style again when it makes sense.

If there is interest, I would be willing to write up an evolution proposal.

Jean-Denis Muys

This is a purely additive change, I can’t imagine how it would impact the ABI of existing code.

-Chris

···

On Sep 6, 2016, at 7:48 AM, Jean-Denis Muys via swift-evolution <swift-evolution@swift.org> wrote:

Hello,

I would like to suggest an additive evolution to Swift that might be in scope of phase 1 of Swift 4 (because it might have an impact on the ABI).

The recursive call should obviously read

return 〘 a-b 〙 ⋙ listOfDifferenceOfListElements(tail)

Jean-Denis

···

On 06 Sep 2016, at 16:48, Jean-Denis Muys <jdmuys@gmail.com> wrote:

Hello,

I would like to suggest an additive evolution to Swift that might be in scope of phase 1 of Swift 4 (because it might have an impact on the ABI).

The idea is to extend the pattern matching abilities of Swift to enable a recursive programming style that’s very common in languages such as Lisp, ML, or Prolog on a collection that is processed as a list. By analogy to ML, Swift could do that on tuples, or on arrays, or on any similar, perhaps new, data type. This would allow the following for example:

func listOfDifferenceOfListElements (list: List<Int>) -> Int {
    
    switch list {
    case 〘〙: {
        return 〘〙
        }
    case 〘 let a 〙: {
        return 〘 a 〙
        }
    case 〘 let a, let b ⫸ let tail 〙: {
        return 〘 a-b 〙 ⋙ sumDifferenceOfListElements(tail)
        }
    }
}

Where I deliberately used unusual Unicode characters to denote syntax that would need to be invented:

- 〘〙 to denote the list-like data structure. It would be old style parenthesis if we wanted that to be Swift’s tuple, or the usual bracket if it was arrays
- ⫸ to pattern-match the tail of the list, i.e. the list composed of any and all elements following whatever has been pattern-matched so far
- ⋙ to denote a list append operator.

If we wanted the list data-type to be tuples, this would require the ability to build longer tuples from existing ones, i.e. build (a, b, c) from a and (b, c), or from (a) and (b, c) (appending tuples). Array seems more suitable, however.

So this post is to assess the interest in such a feature. Also note that while I have tried to have an occasional look at this mailing list in the past, due to its overwhelming volume, I may very well have missed a similar discussion in the past. In that case, I would appreciate a pointer.

As someone who developed Lisp and Prolog software professionally in a rather distant past, with an ever renewed sense of wonder, I would very much love to be able to use that programming style again when it makes sense.

If there is interest, I would be willing to write up an evolution proposal.

Jean-Denis Muys

You can process lists using pattern matching today:

enum List<T> {
    case Nil
    indirect case Cons(T, List<T>)
}
let list: List<Int> = .Cons(2, .Cons(3, .Nil))
switch list {
    case .Nil: ...
    case .Cons(let x, .Nil): ...
    case .Cons(let x, .Cons(let y, .Nil)): ...
    default: handleLongList(list)
}

The thing is, such lists are not idiomatic in Swift. Pattern matching on
Array also kind-of works:

let array: Array<Int> = ...
switch array.first {
    case .some(let first):
        processHead(first)
        processTail(array.dropFirst())
    case .none:
        handleNil()
}

Again, it’s not the most idiomatic way to do this in Swift. Also, there is
no guaranteed tail-call optimization.

Hello,

I would like to suggest an additive evolution to Swift that might be in
scope of phase 1 of Swift 4 (because it might have an impact on the ABI).

The idea is to extend the pattern matching abilities of Swift to enable a
recursive programming style that’s very common in languages such as Lisp,
ML, or Prolog on a collection that is processed as a list. By analogy to
ML, Swift could do that on tuples, or on arrays, or on any similar, perhaps
new, data type. This would allow the following for example:

···

2016-09-06 17:48 GMT+03:00 Jean-Denis Muys via swift-evolution < swift-evolution@swift.org>: