Generics have been something that have confused me a lot in the past when coming from a JavaScript-heavy web development background, so when I came to Swift and started using it as my main language of choice I realized I had a lot to learn (which is never a bad thing).

For those who don't know, languages such a JavaScript, Ruby, and Python are dynamically typed languages. This means that the type of a variable is deduced by the system at runtime and (supposedly) makes the life of a developer easier because you don't have to specify a variable's type in code. Languages such as Swift, C, and Kotlin are statically typed languages which means the opposite. You have to specify the type of a variable and that variable's type is not allowed to change in its lifetime or the compiler will complain.

But what about when you have an object such as an array, where neither you or the compiler know what type is going to go into it? That's where generics come in.

Big Nerd Ranch's book Swift Programming describes generics in the following way:

Swift generics allow you to write types and functions that use types that are not yet known to you or the compiler. Many of the built-in types including optionals, arrays, and dictionaries, are implemented using generics.

So what does the concept of a generic look like? Let's look at this example from Apple's documentation:

struct IntStack {
    var items = [Int]()
    mutating func push(_ item: Int) {
        items.append(item)
    }
    mutating func pop() -> Int {
        return items.removeLast()
    }
}

This a just a basic stack struct. It's a struct that holds integers and allows you to both push and pop items out of it. It's nothing special. But what sucks is that if we implement our stack in this way we'll only ever be able to handle integers!

Here's how we would use this stack:

var myIntegerStack = IntStack()
myIntegerStack.push(1)
myIntegerStack.push(2)
myIntegerStack.pop() // returns 2
myIntegerStack.pop() // returns 1

Now let's see what we can do by making this stack generic!

struct Stack<Element> {
    var items = [Element]()
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
}

My replacing instances of Int with Element and changing the struct's definition from struct IntStack to struct Stack<Element>, we've made our stack generic. Technically, we've made our stack generic over Element. Now we're not restricted to just using our stack with integers. Here's how we could use it now:

var myIntegerStack = Stack<Int>()
myIntegerStack.push(1)
myIntegerStack.push(2)
myIntegerStack.pop() // returns 2
myIntegerStack.pop() // returns 1

var myStringStack = Stack<String>()
myIntegerStack.push("A")
myIntegerStack.push("B")
myIntegerStack.pop() // returns "B"
myIntegerStack.pop() // returns "A"

But where would we use something like this? For one, generics are used all over Core Data. It makes sense, because we're using a lot of the same methods, functions, and classes over different entities. We could also use it in a messaging service where we could have queues that could each handle emails, text messages, and Facebook messages whose objects representing them each conform to a messaging protocol. That's just an idea that came up off the top of my head, and we're just touching the tip of the iceberg in regards to generics.

This is the first in a three part series that I'm writing about generics. Next time, we're going to cover generic methods and functions!