How do you beautify guard-else conditions?

This looks horrible to me.

Screen Shot 2016-08-23 at 11.03.47 AM

This looks wrong too:

Screen Shot 2016-08-23 at 11.06.56 AM

And so does this:

Screen Shot 2016-08-23 at 11.07.50 AM

And this:

Screen Shot 2016-08-23 at 11.08.25 AM

And while we’re at it  these two too, both of which require hand-indenting while fighting Xcode:

Screen Shot 2016-08-23 at 11.17.53 AM

Screen Shot 2016-08-23 at 11.17.59 AM

This is among the least bad:

Screen Shot 2016-08-23 at 11.08.59 AM

What would you do to fix it?

Patrick Perini suggests:

Greg Titus thought using a simpler clause and a Never-returning function might be better. Here’s some code where I incorporated his feedback:

Swift Nostalgia: Letting go doesn’t mean saying goodbye

Just leaving this here.

I’ve filed a bug report about having to do non-generic implementations, which makes this a lot uglier than it needs to be. Jordan Rose wrote in response to my bug,

I’m pretty sure this is an overload ordering question, and I’m not convinced the compiler is wrong. If something is a more specific overload and marked unavailable, silently dropping back to the less-specific overload might be counterintuitive. (It also means the behavior of existing code could change silently if something is marked unavailable between releases.)

In any case, if you have any fixes or tweaks, as always please let me know and I’ll update.

Review: Man, I hate Cursive by Jim Benton

Screen Shot 2016-08-21 at 7scaled.58.09 PM

If you like good, stupid, subversive humor (and who among us does not?), consider pre-ordering Jim Benton‘s “Man, I Hate Cursive”.

Due out this October, this cartoon collection for “People and Advanced Bears” is silly, witty, and laugh-out-loud fun. It offers a collection of Benton’s more popular strips from Reddit, “shining a light on talking animals, relationships, fart jokes, and death” according to the book’s promo copy.

I liked it a lot. Admittedly, some of the humor leans off-color: it’s the kind of book you gift a friend, a fellow programmer, a geek, but not maybe your mom unless your mom is a friendly programmer geek, in which case, she’ll enjoy the laughs.

You’ll probably like it too, in which case, it’s excellent for leaving around on coffee tables if you’re a little uptight or in bathrooms, where its humor might be more appreciated during those deeply  philosophical times when you forget your iPad and don’t subscribe to the Ikea catalog.

Screen Shot 2016-08-21 at 7.57.05 PM

At just under a hundred pages, the book ended way too soon for me.  “Man, I Hate Cursive” is available for pre-order on Amazon ($11.07 paperback, $9.99) and will be published on October 18, 2016.

NetGalley provided me with a free copy of the book for this review.

Kid-fu: Pay for play

Screen Shot 2016-08-19 at 7.24.19 PMHow do you get your kid to try on all his shirts and pants before school starts? So you can sort them into trash, donate, wear, and “for playtime use only”? Answer: Playgrounds. Thank you playground team!

We used the “deal or no deal” rule. Two spins. You can “stick” or you can re-try, but no peeking at the next roll. Payment for each garment  after trying it on, taking it off and folding it. Coins placed into a cauldron (thank you Harry Potter camp) to be counted after we’re done. Any stained items treated with Oxyclean and thrown into the hamper.

For less than a couple of dollars, we got through his entire wardrobe with no complaints except “Don’t I have anything else that needs trying on?”

Source code follows:

Canonical Hex

So today, in the context of assembling color components, I decided that a hex value should always be padded to 2, 4, 8, 16, 32, or 64 characters when building out chunks.

Under this system, the number 256 should be “0100” and not “100”, representing the smallest standard memory footprint that will store the value. This allows chunks to be losslessly assembled together because there’s a consistent width for each component. If you need to use a larger padding value, you can re-pad to a larger minimum width.

