Archive for December, 2015

Swift-Evolution: Nope, not merging that

The Swift team has kindly posted a “commonly rejected” idea list on the Swift-Evolution github repo. This helps those who might be inclined to spend time developing proposals that are unlikely to be accepted.

It’s strongly recommended that you review this document before presenting your ideas on the mailing list. Here’s a mirror of the current list, as I couldn’t figure out how to embed directly from the repo’s version:

Migrating `if`s to `guard`s in Swift

Scattered throughout my code are uncountable variations on the following statement:

if some condition {continue}

Recently, I have been converting a vast swath of these from if statements to guards. This post describes my reasons for voluntarily performing this migration: a step that seemingly has no impact on the efficiency or correctness of my code.

The Guard Statement

Guard statements are best known for adding conditional bindings to an enclosing scope:

guard let value = possibleNil else {leave scope}

But guards can also differentiate positive and negative execution paths:

guard some condition else {continue}

In this latter form, guard statements act as non-fatal assertions. They prevent forward progress should that precondition fail. It checks a condition and then, if false, leaves scope via continue, break, return, etc. For example, in loops, they limit whether each iteration is fully run. In functions, they prevent bad data from causing errors.

A properly-constructed guard statement takes on the metaphoric characteristics of a human traffic flagman. It allows your code to proceed only when it conforms to certain rules.

Establishing Execution Requirements

A general guard statement establishes requirements for execution. It also provides a safe path for transferring control if and when those requirements fail. Contrast that behavior with assert() and precondition(). Like these other runtime checks, guards add tests for desired state. However, its outcome is not noisy fatal errors that terminate execution.

Guards with requirements are not substitutes for normal if clauses. Avoid guard when a Boolean false value introduces side effects or runs a true execution branch. Instead, guard creates instantly identifiable predicates that establish the required conditions for code to execute properly and offer early exit on failure.

Refactoring

The guard keyword jumps out from code in a way that unambiguously distinguishes these statements from if. Even though my code would continue to operate without my by-hand-migration, upgrading to guard from if improves readability and enhances the clarity of my intent.

Placing guards at the start of scopes, as I do with assertions, forms a new kind of requirements block. Dave Abrahams wrote about the roles of assert and precondition on the Swift Evolution list:

The two functions have distinct roles:
assert: checking your own code for internal errors.
precondition: for checking that your clients have given you valid arguments.

To this, I add guard: establishing a set of requirements that must be met before the code that follows can be safely executed. Consider refactoring any statement that say, in essence, “unless this statement is true, do not progress any further”.

Are you migrating to guard in your own code? And if so, what are the rules you use to decide whether to stay with “if” or switch to “guard”? Let me know in the comments or throw me a tweet or email.

Like the post? Buy a book.

We are Devo: Swift Evolution continues

Things that caught my eye over the weekend:

Extending import capability. Should imports integrate with the Swift Package Manager and web-based repos? I think they should! Could they include pick-and-choose members using whitelists and blacklists for inclusion and exclusion?  It’s intriguing but I’m not entirely sold on this. Robert Widmann got the conversation rolling on more nuanced import statements.

Growing from other languages. Other language features continue to pop-up on-list, especially from Rust, Haskell, Scala, Ruby, and the like. It will be interesting to see which make it into the standard library and whether there might be separate Rust-like and Ruby-like imports instead of a mega-standard-lib. Lily Ballard has a new proposal for a few useful standard calls.

Naming Overloads. How do you use selectors in an overloaded language, especially when working with currying-like concepts and other Swift-y features? Doug Gregor has a proposal.

Other hot topics continue on-list for a variety of proposals include member-wise initialization for classes (for it! but need to figure out how to establish defaults), method chaining (hopefully this one makes it to the big leagues some day!), the eternal search for a better typealias keyword (“associatedType“. You can bet your hat on it), for better behaved collection enumeration (Nate Cook did a lot on this a few months ago), and whether Swift should be pushing hard-to-type symbol naming like lambdas (it’s coming in updated Set operations by the way — or it will if I am not entirely hallucinating this feature, which I very well may be. Where did I see this? Was a it a pull request?).

Otherwise, most everyone is enjoying the holidays, overloading on the nog, and looking forward to 2016, and to the continuing evolution of Swift.

Swift bracing

By convention, Swift embraces the “One Truce Brace Style” or 1TBS as its standard for laying out code. A variation of K&R bracing, 1TBS adopts the following features:

  • Opening braces appear at the end of the statement that establishes a clause
  • Else statements appear between paired close and open braces
  • All clauses are braced. Single-line clauses use mandatory bracing, just like multi-line clauses. Bracing ensures that all code line insertions will be safely added, and cannot break the intended flow.

