Apple TV, Home Sharing, and Missing Movies

I rented Hunt for the Wilderpeople last week, while it was the $0.99 featured rental. I’ve heard good things about this Kiwi movie (I’m a bit of a kiwiholic) and couldn’t wait to watch it.

screen-shot-2016-12-13-at-2-41-44-pm

So today, with a draft of Swift Style pushed up to Pragmatic, I thought I’d set it up for a nice family watch tonight. I opened the Computers > Rentals section on Apple TV and saw this:

screen-shot-2016-12-13-at-2-47-11-pm

I wasted about 20 minutes googling things like “why doesn’t my rental show up on my Apple TV” and checking my iTunes accounts and home sharing setup, when I suddenly remembered this had happened to me before.

With that spark of inspiration lingering in my mind, I went to iTunes on my computer (where I had rented it) and sure enough, it was still up in the cloud. I clicked the download button and got it down to my computer:

screen-shot-2016-12-13-at-2-41-42-pm

About 1.41 Gigabytes later (and several pause/resumes when the download speed got slow — seriously, at one point the ETA jumped from over 40 minutes to under 3), I returned to Apple TV and hopped into my home-sharing library.

screen-shot-2016-12-13-at-3-19-15-pm

Tada.

So if you’re looking for a lost movie, or you can’t find your rental on Apple TV, make sure that if you rented it on your home computer, that you’ve downloaded it from the cloud before attempting to play it from ATV.

Programming Cozmo

Anki has been kind enough to let me play with their new Cozmo unit and explore their SDK. Cozmo is a wonderful device, developed by people who understand a lot of core principles about human interaction and engagement.

Cozmo is adorable. When it recognizes your face, it wriggles with happiness. It explores its environment. When it’s bored, it sets up a game to play with you. It can get “upset” and demand attention. It’s one of the most personable and delightful robots I’ve played with.

At its heart is a well-chosen collection of minimal elements. The unit can move around the room, with a 4-wheel/2-tread system. It includes an onboard forklift that can rise and fall, an OLED “face” that expresses emotion, and a camera system that ties into a computer vision system, which I believe is based on PIL, the Python Image Library. (Anki tells me that Cozmo’s vision system “does not use PIL or Python in any way, though the Python SDK interface uses PIL for decoding jpegs, drawing animations, etc.”)

Three lightweight blocks with easily-identified markings complete the Cozmo package, which Cozmo can tap, lift, stack, and roll.

Between its remarkable cuteness and its vision-based API, it’s a perfect system for introducing kids to programming. I was really excited to jump into the SDK and see how far I could push it.

Here is Anki’s “Hello World” code (more or less, I’ve tweaked it a little) from their first developer tutorial:

import sys
import cozmo

'''
Hello Human
Make Cozmo say 'Hello Human' in this simple
Cozmo SDK example program.
'''

def run(sdk_conn):
    robot = sdk_conn.wait_for_robot()
    robot.say_text("Hello Human").wait_for_completed()
    print("Success")

if __name__ == '__main__':
    cozmo.setup_basic_logging()    
    try:
        cozmo.connect(run)
    except cozmo.ConnectionError as err:
        sys.exit("Connection error 😬: %s" % err)

Although simple, this “Hello World” includes quite a lot of implementation details that can scare off young learners. For comparison, here’s the start of Apple’s tutorial on Swift “Learn to Code”:

screen-shot-2016-12-12-at-11-45-24-am

There’s such a huge difference here. In Apple’s case, everything that Byte (the main character) does is limited to easy-to-understand, simple calls. The entire implementation is abstracted away, and all that’s left are instructions and very directed calls, which the student can put together, re-order, and explore with immediate feedback.

In Anki’s code, you’re presented with material that’s dealing with set-up, exceptions, asynchronous calls, and more. That is a huge amount of information to put in front of a learner, and to then say “ignore all of this”. Cozmo is underserved by this approach. Real life robots are always going to be a lot more fun to work with than on-screen animations. Cozmo deserved as simple a vocabulary as Byte. That difference set me on the road to create a proof of concept.