While RGB colors come in 6’s, those are (in my opinion) three channels of 2-digit hex numbers, not a six-digit hex number.

Interesting things about this implementation:

  • You have to use Swift.max because Int has its own max symbol.
  • I was initially convinced to drop strtol() in favor of the built-in radix initializer, but this does do away with leading 0x support, which you have to strip yourself. (I did not include stripping in this implementation.) In my SwiftString repo, I’ve reverted to the old-style conversions.
  • Greg T’s version with fls instead of my convoluted log2 stuff is vastly improved, so I’ve substituted it in-place here.
  • My goal is to produce full-width number-chunks that can be assembled to represent components, whether for storing information, for channels, or for clarity in reading. An RGB group of (0xFF, 0x7, 0xFF) must be “FF07FF”, not “FF7FF”. So yes, there will be leading zeroes. If you want to interpret  output as numbers, use a canonical prefix (0x).
extension String {
    /// Left pads string to at least `minWidth` characters wide
    public func leftPad(_ character: Character, toWidth minWidth: Int) -> String {
        guard minWidth > characters.count else { return self }
        return String(repeating: String(character), 
            count: minWidth - characters.count) + self
    }
    
    /// Returns String's hex value
    /// - note: Non-compliant strings default to 0
    /// - note: An earlier version used strtol(), 
    ///   which accepts leading "0x". This does not.
    public var hexValue : Int { return Int(self, radix: 16) ?? 0 }
}

public extension Int {
    /// Returns Int's representation as hex string using 0-padding
    /// to represent the smallest standard memory footprint that can
    /// store the value.
    public var hexString : String {
        let unpaddedHex = String(self, radix:16, uppercase: true)
        let stringCharCount = unpaddedHex.characters.count
        // thanks, Greg Titus
        let desiredPadding = 1 << Swift.max(fls(Int32(stringCharCount - 1)), 1) 
        return unpaddedHex.leftPad("0", toWidth: Int(desiredPadding))
    }}
}

As always, corrections, improvements, suggestions welcome.

When did Ikea ditch the sunshine, rainbows, and unicorns?

The new Ikea catalog arrived yesterday. Is it me or have they turned over their design to some crazed Swedish goth intern? My new catalog feels more Hitchcock and “Vogue Editorial” than “Affordable purchases for people who wish they could fix their out-of-control lives.”

Ikea’s gone from cute girls in a colorful apartment (top, 2015) to psychotic butcher knives that think they’re actually vegetables (check out that shadow) and this recurring weird backdrop thing, which makes me think they couldn’t afford an editor to crop the photos properly (bottom, 2016).IMG_1527

Suddenly, they’ve transitioned from simple product images inspiring you to simplify and organize  your life to a kind of nightmare clutter scenario where all reason has fled and you apparently must buy every product available from the company and store them in the open without drawers, cupboard doors, or any break in sanity.

IMG_1521

Look at that poor woman standing at that kitchen island. Her entire body communicates the tenseness from barely having a spare inch of counter space, banging her knees against all the junk on the two shelves, the shame of putting your dishes out for public viewing. Inside, she’s screaming “I will never get my life under control and it’s all IKEA’s fault! For just $499!”

(By the way, I love the LED light at the middle of the right page of the 2015 catalog. Mine is black, not red, and it’s perfect between my two computer monitors. Folds up out of the way when not in use.)

IMG_1526

Apparently 2016 is the year of dark spaces, drawn blinds, and Carmen cosplay. You can pretend to die of consumption in the gloomy shadows of your living room, while dressed in red and practicing ballroom in the  (perhaps) 2 square meters of space between couches.

And can you think of anything scarier than your sofa actually being your home. Last year, a beautiful, open plan living room, with a family happily getting work done on the laptop and reading to a kid. They seem happy, their plants seem happy, the lightness and brightness no doubt makes them feel free and open and relaxed. Compare that to this year.IMG_1525

