[swift-evolution] [Draft]: Introducing a striding(by:) method on 3.0 ranges

Dave Abrahams dabrahams at apple.com
Mon Apr 11 17:31:05 CDT 2016


on Mon Apr 11 2016, Michel Fortin <michel.fortin-AT-michelf.ca> wrote:

> Le 11 avr. 2016 à 14:36, Dave Abrahams <dabrahams at apple.com> a écrit :
>
>> 3. The fact that we're migrating C-style for loops to
>>   uses of stride, as noted in https://github.com/apple/swift/pull/2125,
>>   has convinced me that, sadly, we may need an answer that doesn't
>>   involve ranges.  But maybe something like
>> 
>>     for x in loop(from: 0.1, while: { $0 < 10 }, next: { $0 + .2 })
>> 
>>   is sufficient for this purpose.
>
> Please add that. 

Please write a proposal and ideally, submit a patch :-).

Seriously, if this is something you believe in, we could really use the
help.

> First, it would relieve `stride` from some of the pressure of
> excelling at replacing existing C-style for loops. But it would also
> become pretty easy to write custom sequences like this one:
>
> func uniform(start: Double, end: Double, numberOfSteps totalSteps: Int) -> Sequence {
> 	var currentStep = 0
> 	return loop(from: start, while: { _ in
> 		currentStep < totalSteps
> 	}, next: { _ in
> 		currentStep += 1
> 		return start * (Double(totalSteps-currentStep) / Double(totalSteps)) +
> 			end * (Double(currentStep) / Double(totalSteps))
> 	})
> }

Aside from the fact that you can't return Sequence, this seems like a
much better way to do that in Swift 3.0:

func uniform(
  start: Double, end: Double, numberOfSteps totalSteps: Int
) -> LazyMapRandomAccessCollection<CountableRange<Int>, Double> {
  return (0..<totalSteps).lazy.map { 
     start * (Double(totalSteps-$0) / Double(totalSteps)) +
     end * (Double($0) / Double(totalSteps)) 
  }
}

-- 
Dave


More information about the swift-evolution mailing list