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

Kevin Ballard kevin at sb.org
Sat Dec 12 00:48:56 CST 2015


I'd love to have first-class support for generators like this, but it's
a *lot* of work. It's a lot easier to do this sort of thing in a
scripting language like Python than it is to do in a language like
Swift, because it requires reifying the stack into a data structure that
can be passed around. And I suspect there's a lot of non-trivial
questions that have to get answered before you can even propose an
implementation for this.

For context, this sort of thing is something that people have been
talking about doing in Rust for quite a while, and it keeps getting
punted because of the amount of work and the unanswered questions about
how it would actually be implemented.

So I'll give this a general +1, but I think it should also be deferred
until after Swift 3 at the earliest.

-Kevin

On Fri, Dec 11, 2015, at 04:21 PM, David Waite via swift-evolution wrote:
> 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)
>
> _________________________________________________
> swift-evolution mailing list swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151211/d7930a2d/attachment.html>


More information about the swift-evolution mailing list