In this effort, I’ve tried to develop a more engaging system of interaction that better mirrors the way kids learn. By creating high level abstractions, I wanted to support the same kind of learning as “Learn to Code”. Learn to Code begins with procedural calls, and then conditional ones, and moving on to iteration and functional abstraction, and so forth.

My yardstick of success has been, “can my son use these building blocks to express goals and master basic procedural and conditional code?” (I haven’t gotten him up to iteration yet.) So far, so good, actually.  Here is what my updated “Hello World” looks like for Cozmo, after creating a more structured entry into robot control functionality:

from Cozmo import *

# run, cozmo, run
def actions(cozmoLink):
    '''Specify actions for cozmo to run.'''
    
    # Fetch robot
    coz = Cozmo.robot(cozmoLink)

    # Say something
    coz.say("Hello Human")

Cozmo.startUp(actions)

Not quite as clean as “Learn to Code” but I think it’s a vast improvement on the original. Calls now go through a central Cozmo class. I’ve chunked together common behavior and I’ve abstracted away most implementation details, which are not of immediate interest to a student learner.

Although I haven’t had the time to really take this as far as I want, my Cozmo system can now talk, drive, turn, and engage (a little) with light cubes. What follows is a slightly more involved example. Cozmo runs several actions in sequence, and then conditionally responds to an interaction:

from Cozmo import *
from Colors import *

# Run, Cozmo, run
def actions(cozmoLink):
    '''Specify actions for cozmo to run.'''
    
    # Fetch robot
    coz = Cozmo.robot(cozmoLink)

    # Say something
    coz.say("Hello")

    # Drive a little
    coz.drive(time = 3, direction = Direction.forward)
    
    # Turn
    coz.turn(degrees = 180)
    
    # Drive a little more
    coz.drive(time = 3, direction = Direction.forward)

    # Light up a cube
    cube = coz.cube(0)
    cube.setColor(colorLime)
    
    # Tap it!
    coz.say("Tap it")    
    if cube.waitForTap():
        coz.say("You tapped it")
    else:
        coz.say("Why no tap?")
    cube.switchOff()

Cozmo.startUp(actions)

And here is a video showing Cozmo executing this code:

If you’d like to explore this a little further:

  • Here is a video showing the SDK feedback during that execution. You can see how the commands translate to base Cozmo directives.
  • I’ve left a bit of source code over at GitHub if you have a Cozmo or are just interested in my approach.

As you might expect, creating a usable student-focused learning system is time consuming and exhausting. On top of providing controlled functionality, what’s missing here is a lesson plan and a list of skills to master framed into “Let’s learn Python with Cozmo”. What’s here is just a sense of how that functionality might look when directed into more manageable chunks.

Given my time frame, I’ve focused more on “can this device be made student friendly” than producing an actual product. I believe my proof of concept shows that the right kind of engagement can support this kind of learning with this real-world robot.

The thing that appeals most to me about Cozmo from the start has been its rich computer vision capabilities. What I haven’t had a chance to really touch on yet is its high level features like “search for a cube”, “lift it and place it on another cube”, all of which are provided as building blocks in its existing API, and all of which are terrific touch points for a lesson plan.

I can easily see where I’d want to develop some new games with the robot, like lowering reaction time (it gets really hard under about three quarters of a second to tap that darn cube) and creating cube-to-cube sequences of light. I’d also love to discover whether I can extend detection to some leftovers my son brought home from our library’s 3D printer reject bin.

Cozmo does not offer a voice input SDK. It’s only real way to interact is through its cameras (and vision system) and through taps on its cubes. Even so, there’s a pretty rich basis to craft new ways to interact.

As for Anki’s built-ins, they’re quite rich. Cozmo can flip cubes, pull wheelies, and interact in a respectably rich range of physical and (via its face screen) emotional ways.

