Software Development

Correcting The Future

Connections and Usage

I just got done removing all spam trackbacks from my blog. Obviously, SPAM isn't what I meant this blog to be used for. While thinking about this, it reminded me of how things used to be done in some cases.

Let's create an imaginary scenario. Suppose we have a very fast machine with all the hardware and resources one would need except for ONE thing. It would only have a CRT monitor. You can use an LCD if it supports the right connection, but that's not the point. The scenario I'm setting up has one more oddity. Your video card can only display ONE color. You can select from 16 million colors, but it only has ONE register where you can set the color that will be sent out to the monitor.

Some people would have a problem with this. For others, it wouldn't phase them one bit.

Suppose our CRT runs at 60hz with 60 frames per second, we can change the screen color each frame. With a normal machine, we can change the screen 60 times a second no problem. So that much stays the same. But having a single color isn't very interesting. If we can change screen colors once per frame, what's stopping us from changing it more often? Nothing.

So we can time our software to change colors at every line. With a vertical blank interrupt, you could just set up a timer to generate another interrupt every scanline. So when the video beam starts a new line, you can change it colors. If your machine is really fast, you can even set up your timer to generate an interrupt X times per scanline. This will produce X pixels on screen by simply changing the color at each interrupt. And guess what? You could have memory buffer used specifically to store the colors you want to output at each "pixel". And this is basically what your video card does, except in hardware.

For those that are skeptical, you should know that this technique was used way back on the Commodore 64 which ran at 1Mhz. You couldn't do pixels, but you could change the background color once per line reliably. If you tried to do pixels, the timing wasn't precise enough and you'd get oscillating pixel boundaries. The C64 had an area called overscan that surrounded the display area. You could only set it to a single color. But that did not stop demo coders from displaying color bands. They would often have color bands surrounding their logo at the center of the screen. But when it reached the edge, the overscan area was a solid color. They would have liked the color bands to extend all the way to the edge of your TV screen. So they used the technique I just mentioned to produce color bands in the overscan area that matched the rest of the display area.

They also used this technique with the audio to play digitized sounds and music. The C64 has absolutely no functionality for playing digitized sounds, but it did have a master volume control with 16 different settings. So you simply output a constant sound and then updated the volume control with the digitized data at the appropriate frequency. This is analogous to the turntable example in the picture at the top of this article. The groove sets the height of the needle just as the digitized data sets the volume of the audio chip. However, 4bit audio sounds pretty bad.

So what does this have to do with anything?

It means we can't really control how people will use our creations. It also means that with enough creativity, we can usually get around current limitations. But my primary concern is that the way you use something will change the meaning of that entity. Its functionality will be different. The way people see them will be different. The range of things that people will think up will be different.

This applies to programming as well. Not only can the data we feed something change the purpose of that entity. But the way in which we use it can do this as well. Simply introducing time into the equation can change everything. This is what I've been trying to explain what's wrong with the Halting Problem or with abstractions in general. It's not just that they're leaky or whatever else, but that any developer of a function, class or module cannot control the so-called abstraction.

To me, it simply looks like conventional languages are in a never ending battle against one of the fundamental rules of the Universe. That whatever acts last "laughs" last. Without altering a single element from a particular entity, you can change its purpose simply by how it's used. IOW, you can do this by EXTERNAL changes only.

In case you haven't done so already, read up on the difference between composability and compositionality. Most languages only deal with the composing part. The "glue" that enables one to connect things together. But compositionality deals with what an entity DOES. The amazing thing about this is that you can change what it does with composition only without altering its internals.

While these things are certainly possible, what I find troubling is that there is an active agenda to remove this ability. I certainly understand the reasoning behind certain tactics like encapsulation, but at the cost of limited flexibility. The attitude of many languages, especially OOP, is to say "No... just tell me what you want done and I'll do it." So they put up a wall. They try to stop you entirely from using that object in any way that the original designers did not intend and we know how well that ends up working. I'm not against the idea behind the concept, but I do oppose the idea that a subclass should not have access to its parent's data. That's just moronic and why I deem the "private" keyword to be extremely harmful and dangerous.

In programming, we have different paradigms. The two fundamental paradigms are imperative and dataflow. Everything else is some combination of these two, or built on top of one of them. While both can compute anything deemed computable, they are quite different. What's even more amazing is that you can use one to simulate the other. And this is possible because of what I've described above. In fact, you can see one such example with monads in Haskell. Monads are dataflow where only one input and one input is allowed at each step therefore simulating imperative programming while retaining the benefits of purity that comes with dataflow. Functional programming is unpure if it uses external data, but dataflow has the advantage that it remains pure in such cases, hence why monads are used to circumvent this nasty little problem with I/O and other things. But try and tell that to a functional programmer and they will look at you weird.

You see this kind of thing all over the place. On the one hand, you have a tool that is simply using another tool in a different manner to enable functionality that you require. But on the other hand, this technique is frowned upon within the confines of your development environment. It's a rather sick situation. One that I cannot abide by.

I've only begun to look at this ability in a consistent manner deserving of its own status in the development community. I certainly knew about the technique from long ago, but never really considered merging all the similarities together into a consistent feature. If it's good enough for hardware developers and good enough for language developers, then why not regular programmers as well?

As I've said before, what really worries me are people trying to come up with proofs about certain things like the Halting problem that asks about a specific meaning of a program and then someone comes along, like Alan Turing, who never understood the concept I describe in this article. Many readers take objection to such comments. But I'm not here for platitudes. I'm here to find out the underlying principles that make computing possible regardless of whomever came before. The Halting Problem is not just wrong, it's affected the mindset of countless people for almost a century into a false belief.

I'll end this with a little question about viewpoint. When you code something, is your main concern how people interact, or with how your your data is processed? Now change people to any entity that has control of the execution point. Those who understand this know how profound this is. With data, you want to give meaning to the transformations so you know what's going on. With entities that can act, the meaning is already there, so you want to provide better communication channels. Now what happens when you have one of each?

Those are the questions I find interesting. It's also those same questions that are forbidden in most programming discussions when it is not pointed out like this.

Moon MachinesBusy

Comments

Vladasvladas Saturday, September 12, 2009 12:37:03 PM

That's what I call "Positive Controverse"! Questioning "obvious" things always brings you new ideas or points of view. There was the only one phylosopher - Friedrich Nietzsche - who did exactly the same, that's why I like his teachings. These are the only phylosophy teachings you can apply to practice, especially for programming.

Make things inside-out or upside-down - that's the way I (We) look at things. Then look at what happens. Your questions and doubts about "obvious" are alike. And this is the only way True Programmers should go.

Unregistered user Sunday, September 27, 2009 9:17:24 PM

Fant writes: The Amiga has a special Chip (the Copper) that does exactly that =D (with so-called 'copperlists') =D

Write a comment

New comments have been disabled for this post.

June 2012
S M T W T F S
May 2012July 2012
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30