This only works with the example exactly as-is, I think a fairer re-write would 
be something like the following:

func toCSV(values:[CustomStringConvertible]) -> String {
    var gen = values.generate()

    var result = gen.next()?.description ?? ""
    while let value = gen.next() { result += ", \(value)" }
    return result
}

toCSV([1, 2, 3, 4, 5])

For brevity I opted to use nil-coalescing and a default value to handle the 
first (potentially nil) element cleanly.

I’m undecided about whether I want the feature or not; as shown the example can 
actually be handled very neatly already, so it doesn’t really highlight a need 
for the feature. One thing I like about it though is the ability to possibly 
eliminate the need for a generator and use a for in loop instead, like so:

func toCSV(values:[CustomStringConvertible]) -> String {
    var result = ""
    for value in values {
        once { result += "\(value)"; continue }
        result += ", \(value)"
    }
    return result
}

But this isn’t really much of a saving. I can’t think of a real-world example 
offhand that can better demonstrate a use for this; ideally you’d want to use 
several once {} blocks, or do something in the loop that requires other 
statements in the loop, i.e- you use the once to avoid duplicating statements 
in the loop while processing the first element.

> On 17 May 2016, at 07:13, Robert Widmann via swift-evolution 
> <[email protected]> wrote:
> 
> Not to doubt the usefulness of this proposal in general, but your example is 
> subsumed by simply declaring 
> 
> var result = "\(gen.next()!)"
> 
> and proceeding with the rest of the example sans `once`.  I think you'll also 
> have to address how this is any different from dispatch_once or a DSL over 
> the same.
> 
> Cheers,
> 
> ~Robert Widmann
> 
> 2016/05/17 0:03、Nicholas Maccharoli via swift-evolution 
> <[email protected] <mailto:[email protected]>> のメッセージ:
> 
>> ​Hello Swift Evolution,
>> 
>> Its not uncommon to have to do a piece of work only once or on the first 
>> iteration of 
>> a loop.
>> Take for example producing a comma separated string from an Array:
>> 
>>     var result = ""
>> 
>>     let values = [1, 2, 3, 4, 5]
>> 
>>     var gen = values.generate()
>> 
>> 
>> 
>>     if let first = gen.next() {
>> 
>>         result += "\(first)"
>> 
>>         while let value = gen.next() {
>> 
>> 
>>             result += ", "
>> 
>>             result += "\(value)"
>> 
>>         }
>> 
>>     }
>> 
>> 
>> 
>> Since on the first iteration we want to skip putting a comma in front we use 
>> an `if let` to grab the first element and then embed a `while let` inside 
>> the `if let` to handle the rest.
>> 
>> 
>> 
>> Another way to do this could be using a bool to keep track of the first 
>> iteration:
>> 
>> 
>> 
>>     var first = true
>> 
>>     while let value = gen.next() {
>> 
>>         if first {
>> 
>>             result += "\(value)"
>> 
>>             first = false
>> 
>>             continue
>> 
>>         } else {
>> 
>>             result += ", "
>> 
>>             result += "\(value)"
>> 
>>         }
>> 
>> 
>>     }
>> 
>> 
>> 
>> These approaches work, but I think there may be a way to do this with less 
>> noise.
>> 
>> If there was a keyword to execute a block of code only on the first 
>> iteration of a loop I think that would make code like this more concise.
>> 
>> If there was a keyword like `once` then the same thing could be achieved 
>> with something like:
>> 
>> 
>> 
>>     while let value = gen.next() {
>> 
>>         once {
>> 
>>             result += "\(value)"
>> 
>>             continue
>> 
>>         }
>> 
>>         result += ", "
>> 
>>         result += "\(value)"
>> 
>> 
>>     }
>> 
>> 
>> 
>> How does it sound?
>> 
>> 
>> 
>> - Nick
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to