A typical Swift if-statement looks like this, incorporating the 1TBS features listed above.

if let value = key {
   // ...do something
} else {
   // ...do something else
}

Xcode automatically styles code using 1TBS and Apple’s sample code and standard library use it as well. Despite this, you can easily override Xcode to incorporate Allman style, also known as “BSD style”.

Unlike 1TBS, Swift Allman wraps its opening brace so there’s always a clear visual path between opening and closing braces. Here is the Allman adaptation of the if-statement you saw previously.

if let value = key
{
   // ...do something
}
else
{
   // ...do something else
}

You can easily trace each opening brace to its closing partner and the else statement sits on its own line.

I mention Allman because Swift is not a language demanding vertical compactness. Clarity and safety should always win over succinct form.  Apple writes,

Clarity is more important than brevity. Although Swift code can be compact, it is a non-goal to enable the smallest possible code with the fewest characters. Brevity in Swift code, where it occurs, is a side-effect of the strong type system and features that naturally reduce boilerplate.

It’s a shame then that the language has adopted 1TBS over Allman when the latter exposes scope so beautifully and the former can be quite hard to follow, especially with respect to complex declarations that include external and internal labels, default values, and other complicating features:

Compare this example in 1TBS:

public extension Contextualizable {
    public func BuildContextError(
        items: Any...,
        file: String = (__FILE__ as NSString).lastPathComponent,
        function: String = __FUNCTION__,
        line: Int = __LINE__
        ) -> CoreError {
        
            let reasons = items.map({"\($0)"}).joinWithSeparator(", ")
            let context = "\(function):\(self.dynamicType):\(file):\(line) "
        
            return CoreError(reasons, context)
    }
}

with its Allman counterpart.

public extension Contextualizable 
{
    public func BuildContextError(
        items: Any...,
        file: String = (__FILE__ as NSString).lastPathComponent,
        function: String = __FUNCTION__,
        line: Int = __LINE__
        ) -> CoreError 
    {
        
        let reasons = items.map({"\($0)"}).joinWithSeparator(", ")
        let context = "\(function):\(self.dynamicType):\(file):\(line) "
        
        return CoreError(reasons, context)
    }
}

The Allman example simplifies the layout, making it far clearer where each declaration (Contextualizable, and BuildContextError) begin and end.

Swift’s worst bracing sin actually appears in switch statements (although get and set for properties are also not without sin). Left-aligned cases and defaults make its switches a horror to scan.

switch item {
case "B", "C", "D": print("Hello")
default: print("World")
}

Bracing also plays an in-line role due to Swift’s functional programming support. An in-line map can appear with or without parentheses (I use the Rule of Lily, which supports parens) and with or without in-brace padding.

This example skips that padding:

items
    .map({"\($0)"})
    .joinWithSeparator(", ")

This example uses padding:

items
    .map({ "\($0)" })
    .joinWithSeparator(", ")

I am currently leaning (slightly) towards the padding side of things although my personal style to date has not incorporated it. This example also uses indented dot-prefixed fluent chaining, although that’s probably a better subject for another post.

 

Clarity and Optional mapping: looking for opinions

A discussion on Swift-Evolution recently verged onto how you cleanly look-up an optional key in a dictionary. That is:

let dict: [SomeType: ...] = ...
let key: SomeType? = someCall()
let value = dictionary[key] but only if key is non-nil

Dave Abrahams pointed out the standard syntax for this query is as follows:

if let value = key.map({ dict[$0] }) {...}
if let value = key.flatMap({dict[$0]}) {...} // thanks @oisdk
// This gist points out the issue with map vs flatMap

This approach uses optional mapping , returning and optionally-binding a value if the key is .Some(...) rather than .None. It’s simple and uses a single binding statement, along with the mapped look-up.

While I applaud parsimony, I can’t help but feel that the following (more verbose) multi-step version is easier to follow with a minimal loss in efficiency:

if let key = key, value = dict[key] {...}

This compound if-let statement optionally-binds the key and then performs the lookup, with a second optional binding. It’s not significantly different in approach from the optional map but it tells the story better. At least to me.

The downside, as Lily Ballard points out,  is that it binds an extra variable. In this case, it’s no big deal as key was already defined as part of the problem statement. But what if you rephrase the call as such:

if let key = foo(), value = dict[key] { ... }

This could potentially shadow an existing variable versus the previous case which does so intentionally. If so, this could cause conflict in the statements in success clause. It’s not a likely scenario but it’s one that should be considered in contrast to the Optional-mapping, which has no such issues:

