Metal is fairly specialized knowledge partially due to it being a proprietary API only available on Apple platforms. Furthermore, most Apple developers use higher level frameworks for drawing to the screen, so there is not a huge demand for tutorials or books about Metal.

Still, there are a few resources which are available:

There are also samples and other notes in Apple’s archived documentation. Metal usually has at least 3 WWDC sessions every year so it is still an evolving technology that Apple is investing in.

Also, I’ve found 3 books related to Metal:

If I were to choose one, I would pick Metal by Tutorials. It gives the basic information to start building many game rendering engine features. The book can be a bit overwhelming because it usually gives a brief introduction to a rendering engine concept and then shows a code example through a mini-project. However, if you do not understand the concept, it can be hard to follow the code, so you may need to use other resources. The book does provide other references for further reading. The book has been recently updated for Metal advancements up to iOS 13 in 2019.

I hope to have a more robust list of math and general graphics programming books in a future blog post.

One of my relatively recent interests is GPU programming. Graphics programming has always fascinated me because there has been this other part of any modern computer which was kind of like the CPU but had its own unique way to process data. Whether the GPU is part of an integrated system on a chip or a discrete chip with its own memory, the GPU can efficiently process large amounts of data in parallel. However, for most programmers, the GPU is rarely directly used because their problem domains are not suitable for the type of parallel processing which the GPU is great at.

So why do I have a recent interest in GPUs? My theory is that GPUs may play a bigger role in the next generation of devices capable of features like AR. Parallel data processing whether it be displaying and manipulating image data on a screen or running machine learning algorithms to recognize hand gestures or your voice will all utilize the GPU or similar processors. Of course, GPUs will still be specialized domain knowledge, and there will be many libraries and off the shelf tools and engines which more people will use rather than directly programming to the GPU. The market for programming web services will always be orders of magnitude greater than graphics programming. But sometimes it is good to work with some of the more foundational API layers and somewhat closer to the hardware. Plus, unlike most business logic programming, if you learn graphics programming, you can output something pretty versus some histogram or bar chart.

In particular, I am trying to learn Metal, Apple’s low level API for GPU programming. Metal powers all of Apple’s platforms. For instance, most of Apple’s UI and game frameworks use Metal. I’m picking up Metal more due to practicality since I have many Apple devices, and Metal is the preferred way to access the GPU. DirectX and Vulkan would also be equally nice to learn but are unavailable or unsupported on Apple platforms.

As an aside, for browsers, WebGL is fine but due to it evolving from OpenGL ES, the API seems like a couple of generations behind. If you are interested in WebGL and new (or need a refresher) to graphics programming, I recommend the WebGL Programming Guide book. The book requires only basic JavaScript knowledge, and it gives enough to jump start simple rendering projects. I picked up the WebGL book after reading a few chapters in a couple of Metal books because the Metal programming was already becoming complicated and I wanted to see how it was in WebGL for comparison. From my very brief foray, WebGL is capable but a bit awkward (e.g. setting up the shaders is cumbersome); WebGL made me appreciate Metal more. Maybe WebGPU will be better.

In the end, I expect to stumble quite a bit since this is largely a new domain for me. As I progress through some books and projects, I will try to blog a bit about what I’ve learned along the way.

Protocol oriented programming is a programming paradiagm promoted by Swift developers. Coming from a Java or Objective-C background, interfaces are a core language feature used by practically every developer. Protocols are very similar to interfaces, and it is quite easy to dismiss “protocol oriented programming” as just interface oriented programming.

In many ways, protocols are basically interfaces (or traits in Rust), so the core ideas are the same. However, one of the biggest differences is the addition of the ability to retrofit conformance of existing types to new protocols/traits and generic language features. It may muddle the argument that protocol oriented programming is unique due to other language features not named protocol.

Taking a step back, the use of interfaces is primarily applicable when code is interacting between two separate parties (say a framework/library and application code). Using interfaces allows flexibility for method inputs in comparison to concrete implementations such as classes or structs. While interfaces are extremely helpful, the end goal is integrating the code. Protocol oriented programming expands on the toolset to make code integrations easier.

Here’s an example of how protocol oriented programming iterates over interface based programming.