Even if you’re not programming the system, it’s a delightful toy. Add in the SDK though, and there’s a fantastic basis for learning.

Enter the Python: Peeking at a language

Last week, I wrote about how I set up Xcode to run Python. It’s been working great. Xcode may not be everyone’s cup of tea, but I love it. Syntax highlighting, familiar keybindings, symbol completion. I couldn’t be happier. A lot of people pushed me to use Pycharm community edition, but while I’ve installed it and tried it a few times, I keep going back to Xcode. Warts and all.

I haven’t logged many hours in Python but it’s been a fascinating language experience. Let me go all metaphor on you. Way back in the 90’s there was this show called “Sliders“, about a bunch of people moving between parallel worlds. Almost everything was the same from world to world — normal humans, trees, buildings, whatever — but there were always fundamental differences in the culture and the people that always reminded you that you weren’t home.

Python is the Sliders version of Swift, the one where Chris Lattner was never born. Everything is eerily familiar and nothing is quite right. Where are my value types? My generics? My type extensions. Let me throw out another metaphor — one that will probably resonate with even fewer people: Python is the language version of the Nethack Rogue Level, where you enter “what seems to be an older, more primitive world.” It’s all familiar. Nothing is exactly the same.

This morning, I attempted to extend a type. I’m working with Anki’s Cozmo robot SDK, which is written for Python 3.5.1 or later. I’m trying to reconfigure many of the basic calls into more appropriate chunks suitable for teaching kids some programming basics.

Instead of focusing on asynchronous callbacks and exceptions, I want to provide really simple blocks that extend the robot type API in a way that hides nearly all the implementation details. I’m trying to build, in a way, a Python version of Swift Playgrounds but with a real robot. (And it’s going well, but more about that in another post.)

What I found was that Python really doesn’t want to extend types. You can subclass. You can compose. But so far, I haven’t found a way to add an extension that services an existing type. When I asked around, the Python gurus on freenode recommended I stop worrying about polluting the global namespace and embrace freestanding functions as needed.

Oh, my delicate Swift sensibilities! Adding global functions and constants? Cluttering the global namespace? I find myself clinging to Swift conventions. I create enumerations and type my arguments:

class Direction(IntEnum):
    '''Permitted driving directions.'''
    forward = 1
    backward = -1

def drive(robot: cozmo.robot.Robot, 
    direction: Direction = Direction.forward): ...

The Cozmo SDK defines its constants like this:

LEFT = 1
RIGHT = 2
TOP = 4
BOTTOM = 8

I don’t think I’m in Swift-land anymore.

A lot of the things I like most about Python appear to be fairly new, like that ability to type arguments. I’m assured by some Pythonistas that this is almost entirely syntactic sugar, and there appears to be no type-checking, inference, or casting applied to calls.

I thought I would really hate the indentation-based scoping but I don’t. It’s easy to use (start a scope with a colon, indent 4 spaces for that scope). It reads well. It’s clean. Non-braced scoping ended up being a complete non-issue for me, and I mildly admire its clean look.

I’m less excited by Python’s take on structured documentation. The standard is outlined in PEP-257. Unlike Apple’s Swift Documentation Markup, Python markup doesn’t seem to support specific in-line tool use in addition to document generation. I’m sensitive to how much better Swift creates a structured system for detailing parameters, error conditions, return types, and descriptions, and how it scales from types to functions and methods to individual instances and provides Xcode integration.

So much in Python is very similar to Swift but with a slight twist to it. Closures? Lambdas are in there. Mapping? That’s there too. Partial application? Seems to be. Most times that I reach for a tool in my existing proficiencies, I can usually find a Python equivalent such as list comprehension, which is basically mapping across sequences and collections.

I’m sorely missing my value types. One of the first things I did when trying to work through some tutorials was to try to create a skeleton dictionary rather than type out full dictionaries for each instance. I quickly learned Python uses reference types:

