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

Andrew Bennett cacoyi at gmail.com
Sat Dec 12 06:31:13 CST 2015


I like this idea, as long as it is kept small in scope, only the
introduction of a yield implemented as something conforming to SequenceType.

You can get fairly concise syntax already with anySequence and AnyGenerator:

func fibonacci() -> AnySequence<Int> {

    return AnySequence<Int> { () -> AnyGenerator<Int> in

        var (i, j) = (0, 1)

        return anyGenerator {

            (i, j) = (j, i + j)

            return i

        }

    }

}


But state management is more involved.

To implement this I guess you'd have to look at each yield statement and
work out what state it can have, something like this:

func test() -> AnySequence<Int> {

    var j = 0

    for i in 1 ... 5 {

        j += i

        yield j

    }

    yield j

    return j+1

}


becomes:


func test() -> AnySequence<Int> {

    return AnySequence<Int> { () -> AnyGenerator<Int> in

        var state: YieldState_test = .Yield0(j: 0, i: 1)

        return anyGenerator { () -> Int? in

            switch state {

            case let .Yield0(j: j, i: i):

                let j_ = i + j, i_ = i+1

                state = (i_ <= 5) ? .Yield0(j: j_, i: i_) : .Yield1(j: j_)

                return j_

            case let .Yield1(j: j):

                state = .Return0(j)

                return j

            case let .Return0(r):

                state = .Complete

                return r+1

            case .Complete:

                return nil

            }

        }

    }

}



On Sat, Dec 12, 2015 at 10:20 PM, T.J. Usiyan via swift-evolution <
swift-evolution at swift.org> wrote:

> This feature (set) as sketched here by Joe is worthwhile, in my opinion.
> The use of catch fits in and effect neatly captures this class of behaviors.
> +1 for `effect`
> ---
> TJ
>
> On Sat, Dec 12, 2015 at 4:17 AM, Joe Groff via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>>
>> On Dec 11, 2015, at 6:26 PM, Jordan Rose via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> Eh, I was trying to avoid grabbing another keyword, but I guess it's
>> context-sensitive anyway.
>>
>>
>> I've thought about this some. It might not have to be a keyword, if this
>> were a generalized language feature. Anything that interrupts control flow
>> and optionally resumes it later, such as 'throws', 'yields', and
>> potentially also 'async', could be implemented as instances of algebraic
>> effects. As a rough sketch of an idea, you could declare an effect and its
>> operations:
>>
>> effect throws { @noreturn operation throw (ErrorType) -> () }
>> effect yields<T> { operation yield (T) -> () }
>> effect awaits { operation await<T> (Promise<T>) -> T }
>>
>> and 'catch' could be generalized to let you handle any effect operations
>> that might be performed in the body of a block:
>>
>> class Generator<T> {
>> var generator: () yields<T> -> ()
>> func next() -> T? {
>> do {
>>    generator()
>> return nil
>> } catch yield (let x) {
>> generator = currentContinuation
>> return x
>> }
>> }
>> }
>>
>> See Eff (http://www.eff-lang.org) for an example of a language with this
>> already implemented.
>>
>> -Joe
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>
> _______________________________________________
> 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/20151212/e18c1798/attachment.html>


More information about the swift-evolution mailing list