Archive for November, 2016

Holy Wars: Namespacing Hygiene

sssilver writes: “In my company I find code that’s basically a class with a bunch of static functions in it. When I ask people why not just write the functions directly, they answer that they don’t wanna pollute the namespace. In something like Rust, everything is scoped to the module. What’s the idiomatic way to do this in Swift?

Swift prefers namespacing to freestanding functions and constants. This applies even in module APIs where you gain a basic level of namespacing for free. You want to keep your namespace clean and focused, scoping items to types and protocols of natural interest.

This practice makes Swift a bit more hierarchical than you might be used to. In Swift prefer to:

  • Namespace constants into a type where they naturally fit.
  • Namespace functions into the types and protocols they service, either as static methods or by removing the first argument and re-implementing the function as an instance method.
  • Add subtypes rather than pollute the global namespace with items that are only of interest within a parent type. Subtypes allow the parent and its nested types to reduce complexity when referring to each other, so Shape.Triangle and Shape.Circle see each other as Triangle and Circle.
  • Embed functions that will only be called by a single method client into that method, rather than create a second method that exists only to serve one parent.
  • Move operator implementations into the types they service, so you reduce the number of operators implemented in the global namespace.

Where you might have previously created public constants and functions like these, now prefer to incorporate them into existing or utility types:

public let π = CGFloat(Double.pi) // no
public let τ = π * 2.0 // no

public func halt() { // no
    PlaygroundPage.current.finishExecution()
}

extension CGFloat { 
    /// The pi constant, yes
    public static let (pi, π) = (CGFloat(Double.pi), CGFloat(Double.pi))
 
    /// The tau constant, yes
    public static let (tau, τ) = (2 * pi, 2 * pi)
}

extension PlaygroundPage {
    // This is never going to be beautiful
    public static func halt() {
        current.finishExecution()
    }
}

Embedding globals into types as static members provides clean, Swiftier namespacing, with minimal overhead costs. Where possible, prefer extending an Apple-supplied type (like `CGFloat` and `PlaygroundPage`) over creating new types (like `MathConstants` or `PlaygroundRuntimeSupport`).

At the same time, don’t force constants and functions into classes where they have no natural fit. If you must create a new type to warehouse a namespace, prefer a no-case enumeration, which is guaranteed to be unconstructable.

I’ll probably think of more things after I hit “Publish” on this, so if I missed anything, let me know and I’ll update the post.

 

Flybbertigybbets

“gyb” stands for “Generate Your Boilerplate”. Built in Python, it’s part of Swift’s utility suite. You can find its implemention here. It’s part of the open source Swift source.

Gybbing provides a preprocessor that automates inherently repetitive coding tasks. For example, it helps construct built in math types. With gybs, you don’t have to re-implement a common task for each type. That can get very old very fast. (Copying and pasting nearly-identical code is never fun.)

If you hop over to the standard library source, you’ll find a couple of dozen gyb sources to look at. These range from tuples to string interpolation to integers. They use a mix of GYB markup and injected Python code to generate related-type code.

Here’s the help info from running gyb -h:

usage: gyb [-h] [-D NAME=VALUE] [-o TARGET] [--test] [--verbose-test] [--dump]
           [--line-directive LINE_DIRECTIVE]
           [file]

Generate Your Boilerplate!

positional arguments:
  file                  Path to GYB template file (defaults to stdin)

optional arguments:
  -h, --help            show this help message and exit
  -D NAME=VALUE         Bindings to be set in the template's execution context
  -o TARGET             Output file (defaults to stdout)
  --test                Run a self-test
  --verbose-test        Run a verbose self-test
  --dump                Dump the parsed template to stdout
  --line-directive LINE_DIRECTIVE
                        Line directive prefix; empty => no line markers

    A GYB template consists of the following elements:

      - Literal text which is inserted directly into the output

      - %% or $$ in literal text, which insert literal '%' and '$'
        symbols respectively.

      - Substitutions of the form ${}.  The Python
        expression is converted to a string and the result is inserted
        into the output.

      - Python code delimited by %{...}%.  Typically used to inject
        definitions (functions, classes, variable bindings) into the
        evaluation context of the template.  Common indentation is
        stripped, so you can add as much indentation to the beginning
        of this code as you like

      - Lines beginning with optional whitespace followed by a single
        '%' and Python code.  %-lines allow you to nest other
        constructs inside them.  To close a level of nesting, use the
        "%end" construct.

      - Lines beginning with optional whitespace and followed by a
        single '%' and the token "end", which close open constructs in
        %-lines.

    Example template:

          - Hello -
        %{
             x = 42
             def succ(a):
                 return a+1
        }%

        I can assure you that ${x} < ${succ(x)} % if int(y) > 7:
        %    for i in range(3):
        y is greater than seven!
        %    end
        % else:
        y is less than or equal to seven
        % end

          - The End. -

    When run with "gyb -Dy=9", the output is

          - Hello -

        I can assure you that 42 < 43

        y is greater than seven!
        y is greater than seven!
        y is greater than seven!

          - The End. -