No, Ikea, a sofa is not the home. And who are all those strange people who wandered into this poor woman’s life just to stare at and harass her?

Here’s Elsa. Elsa thought she’d have a lovely relaxing time, putting up her feet before picking up the kids and stopping by an organic locally sourced market for take out to eat while perched on a variety of ottomans and sleeper couches.

Who would ever have expected an entire gang from Twitter to take up residence on the other side of her monster sofa, laughing at her, mocking her, and critiquing her lounging style. That gang of four sure think Elsa is a hoot. And all at the same time, creepy Helmut from down the road just stares at Elsa with unrequited longing. I think perhaps he’s humming ska songs from the 1980s to her.

Poor Elsa. This is what comes of living in the middle of a photographic studio, without doors to keep out strangers, no storage for clothing, a ragtag group of floating sofas for the young ones to sleep upon, and three mysterious remote controls to remind her a time when she had a real house to call home.

Oh Ikea. It’s time to say goodbye to 2015, with its misty bright hopes for a world of knotty pine. 2016 has arrived with its dark bleak dystopian furniture and a bookshelf that looks like an insurance liability court case ready to happen.

IMG_1523

(As a side note, I had no idea that sleeper sofas crept out of their homes while we were at work to embrace that secret 24-hour life. It must get crowded at the bowling alley and at the local microbrewery when affordable furniture sits around, drinking lager, and sharing the stories you thought were kept secret.)

Being overly clever with dates

To find out the distance, say in days, between two dates, call a calendar’s dateComponents(_:, from: , to:) method and pass it the unit you want to use. This call returns a DateComponents instance. You can then find out how many days fall between the two by looking at the returned instance’s.day property.

But what if you want to write a more general method that returns the distance for pretty much any unit you throw at it, whether it be days, minutes, seconds, or years?

Either you can write a really complex switch statement or you can build an extension for DateComponents that allows you to subscript using any Calendar.Component. (Essentially performing the exact same switch statement but as a built-in feature.) And that is, exactly what I did today.

Here are my distance functions, which use subscripting to access the component information after pulling the distance from the shared calendar:

static public func distance(_ date1: Date, 
    to date2: Date, 
    component: Calendar.Component) -> Int {
    return Date.sharedCalendar
        .dateComponents([component], from: date1, to: date2)[component] ?? 0
}

public func distance(to date: Date, 
    component: Calendar.Component) -> Int {
    return Date.sharedCalendar
        .dateComponents([component], from: self, to: date)[component] ?? 0
}

The subscripting itself, along with a full refresh of my NSDate (well, Date now) utilities can be found at my github repo. This has been one of my more popular (and personally neglected) repositories that dates back almost a decade and I’m happy to say I’ve cleaned it up quite a bit while updating it to Swift.

I’m using a much better way to calculate “same” (for example, same date or same week) by creating a canonical form from the dates and then comparing the canonical versions. For dates, that’s midnight at the start of the day. For weeks, it’s midnight at the start of the week. (update: Sebastian Celis points out the existence of compare(_ date1: Date, to date2: Date, toGranularity component: Component), which is part of swift-corelibs-foundation)

I’ve added in quite a lot of formatter and string options, and doing this in Swift is a pure delight. (It’s a pity playgrounds don’t let you code using gyb-nastics. There’s a lot of redundancy in my code.)

All the date offsets are now much cleaner, and completely migrated to date components (as they should have been years ago).

As always, if you want any requests or changes, ping me now while I’m paying attention to this because my primary interest is migration to Swift and not dates per se. And thanks in advance for any feedback.

More fun with sequences!

I want to share a little conversation from Swift-Users. KS Sreeram wrote:

I’m trying to initialize a byte-array efficiently with minimal copying with the following steps:

1. Create an empty byte array.
2. Reserve sufficient capacity in the array.
3. Use mutable pointers into the array to fill in the data.
4. The actual size that was filled is known only after it is filled in.
5. I would like to set the size of the array to the actual size.

