Apous – Swift Script Package Manager

So I've had this project on my mind for a few months now: Swift script management system. While I was doing the planning for it, I was dreaming big… like how could we replicate the Python system.

That's a lot of work though… and I had other things going on. And really, who would want to use it besides just me?

Then I saw this talk by Ayaka Nonaka and thought to myself, "OK, maybe people would actually like to have something like this."

Instead of going big, I figure I'd just start small and do it the hackiest way possible: concat files together and call it good!

So if you're looking for a way to write Swift scripts and manageme dependencies, check out Apous.

Apous – Swift Script Package Manager

‘RE: Should I use a Swift struct or a class?’

There is a post about using structs or classes in Swift here: Should I use a Swift struct or a class?. If you like functional programming or reducing state mutations, be warned, it's somewhat antagonistic to your position.

The fundamental problem I find with the piece is that it creates a false selection of choices to the problem statement posed while misrepresenting much of the advice about chosing when to use value types. I think it also confuses the purpose of the proposed "inner class device".

1. We have a protocol defined as:

protocol CanSend {
    typealias Message
    func send(messgage: Message) throws
}

2. We need to implement this protocol in two manners: one that mutates and one that does not.

Specifically, the desire is to create a MockServer<T> that can be used to keep track of state for testing. Ok, this sounds reasonable. So the following is presented:

struct MockSender<T> {
    var sentMessages: [T] = [] //you inspect this property to study 
    //what messages were previously sent for unit test purposes
}

extension MockSender : CanSend {
    typealias Message = T
    func send(message: T) {
        self.sentMessages.append(message) //error: Immutable value 
        //of type '[T]' only has mutating members named append
    }
}

This, as pointed out, does in fact present a problem. The protocol function send is not marked as mutating yet the implementation clearly attempts to mutate itself.

However, this is the conclusion that is drawn:

Right, so the problem is our protocol says the function is non-mutating, but in reality it needs to be mutating.

So we go change the protocol, right? I mean after all, by definition this program has no legacy code, so we can structure the protocol however we want.

After some clammering about how this is the wrong approach, which I agree, there is no need to mark the function as mutating, we get to this conclusion:

We can solve this problem with a device called an "inner class", which you probably have already seen, but if you haven't just imagine that there is some god-awful way to create a mutating implementation of a non-mutating func, and we will cover the details later.

This, is actually the wrong conclusion. The entire purpose of the "inner class" is to provide value semantics while maintaining effeciency of implementation. In addition to that, if some of the quoted advice in the article had been followed with regards to struct usage, a different conclusion would have presented itself. Let's look at this piece of advice:

Don't use classes when structs will do. Use classes if you want reference types. Use structs if you want value types. You can add functionality to both (and to enumerations) in Swift. When in doubt, err on the side of value types. If your construct doesn't have a life cycle, or two constructs with similar values should be considered as the same thing, use a struct. (Do take advantage of Swift structs. They're neat.)

I emphasized the interesting bit from there.

You see, MockSender<T> does indeed have a lifecycle; it has a history of all messages sent that varies over time.

Also, this piece of advice:

Unless you require functionality that can only be provided by a class (like identity or deinitializers), implement a struct instead… Rationale: Value types are simpler, easier to reason about, and behave as expected with the let keyword.

In addition to that, we have a protocol in which we do not want to enforce a mutation contract across all conforming types. A class provides us the functionality that only it provides. So why not simply follow the advice and create this version instead?

{} class MockSender

var sentMessages: [T] = []

}

extension MockSender : CanSend

typealias Message = T
func send(message: T) {
    self.sentMessages.append(message)
}

}

This solution does exactly what we want. It also does it by maintaining the protocol can be conformed by immutable value-types and my mutable reference types. This is a validation of the "Structs Philosophy‚Ñ¢"; `MockServer<T> is not a value-type, don't try and make it one. 

The problem with the first example is that, in my opinion, the author conflated two separate things: the desire to create a value type and the usage of inner classes in value types for performance reasons. If, we really wanted immutable value-types from the protocol and allow state changes, the protocol should have been defined as such:

protocol CanSend

typealias Message
func send(messgage: Message) throws -> Self

}

The weird part about the piece is that we end with the conclusion that we should have just started with, and that conclusion isn't in disagreement to much of the advice out there about starting with a struct and move to a class when/if necessary: 

> In all other cases, define a class, and create instances of that class to be managed and passed by reference. In practice, this means that most custom data constructs should be classes, not structures.

So...

 - Yes, make your `MockServer<T>` a class.
 - No, do **not** write the "struct with inner class wrapper" so you can simply make it pseudo-mutable.
 - You should still start with the question: is my type a value-type or a reference type? This is also the advice from Apple.

 **Update Sunday, July 5th @ 4:03PM**
 Here's a follow-up [conversation thread](https://gist.github.com/drewcrawford/752b2bfef7d8574eab01).
‘RE: Should I use a Swift struct or a class?’

Swift’s Scripting Is Not Magical

Ever since Swift has debuted, there's been a bit of a fuss about how it can be used for scripting. Yes, yes it can, but so can every other language that has an interpreter, or more accurately, a binary that can do something with the input file.

In fact, we can even make such a thing for C.

Here is what our little "c script" will look like.

#!/path/to/cscript

#include <stdio.h>

int main() {
    printf("I want to be a cool kid too!\n");
}

Now, the astute among you may have noticed something… the magic SHEBANG (#!) is, well, it is currently pointing to some magic place.

I've actually created a little tool to help us out (of course it's in Swift!).

import Foundation

let path = NSProcessInfo.processInfo().arguments[1]
let code = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)

let newCode = code
    .componentsSeparatedByString("\n")
    .filter { $0.rangeOfString("#!/") == nil }
    .reduce("") { $0 + $1 + "\n" }

try newCode.writeToFile("_script.c", atomically: true, encoding: NSUTF8StringEncoding)

var task = NSTask()
task.arguments = [ "_script.c", "-o", "_script" ]
task.launchPath = "/usr/bin/clang"
task.standardOutput = NSFileHandle.fileHandleWithStandardOutput()
task.standardError = NSFileHandle.fileHandleWithStandardError()

task.launch()
task.waitUntilExit()

var script = NSTask()
script.launchPath = "_script"
script.standardOutput = NSFileHandle.fileHandleWithStandardOutput()
script.standardError = NSFileHandle.fileHandleWithStandardError()
script.launch()
script.waitUntilExit()

try NSFileManager.defaultManager().removeItemAtPath("_script.c")
try NSFileManager.defaultManager().removeItemAtPath("_script")

First, compile that Swift code into an executable cscript. Next, modify the #! reference in your C source to point to this new cscript tool. Finally, be sure to chmod +x on the

"c script" file.

Then, it's simply a matter of running it like any other script:

> ./script.c
I want to be a cool kid too!

Anyhow, I just wanted to point out that this is not some black-magic that Swift is doing; it is simply a by-product of the Swift REPL environment. This is just one of the great things about our lovely OS X being backed by a unixy foundation.

Swift’s Scripting Is Not Magical