Defer; defer; defer

Someone was asking about defer, and the order in which they’re added to the stack. It’s pretty easy to create a test set-up like this one so you can play with them yourself.

Here are a few inspirational ways to use defer:

Pair tear-down tasks with setup. For example, if you’re deploying to pre-iOS 10, you might use begin and end for image contexts. Defer is also great for alloc/dealloc, fopen/fclose, etc.

UIGraphicsBeginImageContext(size); defer { UIGraphicsEndImageContext() }

Postdecrement/postincrement. Use defer to return a value before modifying it:

defer { x = x - 1 }; return x // x--

Apply “next state” updates. Use defer in sequence calls, like this example that repeatedly circles through the color wheel:

return sequence(state: hue, next: {
     (state : inout CGFloat) -> Color? in
     defer { state = state + stepAngle }
     ...
     return value }

Leverage group layout. This example draws an array of images into a line. The actual code does a lot of fussy work. Moving defer to the start of the forEach loop helps keep track of the “next step” without searching through the actual layout code.

allImages.forEach { image in
    defer { px += image.size.width + spaceOffset }
    image.draw(at: CGPoint(x: px, y: py))
}

Handy, no?

A few interesting things about iOS Swift Playgrounds

Misc rambles:

Interesting: You no longer “print” in iOS Swift Playgrounds. Anything that can be presented using a playground QuickLook or a custom string representation is done so with the tap-to-view item at the right. There’s no “printing” per se, no console, while I suppose you can import Foundation and NSLog stuff, I’m not sure how reasonable a solution that is, especially on the go.

Because: This morning I ended up importing AVFoundation to let AVSpeechSynthesizer “speak” feedback to me. Not ideal, but short and easy to implement, and got the job done for some stuff that wasn’t rendering nicely the way I needed it to, in a complicated playground book that was using SceneKit not UIKit.

Rad discovery of the day: Command-R runs the playground without having to tap the screen. \o/ Press and hold Command key (on a physical Bluetooth keyboard, this doesn’t work on, for example, type2phone) to discover other shortcuts:

screen-shot-2016-11-11-at-3-13-29-pm

Sad discovery of the day: You cannot air drop playground books anymore, and Swift Playgrounds is being very very careful about allowing you access to any material you didn’t create or import yourself. There’s no Documents support for iTunes. At the suggestion of Jonathan Penn, I gave it a try after rebooting and now it works. You wouldn’t believe how much time I wasted trying to extract information to look up implementation details.

Thanks again to Jonathan P for pointing me to the command-key discovery feature!

Cocoapods and Copyright claims

So what do I do about this? Or more particularly about this: “Copyright (c) 2016 tangzhentao <tangzhentaoxl@sina.cn>”? I don’t mind people using sources from my repos, but I do mind them claiming copyright. I would appreciate advice and thoughts.

Update: On Jeremy Tregunna’s advice, I sent an email: “You are welcome to create Cocoapods using my repositories, but you are not welcome to claim copyright ownership, change the license (BSD attribution in this case), or otherwise misattribute my code. ” I asked tangzhentao to correct the matter immediately.

Update: Tangzhentao responds: “I just saw this problem today in Github and then I went to check my email. Thank everybody to piont out this mistake, especially Erica Sadun. Now I have corrected this mistake. But I don’t know if I really correct this mistake. If not, please remind me, thanks.” There are no changes to the authorship or copyrights, I have asked him/her to update within 24 hours or I will contact Github.

Swift By Emoji: A considered approach

Not too long ago Iain Delaney pointed me to this graphic:

cwniukiukaaydtj

The graphic was designed by Steve Luscher and written about by Joey Devilla in this blog post on Global Nerdy. I thought it was brilliant and inspiring.

It wasn’t written in Swift and certainly wasn’t running in Swift. I decided to play around: I built a playground, assigning massive lists of emoji strings to emoji variables, and got these examples running properly using Swift syntax.

mapfilterreduce2

Rather than use a pile of poo, which assumes at each stage of reduction you’re combining poo with a new food, I went with Jaden Geller’s recommendation on Twitter. In the Swift version, the reduction starts with a sad face and becomes happy and satisfied.

I played around with other foods to see if it was worth expanding the samples but it was never quite as clean or elegant as the simple 4-item original:

mapfilterreduce1

Stepping away from the cow/potato/chicken/corn space, I wanted to see if there might be a better filter than isVegetarian. A child makes amusing (if not nutritious) food choices:

filter

And then I thought, well what about other Swift language essentials. So I mocked up the concept of naming items by whether they are mutating or non-mutating:

mutating

And repeating:

repeating

And sorted (although this one could probably use some better food choices):

sorted

Zipping was an obvious win as well:

zip

And map vs flatMap:

flatmap

Unfortunately, a soccer ball is not a valid character identifier so I couldn’t bitcast between a European football and an America one. Inconsistent Emoji character sets made me sad. Swift needs a standards-based operator and identifier makeover:

unsafebitcast

By the time I started playing with fatalError, I realized I was spending way too much time on this:

fatalerror

Do you have any favorite Swift functionality that lends itself to emojification? I’ve showed you mine. Now, show me yours.

Update: Phil Aaronson suggests using emoji functions too.

Ideally, examples should be able to compile and run in a Swift playground but I’m open to concepts that can be better explained with Emoji even when implementation is tricky.

Holy War: Enum Hash Values and Option Sets

I recently engaged in a conversation on the Swift Users list about converting a JSON array of string values into an enumeration set. I somewhat tongue in cheek suggested that these values be converted into an string-based enumeration, and then their hashValues be used to set-up flags.

I was, of course, immediately (and rightfully) challenged on whether a solution should hinge on the hashValue implementation detail — it shouldn’t. But the more I thought about this, I wondered whether it might be reasonable to eliminate potential errors by using the hash values to guide the option set creation.

Here’s what I mean. Consider this enumeration:

private enum LaundryFlags: String { 
    case lowWater, lowHeat, gentleCycle, tumbleDry }

You can use the enumeration to populate an option set, knowing each hashValue will not overlap, allowing the compiler to choose the implementation details without ever touching them yourself:

public static let lowWater = LaundryOptions(rawValue: 
    1 << LaundryFlags.lowWater.hashValue)

This approach allows you to build option sets from strings but not worry what the raw values are. Whatever the compiler picks will be consistent:

// String based initialization
public init(strings: [String]) {
    let set: LaundryOptions = strings
        .flatMap({ LaundryFlags(rawValue: $0) }) // to enumeration
        .map({ 1 << $0.hashValue }) // to Int, to flag
        .flatMap({ LaundryOptions(rawValue: $0) }) // to option set
        .reduce([]) { $0.union($1) } // joined
    _rawValue = set.rawValue
}

There are limits. You cannot use enumerations to represent compound convenience members like the following examples:

public static let energyStar: LaundryOptions = [.lowWater, .lowHeat]
public static let gentleStar: LaundryOptions = energyStar.union(gentleCycle)

On the other hand, you can adopt CustomStringConvertible pretty easily even though raw-value enumerations do not report their members and cannot be initialized from hash values. As the following code shows, it’s not a huge burden to generate a lazy member dictionary. You can boiler plate the implementation and copy/paste your case list into this array:

static var memberDict: Dictionary<Int, String> = 
    [lowWater, lowHeat, gentleCycle, tumbleDry]
    .reduce([:]) {
        var dict = $0
        dict[$1.hashValue] = "\($1)" 
        return dict
}

Reduce the dictionary with bit math from the option set:

public var description: String {
    let members = LaundryFlags.memberDict.reduce([]) {
        return (rawValue & 1 << $1.key) != 0
            ? $0 + [$1.value] : $0
    }
    return members.joined(separator: ", ")
}

So here’s the holy war question: given how simple and reliable this approach is, do I back off of my “never use implementation details” guidance for raw value enumerations and their hash values?

Full gist is here.

Swift Holy War: Comments are not an Anti-pattern

Got into a debate yesterday about this write-up by developer Andrew Warner. His “Beware the Siren Song of Comments” suggests that developers delude themselves because comments detract from code quality:

Comments decay. They aren’t compiled, and they’ll never get executed at runtime. If they become out of date or incorrect, no test is going to fail and no user is going to complain. Programmers work around them out of fear that “somebody might need this comment or it might provide some value in the future”, pushing them along far after they’re useful (if you can even argue that they were useful in the first place).

His recommendation?

[Y]ou don’t have any excuse to write comments. Give these methods a try, and I promise you’ll have a cleaner codebase that’s easier to maintain.

I don’t claim that comments should counterbalance bad design decisions like poor naming or flawed algorithms. I do believe they play an important role in good coding practices — whether or not your code is meant strictly for internal use or to be consumed as APIs.

As I discussed on this blog a few weeks ago, there’s a big difference between the you writing code and “future you”, your team, and anyone else reading code. Here’s what I have to say about commenting in Swift Style:

Comment, comment, comment and while you’re at it, write tests. Tests can save you the whole “What I was doing here?” because you can just look at what is broken and what you expected to work.” It’s better to write less code and make up that time by explaining the code you did write better.

Sure, it helps to leave in a “TODO:” where it counts (“the performance is really bad here”) but while you’re at it, try to leave a few ideas about what exactly is going wrong, and what hypotheses you have rolling around your soon-to-be-extinct neurons. Past you understood things. Future you is clueless.

It always costs less to fix things in the past because you’ve invested in uploading the full design into your brain. Re-upping that design and getting back up to speed involves huge penalties.

Comments can explain the non-obvious, the tricky, or the counter-intuitive to a reader: This is intentional. This thing affects that thing. This data is not validated at this stage. Responsibility for this process now passes to this delegate. Comments enable you to establish what your assumptions are at which points in code and they allow you to comment on design qualities.

Comments create a record of intent. They may mention approaches that were tried and why they were abandoned. They may discuss how design decisions came to be — what paths were explored and why some of those paths weren’t chosen in the end.

Comments allow you to colocate thoughts with the code they refer to. Commit messages are helpful but I don’t think a commit message is  the proper place to document workarounds or unexpected behavior. Plus version control history may not travel with source code, if the code is reused in another project.

Comments provide a bread crumb trail of design decisions that aren’t kept in working memory and cannot be intuited just from reading code or scanning tests. Unexpected complexity is one of the things you’ll want to comment about. In fact, commenting on the unexpected is important because the alternative is essentially a bug.

Structured comments add another layer of utility, supporting API consumption. Markup allows these special comments to automatically convert into highly formatted local documentation supporting another set of readers beyond code review, debugging, maintenance, and enhancement.

Comments don’t just paper over bad design and coding. They document a process of making code right, supporting future reading and modification. Good comments reduce the mental effort needed by readers each time they review your source, enabling them to focus more on specific tasks like “how to I add this feature” rather than “what the hell was going on here”. While good code can at times be “self documenting”, that doesn’t mean it always is (or even usually is) self documenting.

As stepping stones to “past you”, good comments document what you were thinking and why you did things the way you did. Your past design decisions should never be a mystery or a burden placed before future readers of your code no matter how brilliant or insightful you expect them to be.

PaintCode releases new update and leaves App Store

screen-shot-2016-11-02-at-8-54-38-am

I’ve been a fan of PaintCode for a long time. PaintCode is a drawing and programming app that lets you move between code and rendered pictures. With it, you can create paths and fills, and then paint that information right into your app code using a variety of development languages.

Mike A at PixelCut dropped me a note last night letting me know that PaintCode 3 is now ready for release. The new version adds Android code generation, JavaScript, Telekinesis and more, in addition to Objective C and (now) Swift 3 support.

You can now use parameterized methods to draw into target rectangles. The app supports destination behaviors like aspect fit, stretch, center, etc. Although I’ve long since developed similar code for my own use, this is a great feature to add without relying on the end-coder’s expertise.

PixelCut has also made the choice to leave the Mac App Store. I’ve reached out to them to find out more about their decision.

PaintCode isn’t cheap but it’s a good tool for anyone who uses a lot of vector art, drawing, and paths in their code and they’ve been dedicated to keeping the tool current and updated. Existing customers get a 20% discount off the $99 app price.