Practical Covariance and Contravariance

For a more in-depth rundown on covariance and contravariance explained in terms of category theory have a look at Thomas Patricek’s blog

Covariance and contravariance are things you’ll probably ignore until you start using generics in ernest. Then one day you’ll want to pass an enumerable to a function that takes a slightly different yet related type of enumerable and then BAM – you’re hit with some crazy error messages and then all of a sudden you’re up to your elbows in browser tabs of StackOverflow articles.

To cut straight to the chase, this is the problem:

1
2
Base rawBase = new Derived(); // this works
MyType<Base> wrappedBase = new MyType<Derived>(); // ERROR!

Sometimes we want the OO polymorphism substitution rules (AKA Liskov’s substitution principle) to apply to generic types too. Covariance and contravariance provide us a mechanism to allow this substitution to take place.

To be more specific, [co|contra]variance are necessitated due to the interaction of two different forms of polymorphism – object inheritance and generic typing. And yet sometimes you want to combine the two – while MyType<T> and MyType<U> share no inheritance relationship and therefore are not substitutable for each other, sometimes you want to treat them as if they are substitutable if T and U are themselves related.

So a covariant or contravariant generic type (e.g., a IEnumerable<T>) might be bound to other references of that type (e.g., IEnumerable<U>) when there is an inheritance relationship between the two predicated types. This allows you to pass your IEnumerable<Employee> to a function that actually accepts an IEnumerable<Person> without the compiler complaining that they are different types.

The rule of thumb with inheritance is that if U inherits from T you could say that U is-a-kind-of T. With covariant and contravariant types, I like to think of them in terms of can-be-used-as-a relationship. To determine if MyType should be covariant or contravariant you could ask if Dog is-a-kind-of Animal, is it true that MyType<Dog> can-be-used-as-a MyType<Animal>?

Covariance and contravariance are two different ways that differently specialised generic types should themselves be substitutable for each other like derived types are:

Covariance: MyType<T> is covariant if typing MyType<Base> x = new MyType<Derived>() makes sense (this looks very much like standard substitution rules.)