if let value = foo().map({dict[$0]}) { ... }
if let value = foo().flatMap({dict[$0]}) { ... } // thanks again @oisdk

Even so, I still think the two-stage approach wins in clarity. The functional chaining has become more complex and in real world situations would likely use longer, more-involved symbols. The code is more fluent but also harder to track.

For me, it breaks down into the following questions:

  • Does the Optional map approach produce more efficient code? Slightly
  • Does the Optional map approach more effectively avoid potential errors? Possibly, with unplanned shadowing
  • Does the Optional map approach better communicate the programming story? Not for me, but it may for people more comfortable with thinking “mapping” and “Optional” together.
  • Will the Optional map approach be more maintainable? I don’t think so.

Those are my thoughts. Do you have strong opinions one way or the other?

Creating a Swift Package on github: Not as easy as I thought

When it comes to all things git, I’m useless. This should not be news to anyone.

Package.swift

I thought that setting up a git repo to be used with the package manager would be a no-brainer. After all, consuming a package just means sticking a dependency one-liner into an app package, right?

Here’s the Package.swift file I established, which I thought I’d just compile and use.

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
	.Package(url: "https://github.com/erica/SwiftString.git",
                 majorVersion: 1),
    ]
)

Not so quick.

Git Tags

As I was forced to learn, git tags don’t automatically push forward to github on your behalf. It took me forever until I figured this out, which I did by (finally) cloning a repo and running git tag. There was nothing there.

% git tag
%

And that, in a nutshell, was why all my attempts at building a simple test app ended up in tears and “swift-build: The dependency graph could not be satisfied” (or “satisfed” under earlier Swift builds).

Adding Tags

You add tags by using git tag, e.g.

git tag -a 1.0.0 -m "Version 1.0.0"

You can then see those tags either by using git tag without arguments:

% git tag
1.0.0

or with names (messages):

% git tag -n
1.0.0 Version 1.0.0

Those tags don’t head up to github until they’re pushed:

git push --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 176 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/erica/SwiftString.git
 * [new tag] 1.0.0 -> 1.0.0

Only then will your dependencies, which rely on tag versions, start working.

Lily B adds: “`git push –tags` will push _all_ of your tags. If you only want to push one, you can just list it explicitly, e.g. `git push origin v1.0.0`”

Reading Tags

You can read your tags from the consumer end by hopping into the Packages folder. There you’ll find each dependency with the tag number listed at the end:

% ls
./ ../ SwiftString-1.0.0/

If you enter the package folder, you’ll find the complete repo clone, including all the .git files. There, once again, you can check for the tag and any associated message:

% cd SwiftString-1.0.0/
% ls
./		.git/		Makefile	README.md
../		.gitignore	Package.swift	Sources/
% git tag -n
1.0.0           Version 1.0.0
%

Hopefully this post will save someone the time I wasted today.

Swift Packages, Linux, custom C-code and /usr/local/lib

I spent a few more hours hitting my head against the issue. I still cannot find a way to link using a custom library search path. For now, my Makefile copies my .a file to /usr/local/lib. I consider this a defeat, even though I can now build pure-C libraries and call them from Swift.

% cat Makefile
PKGNAME="CTestPackage"

all: 
	cc -c $(PKGNAME).c -o $(PKGNAME).o
	ar rvs $(PKGNAME).a $(PKGNAME).o
	sudo cp $(PKGNAME).a /usr/local/lib/lib$(PKGNAME).a
	git init ; git add . ; git commit -m "Commit" ; git tag 1.0.0

clean:
	rm -rf .git
	sudo rm /usr/local/lib/lib$(PKGNAME).a
	rm *~ *.[ao]

I’ve tried sneaking flags into the “link” entry for module maps (including -L and -v) and got nowhere. I’ve tried walking through the documentation, trying to find any kind of tweaks around this, but still nothing.

If my intent were to create a re-usable package that’s applicable to multiple projects, /usr/local/lib would be the way to go. Right now, I just want a way to build stuff in C to work around early Swift language limitations on Linux. This means I’m cluttering up a meaningful folder with non-meaningful libraries of temporary code.

Some Linuxy Swift Module goodness

If you substitute the word “hack” for “goodness”, you’re probably closer to the truth. Here’s what I did. Thought I’d share. Caveat programmer/ hackteur.

Building a Custom Module

I created a Packages directory on Ubuntu (/home/erica/Packages). In it I built a TestPackage subdirectory and added TestPackage/Sources, along with a Package.swift file and a Makefile:

% ls
./ ../ Makefile Package.swift Sources/

The text-based Package.swift file specifies the name of the package, and that’s about all. When you make your own module, substitute a different name as needed.

% cat Package.swift 
import PackageDescription

