The_Programmers_ByAble/Unix; Your mouse are a file.md

3.9 KiB

A file is a wonderful abstraction over raw data on a storage device. Users don't want to think about how many blocks on a disk their data takes up. They want a nice clean efficient way to reference all of the data, as such filesystems were a genius idea. A mouse device by design has some state which can be represented in a certian way, say we use JSON.

{
    "x": 0,
    "y": 10,
}

Now we can make a file path that points to this data. /mouse for example finally we document how this format works. /docs/mouse will be our location of choice

we now have a filesystem with the following files

/docs/mouse
/mouse

Wonderful we have achieved the ideal system.

Another hypothetical device gets added to our system the keyboard this time another fella decides to write the software for out keyboard device This fella decides that JSON is wonderful as well but a keyboard does not use numbers to represent keystates we will use true/false as our states

{
    "a": true,
    // the range between a-z ommited for brevity
    "z": false,
    "caps_lock": true,
    "shift": true,
}

We have our /keyboard file and our- wait whats this? The fella decided that the code speaks for itself and needs no documentation?! Strange but accepted. Really because I don't have a keyboard to test your code on or write documentation for.

Our filesystem now has expanded by one device

/docs/mouse
/keyboard
/mouse

Assuming we try adding support for every new device maybe we end up with 20 devices using 3 different formats (Binary, JSON and YAML) and 15 documentation files using 2 formats (markdown and plain text). I propose we move all device files into a devices folder

/dev/mouse
/dev/keyboard
/docs/mouse

We now have a less perfect system with 75% documentation. This is not ideal and makes developing a library to work with input devices, for example, hard to deal with. Keep in mind we only have documentation for the mouse.

We, as software developers, can impose a set of arbitrary rules for our file I/O based device management.

I'd like to offer an alternative that might not look so different but will offer a much nicer interface.

An interface language.

To create a device driver you must describe all fields and related functions and such using one language. Here is a mouse for example

struct Mouse {
    x: i16,
    y: i16,
}

Lets assume that this has to be defined and is enforced by the operating system.

We now have a convenient device structure (One language) and if we allow some more metadata to be tacked on we might even approach a usable system without tones of time spent documenting.

Lets add a concept called a decorator, signified by the @ symbol and add a decorator called a validator. To complete our mini example lets add a Bounds validator which lets us set a range on numbers.

struct Mouse {
    @validator[Bounds[-10, 10]]
    x: i16,
    @validator[Bounds[-10, 10]]
    y: i16,
}

This example is a bit silly but we can now limit the mouse position to be capped to certian Bounds as part of the API and not in code. Now when you want to write a device driver you can define a simple api with the Interface language and add very distinct dedicated features.

Now that our mouse device has some bounds lets add in a function to reset the device, useful if it ever fails to respond. We also add a safety and documentation decorators

struct Mouse {
    @validator[Bounds[-10, 10]]
    x: i16,
    @validator[Bounds[-10, 10]]
    y: i16,
    @documentation["Reset the mouse device"]
    @safety["The safety of this function is dependant on the mouse."]
    reset: function(None) -> None;
}

I would like to argue that this mandated format across many components of our operating system are better than the stringy file equivelents.