Types for obsessed mind

It was early 2013. I just dropped out of college. I gathered my friends to start building a game for iOS. We were not great at it, and eventually the project fell apart. Among many completely unimportant things that nonetheless bugged my mind was one unsatisfaction with the type system of Objective-C or any other language I knew at the time. It took me more than 10 years to untangle this problem and unexpectedly find a solution in the middle of the night.

The problem that my formalism-obsessed brain noticed can be stated this way: We have a 2D world where our protagonist moves. To describe its position, we define a 2D vector type. But how do you capture the fact that this vector is related to this particular world and not some other graphics system’s plane or some unrelated coordinate system? From this question, you might figure I was the kind of software engineer who prematurely worries about all the completely unimportant things. I do somewhat better nowadays, thank you.

The way it is stated, the problem is not worth the effort to invent any solution. What it does is open a peephole into the universe of similar problems in software engineering. So, let’s explore an array of increasingly sophisticated problems and see if any type system offers a solution.

Lambda cube

To arrange known type systems in a structure, Henk Barendregt introduced the lambda cube. Its vertices are known type systems. Moving along the edges of this cube adds abstractions to the type system. Half of this cube can be observed in popular contemporary programming languages. So that is where we will begin.

Problem statement

The idea could very well be translated into any field. But for the sake of clarity, I have to pick some specific case. Imagine you’re building a simple image manipulation program, similar to Microsoft Paint. Such a program might have many types that it works with, but I will talk about only a particular subset: pairs of coordinates. Such a type is used for so many things including the obvious—point on a canvas—but also: mouse pointer position relative to window, relative to screen.

Base

The base case of a type system can be observed in languages like Pascal. It is known as simply typed lambda calculus. It allows for functions on values but not on types. Let’s see how such a type system helps us in our case. For clarity the code is in C++.

struct point { int x; int y; }

Such a type already has a flaw: it is ambiguous on what the coordinate system is in the very general sense. Let’s make it a bit better:

struct point { unsigned int left; unsigned int top; }

Now we can declare procedures that work with this type.

void drawPoint(point canvasPoint, color pencilColor);
point canvasPoint(point mouseWindowPoint);
void canvas_MouseClick_Handler(point mouseWindowPoint);

You might be able to see the problem here. The type allows for a naïve mistake:

void canvas_MouseClick_Handler(point p) {
    drawPoint(p, c);
}

It is a good idea to use type system to check for this kind of mistakes:

struct canvasPoint: point {}
struct windowPoint: point {}
struct screenPoint: point {}

Now procedures’ signatures can be changed:

void drawPoint(canvasPoint p, color pencilColor);
canvasPoint canvasPoint(windowPoint mouse);
void canvas_MouseClick_Handler(windowPoint mouse);

This was a simple stuff. Though some developers might be reluctant to building such an elaborate tree of types, it obviously gives some useful compile-time checks without any runtime overhead. Let’s not waste any more time here and travel further on our lambda cube.

Polymorphism and generic types

It is a well established abstraction now but it has to be mentioned that Lambda cube distinguishes the two modifications of type system: adding terms that depend on types—polymorphism—and adding types that depend on types—generic types.

One trick that some of you might not expect is to use generic type to distinguish types of coordinates for our program. You might think of something like this:

template <typename T>
struct point { T left; T top; }

Here you see a type that is parametrized over format of coordinates. But instead I would like you to consider this:

template <typename T>
struct point { unsigned int left; unsigned int top }

typedef point<Screen> screen_point;
typedef point<Window> window_point;
typedef point<Canvas> canvas_point;

Now, you see, it is a type of point that can be parametrized over where it could be used. This way point on a screen could not be used where point inside canvas is expected.

If only this trick would allow us to also distinguish between points inside different windows. For that we will explore another face of Lambda cube in part 2.

Faulty Iteration

I was writing a C# app that is supposed to scan through directory tree, and it struck me by surprise how useless some .Net methods are. These in particular:

  • System.IO.Directory.EnumerateDirectories
  • System.IO.Directory.EnumerateFiles
  • System.IO.Directory.EnumerateFileSystemEntries
  • System.IO.DirectoryInfo.EnumerateFiles
  • System.IO.DirectoryInfo.EnumerateDirectories
  • System.IO.DirectoryInfo.EnumerateFileSystemInfos

Usually, you would use one of them in a for-each loop:

foreach (var filename in Directory.EnumerateFiles(@"Documents\Important"))
{
    // Do something...
}

Trouble comes when you try to use these methods to search through all subdirectories. If some directories are not available for your process to look into, you get UnauthorizedAccessException. You can’t catch exception inside a for-each loop. There is literally no call, that actually throws. The reall call is implicit, it is not shown here. That would be the call to MoveNext(), implied from for-each statement. When it throws, only option is to handle exception outside the loop, effectively breaking it. This leaves no option of skipping some unavailable directories without leaving current context.

In a search for better option, I wrote some mechanism for safe (no throw) iteration: SafeEnumerable. It is still raw but I’m working on it. It was supposed to fix the issue with iteration through entries in file system directory. It doesn’t work though: original implementation of directory iteration stops on error anyways. Look: source