let package = Package(
    name: "TestPackage"
)

I also created a really bottom-of-the-barrel Makefile. You can use this without edits.

all:
	swift build
	git init ; git add . ; git commit -m "Commit" ; git tag 1.0.0

clean:
	rm -rf .build
	rm -rf .git
	rm *~ Sources/*~

Notice how this builds the sources and then establishes a git repo. You need that for accessing the module. I went with a brute force “clean everything, build everything” approach to keep things simple.

Adding Content

In the Sources directory, I built a minimal test file. You can replace this with any file name and file content you want (except main.swift) and can add any number of files as desired for your module.

% ls
./ ../ testpackage.swift
% cat testpackage.swift 
public let testString = "Test Package is Installed"

public func testFunc() -> String {
    return testString
}

Then I ran make in the main TestPackage folder to build the module:

% make
swift build
Compiling Swift Module 'TestPackage' (1 sources)
Linking Library:  .build/debug/TestPackage.a
git init ; git add . ; git commit -m "Commit" ; git tag 1.0.0
Initialized empty Git repository in /home/erica/Packages/TestPackage/.git/
[master (root-commit) 9f41c4e] Commit
 15 files changed, 97 insertions(+)
 create mode 100644 .build/debug/TestPackage.a
 create mode 100644 .build/debug/TestPackage.o/Sources/testpackage.swift.o
 create mode 100644 .build/debug/TestPackage.o/TestPackage/master.swiftdeps
 create mode 100644 .build/debug/TestPackage.o/TestPackage/output-file-map.json
 create mode 100644 .build/debug/TestPackage.o/TestPackage/testpackage.d
 create mode 100644 .build/debug/TestPackage.o/TestPackage/testpackage.swiftdeps
 create mode 100644 .build/debug/TestPackage.o/TestPackage/testpackage~partial.swiftdoc
 create mode 100644 .build/debug/TestPackage.o/TestPackage/testpackage~partial.swiftmodule
 create mode 100644 .build/debug/TestPackage.o/build.db
 create mode 100644 .build/debug/TestPackage.o/llbuild.yaml
 create mode 100644 .build/debug/TestPackage.swiftdoc
 create mode 100644 .build/debug/TestPackage.swiftmodule
 create mode 100644 Makefile
 create mode 100644 Package.swift
 create mode 100644 Sources/testpackage.swift

Consuming a Module

It’s just as simple to build an application that imports and utilizes a Swift module. In my personal Dev folder, I created a new directory. Its  structure is basically identical to the module one:

% ls
./ ../ Makefile Package.swift Sources/

The Makefile here is slightly different, as you see in the following. I decided to name my target “myutility” but obviously, you can change that to whatever name you like. Other than that, you should be able to preserve this as-is.

TARGET=myutility
all:
	swift build

install:
	cp .build/debug/$(TARGET) .

clean :
	rm -rf Packages
	rm -rf .build
	rm *~ Sources/*~ $(TARGET)

The Package.swift file looks like this from the consumer end, using the same target name for the package results. Since this example uses a local module, a dependency url points to the module directory. Make sure that url matches the folder for your module.

% cat Package.swift 
import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
        .Package(url: "/home/erica/Packages/TestPackage", majorVersion:1)
    ]
)

Once again, you can stick anything you like in the Sources folder, but here I went with a main.swift.

% cd Sources
% ls
./  ../  main.swift
% cat main.swift 
import TestPackage

print("About to run tests on TestPackage")
print("Base test string: ", testString)
print("Module-specific test string: ", TestPackage.testString)
print("Test function", testFunc())
%

And go…

To conclude, I built and “installed” the application and ran it.

% make
swift build
Cloning Packages/TestPackage
Using version 1.0.0 of package TestPackage
Compiling Swift Module 'TestPackage' (1 sources)
Linking Library:  .build/debug/TestPackage.a
Compiling Swift Module 'myutility' (1 sources)
Linking Executable:  .build/debug/myutility
% make install
cp .build/debug/myutility .
% ./myutility 
About to run tests on TestPackage
Base test string:  Test Package is Installed
Module-specific test string:  Test Package is Installed
Test function Test Package is Installed

And next?

So I’m still trying to figure out how to build modules around normal C-code that isn’t system provided (that is, through /usr/include, /usr/lib stuff). If you have any tips for creating a basic module around cc -c / ar rvs / etc, please let me know.

I’ll probably hook into the built-in libraries using dependencies but I’d like to write some raw C utilities too.

Update: To be clear, I’m not trying to link to /usr/lib. When I build my own .o/.a files, I cannot get Swift to properly link to them as the search path for libraries doesn’t include local files.