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

Kevin Wooten kdubb at me.com
Fri Dec 11 23:05:04 CST 2015


I really like this form…  

    func countToTen() -> yields Int { yield 1; yield 2 }

It reads well and states clearly what it’s intent is.

Works/reads well with ‘throws’...

    func countToTen() throws -> yields Int {}

And there must be some advantage to claiming two keywords that are nearly identical, ‘yield’ & ‘yields’.

> On Dec 11, 2015, at 8:45 PM, Alex Gordon via swift-evolution <swift-evolution at swift.org> wrote:
> 
> IMO the yields should be literally *in* the return type. The present state of things is
> 
> fn countToTen() -> CountToTenGenerator
> 
> Generator functions are normal functions. What is special about them is that instead of returning a named type such as "CountToTenGenerator", the compiler replaces the return type with an anonymous type conforming to GeneratorType. So conceptually it's the return type that is special, not the function.
> 
> Try either one of these for size
> 
> fn countToTen() -> yields Int {
> fn countToTen() -> yields<Int> {
> 
> - Alex
> 
> On Sat, Dec 12, 2015 at 3:17 AM, Joe Groff via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
>> On Dec 11, 2015, at 6:26 PM, Jordan Rose via swift-evolution <swift-evolution at swift.org <mailto: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 <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 <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 
>  _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <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/9932a68c/attachment.html>


More information about the swift-evolution mailing list