Swift: Fun with Ranges

Screen Shot 2015-01-22 at 8.47.26 AM

Update: Easy fix from Joachim and Jacob, proving that my brain is fried. Joachim notes: ” Range and Interval have been separated into separate classes during the beta. … Creates either depending on context.”

I’ve been playing recently with custom operators. The operator grammar in the Swift Programming Language is a bit obtuse as it lists ranges of unicode characters instead of just showing you a table of what the legal ones are. (There are a lot.) So I hopped into a playground hoping to iterate through them to see if any nice/intriguing/helpful characters popped up. What followed was an interesting exploration of arrays of ranges.

I started by creating a basic list of items I wanted to look at, using the list of “operator-head”-compatible hex values.

var ranges : [Range<Int>] = [
    0xA1...0xA7,
    0xA9...0xA9,
    0xAB...0xAB,
    0xAC...0xAC,
    0xB0...0xB1,
    0xB6...0xB6,
    0xBB...0xBB,
    0xBF...0xBF,
    0xD7...0xD7,
    0xF7...0xF7,
    0x2016...0x2017,
    0x2020...0x2027,
    0x2030...0x203E,
    0x2041...0x2053,
    0x2055...0x205E,
    0x2190...0x23FF,
    0x2500...0x2775,
    0x2794...0x2BFF,
    0x2E00...0x2E7F,
    0x3001...0x3003,
    0x3008...0x3030,
]

But when I attempted to iterate, I ran into errors that ClosedInterval<Int> items do not conform to SequenceType protocols:

for range in ranges {
    for item in range {
        var unicode = String(UnicodeScalar(item))
        println(String(format:"0x%X: \(unicode)", item))
    }
}

Instead, I had to create a new range out of the interval as follows:

for range : ClosedInterval<Int> in ranges {
    for item in range.start...range.end range {
        var unicode = String(UnicodeScalar(item))
        println(String(format:"0x%X: \(unicode)", item))
    }
}

Thanks Joachim and Jacob for fixes.

I think my brain is too dead this morning to really think about this in depth but it seems to me a bit odd that I had to work around this in this way, since a closed interval is intrinsically range-y. (Update: Fixed.)

Most of the operator-ready characters by the way are pretty meh but that’s an entirely different post.

 

One Comment

  • I think Swift’s type inference is falling down here and giving you problems. `…` can return either a Range or a ClosedInterval, and it’s up to the compiler to choose which unless you specify. (Airspeed Velocity has a great series on that topic.)

    Assigning a single value gives you a Range<Int>:

    let range = 0x3008...0x3030

    But in an array literal, the compiler reads it as [ClosedInterval<Int>]:

    let ranges = [ 0x3008...0x3030, ... ]

    As a solution, you can give your ranges array an explicit type:

    let ranges: [Range<Int>] = [ 0x3008...0x3030, ... ]