# the original dict was more complicated
studentDict = {"name" : "", "tests" : []} 

joe = studentDict # create joe
joe["name"] = "joe"
bob = studentDict # create bob
bob["name"] = "bob"

# reference type
print(joe) # {'tests': [], 'name': 'bob'}
print(bob) # {'tests': [], 'name': 'bob'}

Oops.

In any case, I’m still really really new to the language given my full-court-press on finishing Swift Style. As much as I wish I were writing this code in Swift, I’m glad that I have the opportunity to explore Python and hope I get to spend some time with Scala in the near future. This project is offering me a lot of valuable insights about where Swift came from and increased appreciation for the work the core Swift team put in to give us the language we have now.

Cozmo: The Unboxening

I recently reached out to Anki, creators of the Cozmo robot, to  ask if I could explore the device from a developer’s perspective. Shipping with a Python SDK, Cozmo offers some surprisingly sophisticated image processing and recognition features, analogous to Apple’s Core Image.

Before jumping into the programming side of things, let me acknowledge that I am primarily an Apple developer. Therefore I must categorically kick off by evaluating package design.

I didn’t get to start unboxing last night. When my unit arrived during a cold snap, the package window was all fogged up. I opened the top, added a desiccant unit, and let the package dry out and warm out overnight.

czm6qavweaadneu

This morning, I finally could explore. As you’d expect with high end consumer goods (Cozmo retails for $180), the box used satisfyingly thick cardboard, was easy to open, and presented the product nicely while hiding the user manual, power cord, and accessories.

Unexpectedly, my favorite part of the entire boxing system was Cozmo’s perch. Made of quality yellow plastic, this industrial presentation feature is practically a toy in itself.

screen-shot-2016-12-09-at-9-00-16-am

Flip it over, and instead of expected wire wraps, there’s an ingenious system to release the Cozmo unit. Pull up the yellow spacer and pinch the two white tabs. It all comes apart, allowing you to remove Cozmo, and start him charging.

screen-shot-2016-12-09-at-9-01-55-am

Then while he charges, you can spend time putting the pieces back together and taking them apart over and over. It’s practically an extra free toy that ships with the robot. Beautiful design and completely unexpected.

screen-shot-2016-12-09-at-9-04-28-am

The full complement of parts include the Cozmo robot, a USB charging dock with a separate a wall-adapter, a trio of play blocks (“Interactive Power Cubes”), and a welcome packet.

screen-shot-2016-12-09-at-9-09-51-am

The instructions say to place him on an open table in a well lit room, with room to move around. Charging from empty to full is specified at 10-12 minutes, with a rated play time of 1-2 hours. (I wouldn’t be surprised if that number drops once you start putting extra demands on his processors.)

That 10-12 minutes subjectively lasts approximately 3-4 months after you first finish unboxing. Child and I got into a heated debate as to whether we’d name him after Cosimo de’ Medici, founder of the Medici political dynasty, or Cosmog, nebula Pokemon and opener of “Ultra Wormholes”.

I don’t want to spoil the instruction booklet for you so let me just say, the writeup is adorable, clever, and simple. The consumer warnings in particular made me laugh out loud. It’s a great example of technical writing and communication, focusing on simplicity and clarity. It’s really well done.

You must install a separate Cozmo application you on an iOS or Android device. It just shipped a 1.1.0 update, so make sure you’re running the latest version. It helps if you watch this video before trying to set-up.

Open Settings and connect to the Cozmo WiFi network. Lift Cozmo’s front arm to display the password, and then use Settings to log in, making sure to type everything using exact upper casing. The password is random mix of upper case letters and numbers, and the iPhone’s keypad doesn’t remember casing when moving between number input and text input.