I couldn’t find any methods for doing the last step. Is there a way to do this?

Dave Abrahams’ response:

Create a Sequence that represents the elements you’re going to append, e.g.:

 var a = [1, 2]
 a.reserve(256)
 a += sequence(first: 3, next: {$0 < 1000 ? ($0 + 3) * 2 : nil})

There are lots of ways to make Sequences, but the overloaded sequence() functions are probably the easiest.

Sadly:

Dear Erica: Taking the NS off

Dear Erica, Where can you find a list of all the Foundation classes losing the NS prefix? Will any UI ones do the same? — Seivan

The whole “NS prefix stripping” initiative is part of Tony Parker and Philippe Hausler’s SE-0086, which you’ll find by following the link to the proposal. It contains a list of the classes affected by SE-0086’s adoption.

The reasoning behind this proposal goes like this: Swift has a compelling interest in creating a core library suite to support common Swift design patterns. This interest in unifying a core library extends to platforms that lack historic ties to NeXTStep.

To provide this universal support, the Swift Programming Language requires the creation of a family of libraries that will ship with the compiler. This core functionality extends beyond the existing Swift Standard Library and is tentatively called the Swift Core Libraries.

Key elements that will be developed for the library include dispatch, internationalization/localization, and unit testing. As these libraries are both fundamental and native to the Swift language, their naming style needs to be “Swifty”. This renaming differentiates them from Cocoa Foundation:

In addition to adopting the guidelines for method names, the names of the fundamental types should follow the spirit of the guidelines too. The type names should be clear, concise, and omit needless words or prefixes. In combination with adopting Swift semantics for many of these types (SE-0069), and continued improvement to the implementations, this will make core library API feel like it belongs to the Swift language instead of like a foreign invader.

To answer your question, classes tied specifically to Objective-C and the Objective-C runtime, as well as those that are Apple platform specific (AppKit and, as you asked, UIKit) will retain their NS (or UI) prefix. Those that are more universally applicable will slowly lose that prefix through a series of upgrades and redesigns, especially as the tension between Swift value type and Foundation reference type implementations are better explored.

SE-0086 has been through a significant revision. Numerous classes  included in the original write-up were later removed:

Screen Shot 2016-08-09 at 8.50.31 AM

The authors wrote,

 We considered simply dropping the prefix from all types. However, this would cause quite a few conflicts with standard library types. Also, although Foundation’s framework boundary is an easy place to programmatically draw the line for the drop-prefix behavior, the reality is that Foundation has API that feels like it belongs to higher level frameworks as well. We believe this approach better identifies the best candidates for dropping the prefix.

Because of this revision, fairly universal items like attributed strings, time zones, tasks, and sort descriptors did not make it through the first round of renames but may be considered again as the Swift language evolves.

SE-0086 and its heirs will not be taking up the case of renaming the core UI elements that are so tied to Apple’s platforms and their look and feel. That said, I would love to see a push to expand the Swift language to include more constructed literals, and here is my reasoning why.

A constructed literal expresses concepts that are inherently cross-platform. Swift’s constructed literal set currently includes colors, paths, and images. Colors and images fall under the platform-specific umbrella that excludes them from being part of the core library system.

Using a constructed literal allows these platform-tied elements to participate in the core Swift language because implementation details are left to the destination platform. You don’t have to work whether an item is a UIColor, an NSColor, an SKColor, or a CIColor because a color literal builds on an underlying commonality that colors can be expressed using RGBA notation.

Extending the constructed literal set from colors, paths, and images to  views, fonts, and more provides an interesting way to move forward. Like colors and images, these platform types are essentially universal concepts. They could defer of implementation details to destination platforms, allowing them to be created in core Swift.

While I’d love to see this discussed, it’s pretty clear that this kind of additive proposal will probably be deferred to at least Swift 5, as Swift 4 focuses on a much more narrow set of goals.