Swift is Afraid of Possession

To continue with the “translation” which was deemed too complex for that initial effort, let’s write the Swift necessary to represent this English:

Jim, give Jill your dog.

Global function: 

func give(item: Any, to receiver: Person, giver: Person)

Method (for Person): 

func give(item: Any, to receiver: Person)

Hooray for internal and external parameter names! The corresponding generic English sentences don’t look that bad:

Give item to receiver, giver.
Person, give item to receiver.

However, we see in practice that they don’t support English to its fullest capacity:

Global Swift: give(jim.dog, to: jill, jim)
Object-oriented (OO) Swift: jim.give(jim.dog, to: Jill)

Global English: Give Jim’s dog to Jill, Jim.
OO English: Jim, give Jim’s dog to Jill.

The global functions and methods are so similar that I’ll just use methods until the end of this post.

Closures enable possessive determiners, but only via your imagination

My first impression was that “your”, a possessive determiner (aka possessive adjective), adds a useful constraint to the original English: that the dog to be given initially belongs to the giver. Let’s work on enforcing that constraint:

func give(getMyItemToGive: Person -> Any, to receiver: Person)

The intention of the closure is clear, but only via a prolix parameter name. There’s not actually any mechanism in place for guaranteeing that the given item is the giver’s, or even a person’s, for that matter.

Journey into Imagination

Using closures are possessive determiners requires a journey into imagination.

WTF is $?

$ means dollar. I don’t like seeing it in code; the only reason programming language designers ever used it is because you can see it on your keyboard. This solution is not, in the parlance of our times, money.concernedHopefully, shorthand syntax gets better, because it does allow us to be concise:

jim.give({$0.dog}, to: Jill)

$0, in this case, means you, and the dot operator is an apostrophe:

Jim, give you’s dog to Jill.

Close enough! happy-wink

However, although we know, reading this article, what {$0.dog} represents, the clarity achieved in the function signature is lost, so without referring to the function declaration, it’s not 100% clear if $0 represents Jim, Jill, or anything else that could have a dog.

We could use the signature’s parameter names when calling the function, but it doesn’t translate to how we speak:

jim.give(getMyItemToGive: {$0.dog}, to: Jill)

Alternatively, we could avoid using shorthand parameter names, which looks less like “code”, but actually maps more poorly to English:

jim.give({you in you.dog}, to: Jill)

I don’t like any of these solutions, but it gets even worse, in practice…

What might give‘s body look like?

func give<T>(
    getMyItemToGive: Person -> T,
    to receiver: Person,
    setItemToGive: (Person, T) -> ()
) {
    setItemToGive(receiver, getMyItemToGive(self))
    setItemToGive(self, nil)

Invocation options:

jim.give({you in you.dog}, to: jill) {(person, dog) in person.dog = dog}
jim.give({$0.dog}, to: jill) {$0.dog = $1}
Smelly Ghost Code

Who you gonna call when your smelly code needs its trap shut?

Why is passing a property around so horrible?

Before we can teach Swift about the concept of one parameter belonging to another, it needs to learn that a parameter can own something, period. Passing around getters and setters, as two delegates (C#) or closures (Swift), instead of a wrapper around the concept of a property, is a problem that I’m dismayed hasn’t been solved already.

func give(item: Person's Any, to receiver: Person) {
    receiver's item = item
    self's item = nil

jim.give(dog, to: jill)

I came up with other syntax ideas, that involved the dot, and angle brackets, but I don’t see why we can’t just use apostrophe s. As always, I welcome your thoughts and refinements.

With references to properties, as parameters, taken care of, we can finish up possessive determiner support. However, I find that I’m almost happy with the English that corresponds to that last pseudo-neo-Swift line:

Jim, give dog to Jill.

Without any more context, that sounds fine to me. My mind’s ear just hears it with a Russian accent.

Still, our IDE could provide credence as to whose dog we are giving, without us having to have any more text in our code. We’d just need help the IDE out, in our function signatures.

func give(item: self's Any, to receiver: Person) {
    receiver's item = item
    self's item = nil
func give(your item: giver's Any, to receiver: Person, giver: Person)

dog is jims



Leave a Reply

Your email address will not be published. Required fields are marked *