[swift-evolution] Proposal: Add generator functions to the language
Drew Crawford
drew at sealedabstract.com
Fri Dec 11 18:36:30 CST 2015
+1.
I make extensive use of generators in Python, particularly for lazy evaluation, and their absence in Swift is unfortunate.
In a typical ARC-based iOS scenario
for photo in photoGenerator() {
//something with photo
}
is ("should be specified to be") more memory efficient than
for photo in something.buildArrayOfPhotos() {
//something with photo
}
which likely entails an OOM crash and is a common source of noob programmer error.
Reducing the friction of SequenceType in such cases is an improvement entirely orthogonal to coroutines (of which I am much more skeptical).
Drew
> On Dec 11, 2015, at 6:21 PM, David Waite via swift-evolution <swift-evolution at swift.org> 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/1332df2c/attachment.html>
More information about the swift-evolution
mailing list