Value types and reference types in Swift involve different approaches to memory management: value types are implicitly copied while reference types only change their reference count when passed around. Without proper care, it's easy to create reference cycles which cause memory leaks. You might be tempted to avoid classes and stick to value types altogether to avoid that and get immutability guarantees as a nice bonus, right? Not so fast, there might be more problems than one could anticipate!
Did you ever need to parse an Excel spreadsheet on iOS, macOS or Linux in Swift? Turns out it’s easier to implement than one would expect, especially with the help of Swift's great
Codable protocols. The resulting library is open-source and is available on GitHub.
We know that generators produce output by passing arguments to the `yield` statement. I also mentioned previously it would be great if generators could also consume input. Turns out, a generator is a special case of a coroutine, coroutines are more powerful generators that can consume values. How would that work? Would that be useful at all? To answer these questions, we need to have a closer look at how we interact with generators and coroutines.
Every time I come back to Swift, there is one big feature I miss called "generators". Whether you've used generators and `yield` keyword before in other languages, or you are only interested to learn about it, you might find this short pitch interesting. Here I try to imagine how generators could look in Swift and what are the implications.
Have you ever used an app that felt unresponsive? Not reacting to input on time, slow animations even for some simple tasks, even when there isn't anything heavy running in the background? Most probably, an app like that is waiting for some blocking long-running computation to finish before consuming more user input or rendering animation frames. Scheduling all workloads correctly and in the right order might seem hard, especially as there are different approaches to choose from.
In software engineering and computer science, we constantly deal with layers of abstractions, but we don't cross too many of them on daily basis. Here's an abstraction that developers work with a lot: asynchronous computations. These days it's hard to write code that doesn't touch something asynchronous: any kind of I/O, most frequently networking, or maybe long-running tasks that are scheduled on different threads/processes. For something more concrete, consider a database query, which could be local disk I/O or something that sits somewhere on the network. In most cases like this you'd need to use closures or build something more powerful on top of it.
Recently I had a chance to develop and to run in production a few mobile and web apps built with GraphQL APIs, both for my own projects and my clients. This has been a really good experience, not least thanks to wonderful PostGraphile and Apollo libraries. At this point, it's quite hard for me to come back and enjoy working with REST.
But obviously, this needs a little explanation.