An example of this is an IEnumerable-derived type, and is classified as having methods that return the predicated type, or getters (hence C# uses the out keyword.)

The implication is that the relationship between the covariant generic types is the same as the relationship between their predicated types, e.g.:

1
2
3
4
5
Base b = new Derived(); // OK because of Liskov substitution

IEnumerable<Derived> ds = new List<Derived>();
IEnumerable<Base> bs = ds; // OK because IEnumerable is covariant
Base first = bs.First();

Contravariance: MyType<T> is contravariant if typing MyType<Derived> x = new MyType<Base>() makes sense.

An example of this is the .Net generic Action type, and is classified as having methods that accept the predicated type as a parameter, or setters (hence C# uses the in keyword.)

Contravariant types are probably less common than covariant types, and imply that the relationship between the generic types is the inverse of the relationship between their predicated types. E.g.:

1
2
3
Action<Base> b = _ => {};
Action<Derived> d = b; // OK because Action is contravariant
d.Invoke(new Derived()); // invoke alias 'd', actually invokes 'b'
Read on →
Comments

An Introduction to OpenGL - Getting Started

This article is a culmination of all the little notes I took while learning OpenGL over the last several months. It’s mostly stuff that I found difficult to research plus a little summary of the differences between OpenGL versions.

What a daunting task!

If you have any recommendations on how this could be more beginner-friendly please tell me.

Also thanks Gregg Tavares for pointing out my various errors!

Things I wish I knew when learning OpenGL

The most important thing a programmer should know before deciding whether to learn OpenGL is that OpenGL is very low level, poorly documented and extremely crufty. This is because it is an API specification and not a product library per-se. It is up to the many various vendors to implement the API spec as best they can.

In its various incarnations OpenGL spans almost 20 years and at least 7 major revisions, including the embedded versions. Anyone looking to learn to use OpenGL will face a constant battle with finding relevant documentation for their chosen version on their chosen platform with their chosen extensions.

The next thing to know about modern OpenGL is that these days it does very little legwork for you other than allowing you to run a program on the GPU. You will have to write the GPU shader programs that do everything from transforming your own application data into screen-space coordinates, to calculating the exact colour of every pixel on the screen incorporating lighting and shading algorithms that you implement yourself (fortunately linear algebra makes this stuff a lot simpler than it sounds!) So OpenGL will not do any inherently 3D stuff for you – most OpenGL commands and types are capable of describing 3D positions, directions and transformations but you have to do the grunt work yourself.

The third immediate concern – OpenGL does not work out of the box! An annoying truth is that OpenGL realistically requires supporting libraries in order to function, most importantly to create a context within which the rendering operations can work. It is very common to incorporating at least three libraries – one to generate a GL context into which you render, a matrix and vector manipulation library, and an extension loader for when you need a little more functionality than your platform provides.

So why would you even consider it?! Why would you write a series of articles on a technology that scares you so much? The reason it has kept its relevance is because OpenGL is the only low-level graphics API supported on pretty much all platforms you’d want to render graphics on. Because it is so very widely adopted it is still the defacto standard for developers wanting a powerful low-level intrinsics that work on multiple platforms.

If you are only targeting Windows you might consider DirectX. If you don’t need to interact directly with your shaders, and are happy to work at a higher level of abstraction and not with the GPU directly, perhaps a higher level graphics library such as Unity or UDK would work better for you.

So assuming you still want to start using OpenGL, this article might be helpful to you. My intention is to mention a lot of stuff I had to hunt around for that seemed pretty important to me while I was trying to learn it myself. I will not be doing a step-by-step guide to performing specific OpenGL tasks however – for a good getting started guide check out open.gl which is both modern and easy to follow.

To use OpenGL effectively I figure you’d need to understand:

  • opening an OpenGL window (i.e., creating a context)
  • the basics of rendering:
    • primitives, vertices and fragments
    • coordinate systems:
      • built-in normalised device coordinates (NDC) and clip coordinates
      • 3D model, view and perspective coordinates
    • shaders and the render pipeline (how data gets from your app to the screen):
      • vertex and fragment shaders
      • passing uniforms and attributes into the pipeline
      • vertex buffers (VBOs)
      • passing varying data from the vertex shader to the fragment shader
    • the fixed-function pipeline (now deprecated)
  • linear algebra (the magical language of graphics programming)
  • a rundown on all the different major OpenGL versions
  • major challenges that you certainly will face moving forward

I’ll leave more advanced core concepts such as framebuffers and textures for a later article.

Read on →
Comments

Week in Review: Back From My Hiatus (From My Hiatus)

In September I went to Spain for 6 weeks to chill out with my family and check out what the countryside had to offer. Then I moved from Japan to Australia and got caught up in the Christams spirit. So although I have done some stuff (below) I have not made much progress on any big projects in the last few months…

BUT I have done a lot. Below the fold I talk about starting a C++ OpenGL library, creating some nicer OpenGL documentation, learning Blender 3D, setting up a new computer and moving country.

On the side I’ve been helping a mate out set up an e-commerce site for his new Japanese brewery – more information to come when it is released in a few months!

Read on →
Comments

C++11/14 Idioms I Use Every Day

if you want to see a bunch of people complaining about my rules regarding auto, have a look at HackerNews and Reddit

Most attention on the new C++ has focused on the changes that provide functionality and performance that was previously not possible, both library enhancements (chrono, regex, smart pointers, and stuff to help with lambdas for example) and core language enhancements (perfect forwarding, variadic templates, the new memory model and threading capabilities, initialiser lists and the like). This functionality will impact us all in helping to write more correct code and efficient libraries, but often will only be relevant in certain parts of our code.

But the first thing that struck me when I started using C++11 was the smaller features that I could take advantage of every time I put my fingers to the keyboard. These are the things that make code more concise and simple and allow me to present my intentions more clearly.

Stuff I take advantage of every day:

  • more concise general coding:
    • lambdas for scoped initialisation or inline ‘builder’ functions
    • new standard library functionality for string manipulation, particularly std::to_string() and std::stoi() etc
    • range-based for loop
  • clearer declarations:
    • inline member initialisation,
    • the override, default and delete keywords
    • delegating constructors,
    • uniform initialisation, especially when invoking or returning from functions
    • auto type deduction everywhere!
  • far fewer dependencies on boost

These are the things I think all C++ programmers should learn first, because they benefit you straight away and confer very little risk of being learned wrong.

At the very end I also mention a few upcoming features that I’m really excited about as they will be game-changers.

Read on →
C++
Comments

C++ Trick: Use Make Without Makefiles

I use CMake personally because managing Makefiles is a hassle. However, I still use make regularly for one purpose: to easily create quick apps without setting up any projects or infrastructure at all. I have no idea where I first heard about this trick, and I can find very little referring to it on the internet. I recently found out that most people didn’t know about it though, so I thought I’d put a bit of info up here so others can benefit from it.

Generally when using C++ in an IDE it can be a hassle to create a small test application for, say, verifying a new language feature works the way you think it does, or creating a test bed to create a self-contained but complicated algorithm. In such cases, when I am using an OS that supports make, I generally do this:

1
2
3
4
5
vim blah.cpp
# write your small app
make blah
# make magically runs 'c++ tmp.cpp -o tmp'
./blah

… and that’s it. It turns out make, when no makefile is present, will try a bunch of stuff that includes searching for .c and .cpp candidate files for generating your target. If the target (in this case ‘blah’) ended instead in .o it would sensibly generate an object file without linking it into an executable!

There is no easy way to make it automatically detect dependencies and include them, so all your source has to be within that one file. But there are some further tricks you can do…

Compilation options

By default on my OSX at the moment, make will call my CLang compiler:

1
2
3
echo "int main() {}" > tmp.cpp
make tmp
# c++ tmp.cpp -o tmp

But without any special flags, CLang will compile without C++14 support, which I really want!

An easy workaround to this is to set your CXXFLAGS environment variable that contains the flags you always want to be passed to your C++ compiler by default. In my machine I have added to my ~/.bash_profile file: CXXFLAGS='-std=c++1y -stdlib=libc++'. Now when I run this command I get:

1
2
make tmp
# c++ -std=c++1y -stdlib=libc++    tmp.cpp   -o tmp

Thats pretty cool. Of course you can set any of make’s implicit variables to ensure your app is built with these flags by default. For example, the compiler can be changed to GCC by setting CXX=gcc.

You can also include default include paths and libraries to link against, so that your small apps are able to incorporate boost or even your own library that you are developing.

Comments

Swift: A Solid Modern Imperative Language

Note 1: these are first impressions only – I’ve only spent a day really looking at the docs and playing with the XCode beta so I am probably mistaken about some stuff

Note 2: I am using a beta of XCode, and it has caused me some trouble (a mysterious service it starts keeps crashing, filling my HDD up with core files.) I would recommend waiting for the non-beta if I were you.

Apple recently announced the support of a new language targeted at the same application programming space as Objective C. It’s called Swift and it seems to me a very good summary of the features all modern imperative languages are striving for.

The last decade or so has seen a strong resurgence in functional programing evangelism. Languages like F#, Scala, Clojure and even Erlang for a while re-introduced to mainstream programmers high-level concepts that imperative programmers were largely unfamiliar with. A short experiment with a language supporting algebraic data types, type inference, higher order functions, closures, or the standard foundational map, reduce and fold functions will convince any programmer that their language would be far better off being more declarative.

For a comprehensive guide to the Swift language see the Swift tour.

"Some Swift code in Xcode 6 beta"

I have wanted two write another iOS app for a while now, and so I’m thinking Swift may be the way forward for me there. To that end I’ve spent all this morning going through docs and messing with XCode to get a feel for the various idioms and coding styles it encourages…

Read on →
Comments

Week in Review: Running in an Infinite World

Here’s a quick snap of the 2D SFML client alongside a new OpenGL client: "SFML client alongside OpenGL client with QML overlays"

OK I could have spent a bit longer on the screenshot – I haven’t made any models yet other than cubes, and I’m not using any textures, and I should have adjusted the angle and colour of the directional light to make it look like evening or morning or something, to show off some of the immediate benefits of going to 3D.

I did spend some time making the camera zoom in from a map-like view to a chase-cam view: "The camera is tethered to the player character"

In general however I’m hoping to ramp-down on the OpenGL stuff and go back to working on the core functionality. The last week was actually pretty productive: "Most recent git checkins"

Also I’ve been spending a fair amount of time in PicoPico Cafe when it’s open, and I’m guessing I’ll be spending more time there in the coming weeks as a bunch of construction is scheduled outside my house during business hours when nobody is supposed to be home.

Read on →
Comments

Week in Review: Porting to Qt/QML With OpenGL

So I took a month holiday, and got out of the habit of writing blogs… hopefully this will break the dam, it’s not like I don’t have a billion things to write about

Over the last many weeks I have been ploughing through a whole lot of new stuff I’ve never used before. As mentioned in my last post I decided to up the graphics a bit, but specifically I wanted to figure out a system for a extensible UI for menus and other 2D overlays, and 3D or pseudo-3D graphics. Creating a decent UI controls library I have learned is very difficult (if kind of fun to be honest.) Making something that is flexible enough to automatically layout your controls in a sensible way where everything resizes based on the content contained within is a very difficult problem that nobody should have to re-solve in this day and age. So I wanted to re-use one that I also wanted to learn for myself.

In order to add these to my existing framework I took on the (it turns out) monumental task of learning OpenGL and integrating it with Qt/QtQuick/QML.

So far things are looking OK, but I have found the learning curve greater than I’d originally anticipated – OpenGL in particular is a rabbit warren of deprecation and messy global state idioms. That said, I currently have:

  • the UI menu/control system is entirely QML based and very simple to extend and use
  • the game terrain is constructed using PolyVox because I wanted to avoid having to figure out mesh generation along with all this other stuff
  • the OpenGL shaders incorporate basic lighting and not much else

The main value I’ve gained is a fairly decent understanding of what it takes to create modern OpenGL applications (though how useful that knowledge is in this day and age I am not sure.) I have not tried porting any of this across to Windows yet (I’ve written it all in OSX) but hopefully the fact that I’m using entirely cross-platform technologies will help a little there – though Windows is known to have very dodgy OpenGL support so I suspect that will be the cause of most of my porting troubles.

Read on →
Comments

Week in Review: Making Games

I have once again bitten off a whole lot – I started making a game based on my fairly limited knowledge of how such things are done, and have found it very difficult to take a moment to distill my thoughts. In fact it has been nearly impossible as I have been constantly unsure of whether the approach I’m taking is actually going to pay off in the long run!

This is just a catch-up on my experiences over the last few weeks, a few discoveries and surprises, and perhaps my plans for the immediate future. I decided at the last moment to include a screenshot here, but I’m sure we’ve all seen brown circles on green backgrounds before…

"This is a 100m section of a 10km world"

I also created a (low framerate) animated gif of this in action.

Read on →
Comments

Week in Review: Pausing Web App, Starting C++ App

Just over a week ago I decided to put down my web tools for a while and move to working in an environment in which I’m much more comfortable – C++. I will definitely pick up the ‘Table Top’ app (or whatever it turns into) again soon but I felt the need to do work that resulted in a more tangible product.

Over the last few weeks I’ve had a growing realisation that the foundation of web programming is still immature, and I am doubting the value in investing too much time learning the high-level technologies. I am not really one for learning frameworks in general actually – I much prefer learning languages and idioms – and modern web programming is all about rapidly changing high-level frameworks.

That said however, I feel that I’m finally at a point where I can start making useful stuff in Ember and Rails without feeling like I’m misusing the tools or spending most of my time in Google. So last week I knocked off a few high-level features in my app to show the basic scaffolding I was considering (it only took a few hours in the end!), and then set it aside.

"Game Table App as of Feb 2014 - still doesn't do much"

There is a very duct-tape and chicken-wire feel to web technologies, but once you’re familiar with the tech you can pump stuff out pretty quickly. Because of the immediate and ethereal nature of the web it can be a fantastic way of creating a product that is immediately globally available. All of the magic we see however is still largely magic however, and magic doesn’t bode well in any application. The web as a platform for applications is still unbaked and young, and I feel that unless you’re forging new territory on the frontier you’re probably working with technologies that won’t be interesting in a few years time.

Read on →
Comments