Anki recommends typing the password into your Notes app, and I endorse this suggestion, especially when I point out how many times I tried to get it to connect. That’s because at first I didn’t realize Cloak VPN was trying to secure the Cozmo WiFi connection. It really really helps if you set it up to trust the Cozmo network. This one detail put a huge crimp into my set-up, causing immeasurable pain and frustration. I finally found this support write-up, which mentions VPN issues at the very bottom.

I haven’t spent much time playing with Cozmo yet but speaking as an iOS dev, there are quite a few things Anki could do to tighten up their app. There’s great content and some terrific games but the app reads as “cross platform with compromise”. (It seems to have Unity under its cover.)

To give just a couple of examples, the cursor controls in a custom text field don’t follow iOS standards. When you use cursor arrows during typing, the active cursor position does not update. That’s iOS 101.

In terms of user interface flow, it’s missing iOS’s inherent “deference to the user”. For example, there’s no “try again” button when attempting to connect without having to go to the help screen over and over again. (Which I did, over and over and over, through an hour or so of set-up until I found that VPN advice.) When you’re using games and other features, the ability to quickly switch tasks is somewhat limited.

The app would benefit from a HIG/GUI once-over for usability but that’s really the only weak spot in the big package that I’ve encountered.

As for Cozmo himself, he’s a delight. As part of set-up, he learned my face and that of my daughter. Who cannot love a robot that wakes up from charging, sees your face, recognizes you, greets you by name and then wiggles with happiness?!? It’s phenomenally adorable.

Of course, my interest lies primarily in the SDK, and that exploration will have to wait for another write-up. For now, a summary to date:

  • Adorable robot with amazing humanizing affect display.
  • Top notch Apple-worthy packaging.
  • Great starter games to inspire development possibilities.
  • There’s an app.

Cozmo is right now exploring the floor of my office, making random offhand comments in robotese about what he’s finding and generally having a ball. I think I’ll stop writing for a short while and join him in having fun.

Swift Holy Wars: To bracket or not in option sets?

As much as I’d like OptionSets to be a type, they’re not.

public protocol OptionSet : SetAlgebra, RawRepresentable

The current implementation (via a protocol), enables API evolution. As Joe Groff pointed out to me, developers can break down a single option into multiple refined options, while still offering the original components. You can see an example of this in the following implementation, where the compound energyStar and gentleStar  options occupy an equal footing with  component bit-shifted flags:

public struct LaundryOptions: OptionSet {
    public static let lowWater = LaundryOptions(rawValue: 1 << 0)
    public static let lowHeat = LaundryOptions(rawValue: 1 << 1)
    public static let gentleCycle = LaundryOptions(rawValue: 1 << 2)
    public static let tumbleDry = LaundryOptions(rawValue: 1 << 3)
    
    public static let energyStar: LaundryOptions = [.lowWater, .lowHeat]
    public static let gentleStar: LaundryOptions = [.energyStar, .gentleCycle]
    
    public init(rawValue: Int) {
        self.rawValue = rawValue
    }
    public var rawValue: Int
}

Although this design looks like you are using sets, you really aren’t.  The square bracket syntax is a bit a of a cheat:

let options1: LaundryOptions = [.lowWater, .lowHeat]
let options2: LaundryOptions = .energyStar
let options3: LaundryOptions = [.energyStar, .lowHeat]

// prints 3 for each one
[options1, options2, options3].forEach {
    print($0.rawValue)
}

When you surround an option set with brackets, you get back an option set. This means in Swift, [.foo] is the same as .foo.

I entered into a heated style debate today with Soroush Khanlou over option sets, specifically if it were better to make a call like accessQueue.sync(flags: [.barrier]) using or omitting the brackets.

Soroush felt that omitting the brackets produces less noise. If you can compile without the brackets, why include them?

I said “use ’em”. When you’re passing flags and a static member, let the role guide your style. When the code expects an option set, make the argument look like an option set.

The brackets clearly indicate both the argument role and creates an affordance, a specific visual indication that you can expand the set by introducing more options. Without brackets, this may not be intuitively obvious to someone less familiar with option sets.

