[swift-evolution] [Discussion][Expericment] D-like slicing syntax

Dave Abrahams dabrahams at apple.com
Mon Feb 29 16:22:47 CST 2016


on Sat Feb 27 2016, Daniel Duan <swift-evolution at swift.org> wrote:

> Dave Abrahams via swift-evolution <swift-evolution at ...> writes:
>
>> 
>> 
>> on Sat Feb 20 2016, Daniel Duan <swift-evolution <at> swift.org> wrote:
>> 
>
>> Why not just make
>> 
>>     x[..<$-2]
>> 
>> work?  You can create unary overloads for ..<
>
> Hi Dave, I took another stab at it today. The code is in the following link as
> well as end of this email:
> https://gist.github.com/dduan/fcd33a09fae4640fc83c
>
> This implementation is almost good IMO :)

What's the case that keeps it from actually being good?

> struct Dollar {}
>
> let $ = Dollar()
>
> struct BInt: IntegerLiteralConvertible {
>     let bool: Bool
>     let int: UInt
>     func relativeTo(total: Int) -> Int {
>         return bool ? total - Int(int) : Int(int)
>     }
>     init(_ b: Bool, _ n: UInt) {
>         bool = b
>         int = n
>     }
>     init(integerLiteral value: Int) {
>         bool = false
>         int = UInt(value)
>     }
> }
>
> func -(h: Dollar, d: UInt) -> BInt { return BInt(true, d) }
>
> typealias IncompleteRange = (BInt?, BInt?)
>
> prefix operator ..< {}
> prefix func ..<(end: BInt) -> IncompleteRange {
>     return (nil, end)
> }
>
> postfix operator ..< {}
> postfix func ..<(start: BInt) -> IncompleteRange {
>     return (start, nil)
> }
> prefix operator ... {}
> prefix func ...(end: BInt) -> IncompleteRange {
>     return (nil, BInt(end.bool, end.int+1))
> }
> postfix operator ... {}
> postfix func ...(start: BInt) -> IncompleteRange {
>     return (start, nil)
> }
>
> func ..<(start: BInt, end: BInt) -> IncompleteRange {
>     return (start, end)
> }
>
> func ...(start: BInt, end: BInt) -> IncompleteRange {
>     return (start, BInt(end.bool, end.int+1))
> }
>
> internal func normalize(range: IncompleteRange, total: Int) -> (Int, Int) {
>     var actualStart = range.0 == nil ? 0 : range.0!.relativeTo(total)
>     var actualEnd = range.1 == nil ? total : range.1!.relativeTo(total)
>     actualStart = actualStart < 0 ? total + actualStart : actualStart
>     actualEnd = actualEnd < 0 ? total + actualEnd : actualEnd
>     return (actualStart, actualEnd)
> }
>
> extension CollectionType {
>     subscript(halfRange: IncompleteRange) -> Self.SubSequence {
>         let (safeStart, safeEnd) = normalize(
>             halfRange,
>             total: self.count as! Int
>         )
>         let safeStartIndex = startIndex.advancedBy(
>             safeStart as! Self.Index.Distance)
>         let safeEndIndex = startIndex.advancedBy(
>             safeEnd as! Self.Index.Distance)
>         return self[safeStartIndex..<safeEndIndex]
>     }
> }
>
> let s = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>
> // all of these expression results in [6, 7, 8, 9]
> s[6...]
> s[($-4)...]
> s[6..<s.count]
> s[6..<$-0]
> s[$-4...9]
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-- 
-Dave



More information about the swift-evolution mailing list