More Methods and Functions
In the previous post I looked at traditional ways of representing functions and asked how we might appropriately represent methods.
With map()
, for example, Swift used to implement it as a free function. map()
on Array
had to accept both the Array
it was acting on as well as the function it was applying to every element of the Array
. The signature was something like this.
func map<Input, Output>(_ array: [Input],
using transform: (Input) -> Output) -> [Output]
We would call it like this.
map(myArrayOfStrings){string in string.count}
This is the rectangle shape with the funnel at the top where we dump in the Array
of String
s and the function and with the funnel at the bottom that returns an Array
of Int
s. So …
map(["Where", "are", "the", "drawings"]){string in string.count}
returns [5, 3, 3, 8]
.
In Swift 2 we got protocol extensions and map()
for Array
s was implemented in Sequence
. Forget about the throws
and rethrows
, this signature was essentially the following.
func map<Output>(_ transform: (Element) -> Output) -> [Output]
We no longer needed to specify the generic type of the input Array
as map()
is a member and knows the type is Element
.
We also no longer needed to pass in the starting Array
as map()
has access to everything in self
. So here’s how we call this map()
.
["Where", "are", "the", "drawings"].map{string in string.count}
I experimented with many ways of representing methods and asked for suggestions
Jordan Rose suggested two. One was cartoon style conversation bubbles - which I love. I include these in my talks to allow the code to talk back to me.
His other suggestion (included with his permission) looks like this.
I really like this idea. It feels like the dot notation and communicates input from two directions: one from self
and one from the parameters being passed. It also separates these information origins nicely and allows us to chain methods.
This chain was emphasized by the second drawing I was sent.
Lars Christiansen sent me this image of a train. (Also included with permission)
In the second car we see a method that receives its input from the car before and takes no additional parameters. In the next car we see a method that requires both the car before it and additional information for the amount we are increasing by.
Again I love this idea. It’s a simple way to communicate what’s going on.
It also fits nicely with a train-track approach that Scott Wlaschin uses in his wonderful F# talks and writing that you can find on fsharpforfunandprofit.com
Scott gives engaging talks on Functional Programming and uses train tracks to communicate concepts such as map and flatMap.
So I’ve been thinking about drawing comics to illustrate some programming concepts.
Just another medium for communication.
So I’ve been adding ABDCE’s to my Functional Programming Kickstart where ABDCE is “A Badly Drawn Comic Explanation”.
For now I’m using Comic Life 3 and essentially drawing with their basic shapes. Here’s my attempt at functions and methods.
I’m also taking some sketching classes and cartooning classes and hope to replace these with even more poorly drawn comics.
We’ll see how it goes.