// Open a Find handle
_hnd = Win32Native.FindFirstFile(searchPath, ref data);
if (_hnd.IsInvalid)
{
int hr = Marshal.GetLastWin32Error();
if (hr == Win32Native.ERROR_FILE_NOT_FOUND || hr == Win32Native.ERROR_NO_MORE_FILES || hr == Win32Native.ERROR_PATH_NOT_FOUND)
continue;

_hnd.Dispose();
HandleError(hr, searchData.fullPath);
}

private void HandleError(int hr, String path)
{
Dispose();
__Error.WinIOError(hr, path);
}

Calling Dispose() effectively makes object unusable. Yes, it could have continued to look through other directories, but it just quits. Does it sound weird or is it just me? This flaw in design draws the feature of deep search useless. I used this method on my home directory, and it threw. I used it on my Images folder, it threw still.

It seems like a bad design. The whole problem of handling exceptions in unexpected situations leads me thinking: is there a better way? What if there were better ways to manage errors than walking around the call stack looking for someone to take care of your mishap.

Software Platform Proposal

Motivation

Nowadays life becomes mobile. Consumers want access to services everywhere. Means of communication give access to simple services like e-mail and WWW through standardized protocols. However, access to services like banking and social networking requires a more sophisticated interaction between server and client. This leads to several different approaches to solve this problem.

Every program on its own.

The most obvious approach is to develop your own software to give access to your services. Company creates software that clients would use to receive company’s services. There are few downsides of this:

  • Developers usually leave cross-platform out of concern, which makes programs hard to port on different platforms. The use of cross-platform libraries makes it possible to overcome this problem.
  • Such programs require installation into system and they take space on a storage device.

This method became very popular after a boom of Apple’s mobile platform in 2008.

Software platforms

As a way of overcoming incompatibility of various platforms, several companies have built a layer of abstraction that would consolidate those. This layer takes care of interaction with operating system and hardware on case-to-case basis. Examples include Java and .NET. Programs written for Java compile into bytecode that any machine can execute if there is bytecode interpreter available for such machine. Such platforms as Java still have flaws.

  • Software platform requires maintenance. User has to keep software platform installed with all its components to run applications
  • Applications still need to be stored on user’s computer and some of them have a sophisticated installation process.

The Web add-ons and Java Web Start

To overcome the known issues engineers considered incorporating World Wide Web. Sun Microsystems integrated Java into browser. Java browser applications are stored inside browser cache (code and data). This way responsibility of storing app data and code is on to browser. In addition, this technique leads to easier application update, because browser natively supports cache update according to HTTP specification.

Along with Java other browser extensions existed, among which Macromedia Flash (nowadays Adobe Flash) became the most popular.

Java Web Start gave an option of running a common Java application while keeping the benefits of a web application by allowing users to start program through hyperlink in a browser.

Pure Web applications

Pure web applications are those that use only open technologies that World Wide Web consortium has standardized. After Apple has strictly forbidden any Flash or Java content in their mobile browser Safari for iPhone, web designers became rapidly looking for technology that would fit their needs for interactivity inside a web page. Luckily, such technologies already existed. HTML5 and JavaScript served as a new foundation for web applications.

Proposal

Modern web applications use a combination of HTML and CSS to describe user interface. Instead, I suggest the usage of a single language to define the look of a user interface. There are plenty of languages that serve this purpose, including: XAML, QML, UIML etc. To achieve same level of portability in mobile-first world we should use script language like JavaScript or Python to write executable code of the app.

My TV Is My Desktop. Why?

This article has been under development for more than 6 months already and it is still not done. I am posting this now because I can’t hold any longer. I am sorry for being too short on words, I just can’t make it any clearer, not this time. If I get better at explaining my thoughts, I will edit this and give a deeper explanation of my point of view.

Intro

Ever been in situation when watching a movie on your computer you suddenly decide to put it out on a TV screen? Or had to show PowerPoint slides with a projector? Your procedure probably looks something like this: you plug another screen or projector into a video output of your computer, your desktop appears on the screen, you start some program, put its window on a screen, stretch it to the size of the screen and watch it or show it to other people. Noticed what’s happened there? The moment when you plugged your screen to your computer your desktop appeared on the screen. But should it?

Background: The Brief History of “Desktop”

Modern graphical user interface for desktop computers is as old as 1973, when it was first developed by a group of researchers at Xerox. What they did was a remarkable innovation: they introduced the concept of “windows, icons, menus and pointer” (WIMP). Sadly for Xerox, executive board did not see the opportunities of the new invention. But there were people who saw. Among those was Steve Jobs. Thanks to Apple Computer, this concept of a GUI became extremely popular and eventually came to be called desktop.

What’s behind this?

The fundamental element of every wimp implementation is a window manager. Window manager’s job is to compose an image of several windows side-by-side or overlapping one another. Window manager usually is the last chain in the process of putting a picture on a computer screen.

What is wrong?

The problem is not with window manager itself, but with the fact that it is usually overused. Window manager is supposed to handle windows on screens. But when a user connects his or her PC to a big screen, user usually does not want UI to be shown on that screen. So there is no need in window manager. Still many popular graphical operating systems (Windows, Mac OS X) force us to use window manager on those big screens!

“tl;dr” section

Microsoft, Apple! Guys, stop forcing us to always use a window manager! When I run PowerPoint or my favorite video player, I want to just tell it which screen to use, not drag windows around, guessing where exactly my window system has put a screen on a virtual screen layout. (Is it right of main screen or left? Or is it on top of it? Or under?)