[swift-evolution] Proposal: Add generator functions to the language

David Waite david at alkaline-solutions.com
Fri Dec 11 18:21:31 CST 2015


Looking for feedback on crafting a proposal adding generator functions to Swift. I understand this will likely be a very involved proposal at the language level, although I actually don’t know the complexity of the change within the Swift compiler itself.

This would be a function which returns multiple values, which is converted by the compiler to a function returning a SequenceType

A very basic syntax would be to add generator as a modifier to func, and likely involve a new keyword ‘yield’ to differentiate from the flow control behavior of ‘return’.

So for example:

generator func helloGenerator(name:String?) -> String {
    yield “Hello”
    yield name ?? “World”
}

Would have the following expected usage:

for str in helloGenerator(“David") {
   print str
// prints:
//    Hello
//    David
}

And for those unfamiliar to these sorts of simple cases, would have equivalent behavior to the following code:

 45> func helloGenerator(name:String?) -> HelloGenerator { 
 46.   return HelloGenerator(name) 
 47. } 
 48.  
 49. struct HelloGenerator : GeneratorType, SequenceType { 
 50.    var position:Int = 0 
 51.    let name:String? 
 52.  
 53.    private init(_ name:String?) { 
 54.       self.name = name 
 55.    } 
 56.     
 57.    func generator() -> HelloGenerator {
 58.        return self 
 59.    } 
 60.      
 61.    mutating func next() -> String? { 
 62.       switch position { 
 63.       case 0: 
 64.           position = 1 
 65.           return "Hello" 
 66.       case 1: 
 67.           position = 2 
 68.           return name ?? "World" 
 69.       default: 
 70.           return nil 
 71.       } 
 72.    } 
 73. } 

This syntax has at a bare minimum issues with generator closures and for a terse syntax for yielding over another sequence type within a generator function vs. using a loop. (possibly “yield in sequenceName”)

The interaction with the error system might involve disallowing throws from generator functions, or having the Element type be a Result<T> rather than T, as the GeneratorType next() method is not declared as throwing.

This could pair well to make for-in loops more comprehensive, especially if C-style for loops are eliminated.

This would possibly be a first step toward a coroutine-based concurrency system, although I am not proposing that sort of usage or scope here. The goal would be to emit an object compatible with SequenceType

-David Waite (DW)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151211/38903c75/attachment.html>


More information about the swift-evolution mailing list