So what do you think? Brackets? No brackets? What Swift cuisine reigns supreme?

Running Python in Xcode: Step by Step

As I’m preparing for a project that will involve Python programming, I need to get up to speed with at least a basic level of Python mastery. However, I’m not a big fan of using the interactive Python REPL, or whatever it is actually called:

screen-shot-2016-12-04-at-11-37-21-am

I decided to use Xcode instead, and I’m finding it a much better solution for my needs:

screen-shot-2016-12-03-at-8-31-15-pm

Here’s the steps I took to set up this project:

Step 1: Install Python 3.5

If you run python -V at the command line, macOS reports “Python 2.7.10”, or at least it does on my system. Bzzt. I want 3.5.2, which is the most recent non-beta release, and dates to June of this year.

I grabbed my installer from the Python.org downloads page: https://www.python.org/downloads/release/python-352/

Step 2: Locate python3

I use tcsh, so where python3 reports /usr/local/bin/python3. The location is surely the same for you, but I don’t know what the equivalent for where is in bash.

Step 3: Create an Xcode project

File > New > Project > Cross-platform > External Build System > Next.

screen-shot-2016-12-04-at-11-44-06-am

Enter a name (e.g. Python), and enter the path from Step 2 into the “Build Tool” line. Click Next.

screen-shot-2016-12-04-at-11-44-43-am

Navigate to whatever location you like, and click Create.

Step 4. Create a Python file

Choose File > New,  select macOS > Other > Empty. Click  Next.

screen-shot-2016-12-04-at-11-48-04-am

You should already be in your project’s top level folder. If not, go there. Name your file Whatever.py, choosing whatever name you like. I went with Work.py. Make sure the “add to target Python” box is checked. Click Create.

screen-shot-2016-12-04-at-11-49-43-am

Step 5. Edit your Run Scheme

The Xcode default should have the Run scheme selected:

cap

Click and hold on the Python target in the jump bar. Select Edit Scheme…

screen-shot-2016-12-04-at-11-50-56-am-2

The Run scheme displays, with the Info tab selected.

Step 6. Choose the Executable

I warn you now that this step is going to be delicate, fragile, and stupid. That’s because Xcode, for whatever reason, will not let you use the symbolic link at /usr/local/bin/python3. I don’t know why.

In the Info tab. Select “Other” from the Executable pop-up list. A file selection dialog appears.

cap

 

Return to the terminal. Type: open /usr/local/bin. Select python3 and control-click/right-click. Select Show Original. This will probably be named python3.5. It’s not a symbolic link but unfortunately Xcode continues to be fussy about allowing you to select it as your executable because of the period in its name. Sigh.

Drag python3.5 onto the file dialog and click Choose, if you’re allowed to. If so, great. If not, you need to work around Xcode: create a hard link and then drag the link onto the dialog.

% ln python3.5 python35

I know, I know. Ew. But it’s better than copying, or worse, renaming the file. And no, symbolic links don’t seem to work here. Better solution? Let me know.

Finally, uncheck “Debug executable”. You don’t want to debug the Python language itself.

screen-shot-2016-12-04-at-12-05-26-pm

Step 7. Add Launch Arguments

Now, click the Arguments tab. Click + under “Arguments Passed On Launch” and type $(SRCROOT)/ followed by the name of the Python file you created in Step 4.

screen-shot-2016-12-04-at-12-07-02-pm

Step 8. Test it out.

Click Close to dismiss the scheme editor. Enter a program (don’t forget all those colons and tabs) and run it:

screen-shot-2016-12-04-at-12-38-05-pm

It’s a very odd thing to be jumping into Python with a Swift background. Clearly Swift has inherited a lot of Python genes. It also feels sinful to use such lax typing without compiler oversight. That said, my first experiences in Python can wait for another day and another post. More to follow.

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?