Type Extensions

Type extensions allow anyone to add methods to an existing type with a few restrictions.

Suppose there’s an Entity protocol which declares a name function which returns the name of the entity. Also, there’s a simple function which prints hello with the entity’s name. Both exist in a third party library.

protocol Entity {
  func name() -> String
}

func sayHello(subject: Entity) {
  print("Hello \(subject.name())")
}

If you replace protocol with interface (and some language syntax changes), there does not seem to be any difference between protocols and interfaces.

However, let’s say you have an existing Person type which you wish to pass to the sayHello function.

class Person {
  func firstName() -> String {
    return "Jane"
  }

  func lastName() -> String {
    return "Doe"
  }
}

Now, instead of having to create a wrapper type, you can simply add an extension which makes Person conform to the Entity protocol.

extension Person: Entity {
  func name() -> String {
    return "\(self.firstName()) \(self.lastName())"
  }
}

It could be argued that this is just language syntax sugar and writing a wrapper type is easier. Ultimately it depends on the complexity of the protocol and how you use the underlying instance. If you need to convert between types often and depending on how your compiler can treat the wrapping type, there are drawbacks to wrapper types.

Generics

Generics allow expressive function and type declarations which empower the compiler to better type check the code as well as potentially generate better performing code (aka “generic specialization”).

Following the above examples, the sayHello function can be changed to use a generic type.

func sayHello<T>(subject: T) where T: Entity {
  print("Hello \(subject.name())")
}

While the above example is a trivial use of generics, it allows some compilers to determine if it should create a specific version of the function for every specific type of Entity which is used. So there could be a version of sayHello for the Person type. If there was a Robot type which conformed to the Entity protocol, the compiler may generate machine code for both Person and Robot. The type specific machine code could be faster by directly invoking type specific methods rather than going through the Entity protocol via a lookup table (e.g. vtables).

In a more realistic generic function, the function could guarantee that two parameters are the same type while implementing the same interface(s). A common example is a comparision function which usually is used in more performance demanding code.

Library-Application Integration Reversal

But perhaps you do not care about the convenience of type extensions or the improvements from generics because you control your application code. Afterall, you can easily just open up your class and add the : Entity to cause your Person type to conform to Entity.

Applications call library code and it is generally presumed that libraries should be the party that uses interfaces as library inputs. In reality, the integating code goes both ways. The library code may return concrete or interface types (which cannot be changed by the application code author). Then, the library’s concrete types and interfaces are used like other types which were created in the application code base.

In some sense, the library’s type definitions have polluted the application’s code base. If the library were to change its types/method names or make other breaking changes, the changes could drastically affect the application code base.

For instance, suppose you are writing a web application and are getting query parameters and header values off the HTTP request. The web framework has a standard Request type which provides access to all the properties of an HTTP request. Your function needs to retrieve the name parameter off the request like:

func sayHello(req: Request) {
  print("Hello \(req.getQueryParameter("name"))")
}

The Request library type is now part of your application code. While the above is simple, imagine library types which might be passed throughout functions defined in the application.

The use of type extensions and interfaces/protocols defined in the application code base can negate the impact.

You could declare a EntityParameter protocol, and use type extensions to retroactively conform Request like:

protocol EntityParameter {
  func name() -> String?
}

extension Request: EntityParameter {
  func name() -> String? {
    return self.getQueryParameter("name")
  }
}

func sayHello(subject: EntityParameter) {
  print("Hello \(subject.name())")
}

let incomingRequest: Request = // given by the framework
sayHello(subject: incomingRequest)

Now your function can take a type which implements EntityParameter. The dependence on the library code is less. Furthermore, the function is more easily testable since you can easily create a stub which implements EntityParameter.

The goal of the code above could be accomplished with interfaces and wrapper types (e.g. a new application type which delegates to the Request type and which implements EntityParmeter). I would argue that type extensions require less code. Again, generics can help ensure expressiveness with type safety while improving performance.

Iteratively improving code integrations

In the end, conceptually, “protocol oriented programming” may not be significantly different than programming with interfaces in mind. However, the addition of type extensions and generics make programming with protocols/interfaces more pleasant and can help separately developed code bases evolve together.