Skip navigation.

Software Development

Correcting The Future

CSS is the Sucks

This CSS stuff is a pain. If something doesn't show up right, I'll try and fix it soon enough. I don't like the HTML they used. Oh well. I'll work around it eventually. Let me know if anything doesn't work. I know about the login box. I'll fix that later.

The System

This blog entry is just some ramblings... Well, I went and voted today. Not really motivated, but it's done. Sometimes I think I should form a government, but then I'd put all lawyers in jail for crimes against humanity. I'm waiting for tonight to see the results. Interestingly enough, the blackout rule is back in effect this year in Canada. Did I not mention this is Canada? The great white north isn't so white these days. Blame it on global warming I guess.

I used to mock America for leaving Bush in office, but my reluctance to vote must not be unique. Interest in politics is like being interested in a lobotomy. Either way, you'll end up with less brain cells. Must be why there are so many lawyers in office.

I've mentioned in how bad a shape the computing world is in. But after reading laws and learning how to file my own papers (for lawsuits, motions and all that stuff), I have to say that the legal system is a complete and utter joke. I'd be ashamed to be part of it. Everything is very badly written. Some of it is sexist and contradicts the Constitution. Some make judgment calls that it shouldn't. Some are just blatant revocations of human rights. Not only that, but each state and province has its own laws. Just look at consumer protection laws. Some of it is good, but why this doesn't apply to contract law across the board is beyond me. Contract law is also screwed up. Anyone who's a programmer should read up on contract law. There's some sick things in there. You're allowed to tell someone you'll let part of the bill go, and then once he gives you part of the money owed, you can sue him for the remainder even though you said you'd let it go. You can go to court, tell the judge exactly what you did, and you would probably be awarded the money anyways.

There's even a law that protects liars called Res Judicata. So if you lie and get away with it, you're in the clear. Even if the other party finds out you lied, they can't do anything about it and even more they can't even say that you lied because you're not allowed to contradict a previous judgment (other than the appeal process). Not only that, but if you learn something later on that you COULD have found out back during an original trial, but never thought about checking, then you can't bring this up either. If this law isn't written for crooks, I don't know who it's written for. Finality of a judgment should be based on the truth and only the truth. Yes, even I know this is fantasy. Heck, it's insanity.

And now I took part of a system that will do nothing to change these things. They don't even talk about it because most people can't read these laws. The language is atrocious. If people knew what was in these laws, no one would accept them. In the computing world, I feel much the same. Not about the programming languages, but about the amount of suckage people tolerate because they don't know any better. They even go and promote this mediocrity. If people actually understood what they were promoting, I don't think they'd be so ready to accept these things.

In politics, we have a system. In computing, we have a system. The one for computers is a little different though. It's more insidious. With government, we know they're incompetent. With computing, we think there's some kind of intelligence behind the scenes. Worse yet, we get people who think they know enough to confirm these ideas when all they've seen are these very same ideas. It's like asking an impartial Montreal Canadian player: "Who will win the Stanley Cup?". HAHA Can't really ask someone from Toronto. They'd probably say "Not us." Oh Pat Quinn, why won't you retire? You've been there for ages. What else could you possibly teach the players? Or are you keeping some tricks to yourself? Either way, it's time to go. And Théo in Montreal. HAHA Oh man, I remember when he played here in my hometown in the AHL, his nickname was RedLight. Nice to know it still fits.

Unfortunately, I think the only way to be impartial is to get an outsider or someone who dislikes everything. Someone who dislikes everything just doesn't care who's right or wrong because everything sucks anyways. So a Java user pointing to something he likes in Java isn't very useful to me. Neither is the same from SmallTalk or whatever language.

What I like is people who have their own ideas. At first, I wasn't too sure about this whole blog idea. Truth be told, I wasn't too interested in it. But some people had some good ideas. Ideas of their own. So that motivated me. Something I found weird though is that people think I have to agree with them 100%. If I agree 99.99%, it's not enough. And I can't tell for sure if people take all this literally. This is a blog. How serious can I really be? I do believe in what I say and I stand behind my ideas, but I have to provide some entertainment value. HEH! I'm thinking about changing the name of my blog to "The Wheel Factory!"

I also find it curious how people see things. Yeah, I said C++ is dead. I'm still using it. Am I contradicting myself? No. Does it matter? Not likely. For people who are supposed to use abstractions, we sure take things literally don't we? If a tool doesn't work the way it should, there's a chance it can be fixed. I find it funny how if I try to fix something then I'm not allowed to rename it, and worse yet I'm contradicting myself because I'm still using the same tool. You bloggers know who you are. Yet, when XML came about, a format that's existed since the beginning of time called text, it's new and the best thing since sliced bread. Sliced bread *is* pretty cool. And the fact that they fit exactly into my toaster. That's good design if you ask me.

Anyone watch the Australian Open (tennis)? I wonder what kind of software they have for the spot shot. You know what it is... when there's a close shot, they bring up a computerized simulation of where the ball hit (as a black circle), and the court lines are also drawn. I wonder how they decide what part of the ball touched the court. Does it actually squish enough to have that big a radius? Where do they decide on the boundary? And why don't they use it on all close shots? It only takes a second now anyways. How do they detect the ball in the first place? Anyone remember the green and red puck on Fox Sports for hockey? HAHA Man, that was funny. Still, it's cool technology. Just not for hockey. Maybe for when we lose our keys. We could use the sensor in it to locate it. What's this have to do with anything? Usually I have a link to some bigger idea. Not this time. I got nothing. Ok, how about this? How many times have we worked on a project that ended up being scrapped or used in production, but found to be crap or not do what the client expected it? How can we detect crap beforehand? Do you have people in your company who say everything is crap? A pessimist? You'd think I'm pessimistic, but the only thing that bothers me is short timelines and no time allocated for documentation. Oh, and blinking text on webpages. Why does everyone want blinking text on webpages? I don't get that. I think that's what it comes down to. The client wants something, but before they see it in action, they don't really know for sure what they want. For programmers, a mockup is usually a good percentage of the entire contract or project, so it's a difficult position to be in. That's why I like graphic artists. I have no idea how they put something together so fast. And I like that I can make it look exactly like whatever the graphic artist makes. Not just that, but it makes my application look good. Most of the time, no one sees anything we programmers do anyhow.

So if those other bloggers are right and I'm always wrong, then the following are true:
1. The party I voted for will win. (I'm expecting them to lose.)
2. Toronto will win the Stanley Cup. (Not bloody likely.)
3. Théo is a good goaltender. (HAHAHA)
4. The legal system does work.
5. The government is honest and capable.
6. XML is somehow different from text.
7. Bread doesn't fit in my toaster.

If it's ok with you, I'd rather stay crazy... and have toasted bread.

Object = Goto 2

This is the second installment for the case against objects. This time, we'll get to the real issues surrounding objects and why it makes certain kind of tasks difficult, if not impossible to code.

There are two types of execution when it comes to a single thread. Vertical and horizontal. Or more commonly known as recursive vs. sequential. However, sequential in this case takes on a slightly different meaning.

In either procedural or object oriented code, you are programming in a vertical or rather recursive manner. Each function call can go ever deeper until it returns. But even after each return, it can again call more functions and continue deeper again. The reason I think plain procedural is better than OO is because you don't have global state information if you decide to call the same function again. Or at least I hope you're not using global data in a recursive function. In any case, if you don't have sharable state information, then your function is independent from other calls and there's no coupling of data between function calls. In OO code, the data in your object acts like global data and can cause the state of your object to become invalid if you're not careful with recursion even if you don't call the same function twice, but other functions in the class. These are known problems in procedural code. Yet we went and used a paradigm that makes these problems less obvious and in certain cases much much worse.

The other kind of execution is sequential or streaming code. This is where you pass along some data to be processed from one unit to another. At each stage, the data is used in some kind of computation and can even change format completely. At this point, it is passed along to the next stage for further computations if need be. The problem with this kind of streaming is that the data is bare. There is no protection of the data and each stage is free to modify the data as it sees fit. Also, if you are using the OO paradigm, leaving your data open to manipulation goes against the OO principles of encapsulation. If you were to try and implement this in an OO way, you would have to add each stage directly into the object. But this changes the object itself and introduces unnecessary coupling to these methods. It also makes it less than obvious what the chain of processing is supposed to be and how each stage processes the data. It also isn't conducive to modifying the format of the data. Not only that, but if the data can change, it makes externally accessible methods rather hard to define as each one will now have to check if the data is in the correct format before executing. Normally, the object would only contain data that ALL its methods could handle. And you would have a different object for each type of data. But this doesn't work for streaming data where it can change at any instant.

The thing is that these two paradigms can work very well together in small modules. Basically, we need clusters of classes (to borrow an Eiffel term). At each level, we need ever bigger clusters. Clusters of clusters. Super clusters. Groups of super clusters. And keep going bigger until you're done mapping your entire application.

This means that an object can only reside inside a cluster. This is vertical processing. Data goes in and starts the execution of that cluster. When the cluster's execution terminates, it should output the processed data if any. Each cluster will have its own thread during processing. Only raw data can be passed between clusters in a predefined format. So each cluster should define the kind of data they accept and what they output. You can use whatever you want, but there should be a standard container for different kind of things. If you want to use XML, that's fine, but there should also be a binary version.

This would be a normal app with a super cluster controlling the operation of all this. So the first super cluster is the application itself with as many clusters as needed inside. Each cluster can contain objects. So a single cluster is the way we write applications NOW. Trying to shove everything in there is ridiculous.

Now notice what problems we fix. Any shared library that is used by multiple clusters will have to be defined as re-entrant, be thread safe or copied directly into the cluster. Whatever way you decide is fine and you could even use a default to avoid confusion. This means there is no threading problem from within the cluster. There are no concurrency problems. And there are no synchronization problems. The super cluster is what manages all the recourses of all the clusters, so it also handles the creation, deletion and execution of threads. It's a grandiose thread manager. Notice also that the super cluster is responsible for chaining the subclusters together and for passing data between them. This passing of data can be done by yet more threads, but under the control of the super cluster. Notice also that each cluster can execute in parallel.

If you can't see the advantages of this, then you've probably never done large scale distributed or threaded applications. You always end up doing something like this anyhow. The funny thing is that there are very few people that actually code this stuff because it can get rather complicated very fast. If you've never done it, you will fail. That's all there is to it. I've spoken about this before so I won't go into it. But I think if the setup was more conducive for this kind of production, it would suit many types of applications. In fact, it would encompass the OO, procedural, hierarchal and streaming paradigms. Not to mention easy threading. You also don't need to chain clusters together. You can use them as independent processing units thus making it somewhat like a processing array.

Now super clusters are nothing more than ordinary clusters. They are simply at a higher level. So the higher up you go, the higher your concepts should be. If you start coding a network protocol in a super-super cluster for example, then you know you're doing something wrong. Processing of that kind should go into a cluster or even a library. This allows for very clear separation of abstractions. There is now a progression. A super-super cluster can be invasive in that it can replace lower clusters with replacement parts. An example of this could be to create a thread on another computer when an underlying cluster tries to create a thread. And to provide an identical interface that would link the two computers up. As far as the underlying cluster is concerned, it would not care or necessarily know that the thread it created is actually running on another computer. These replacement parts are coded at a lower level than the super-super cluster that actually uses them. All you do at this high a level is tell certain parts how they link up and where they should go. The details are left to lower level clusters. And because they are independent, there's no risk to any of the threads.

So now you can take regular applications and make them distributed with little effort. I can already see what kind of tools would be useful in these scenarios. It also means that we can go to infinite levels of distribution. So if in the future we get a super-Internet that makes our current Internet look like a regular hub, then there's no problem. We add a higher cluster that redirects the necessary parts and problem solved. No need to actually modify the main source. BTW, this kind of super-Internet would probably only happen if we colonized the moon for example. I think ahead and BIG!

Notice the usefulness of both vertical and horizontal processing. But a clear separation is critical. Without it, we get a jumble of classes all over the place. Even when we drive for example, we have different levels of roads. There are residential roads, main city arteries, inner-city express highways, inter-city state or provincial highways and national highways. There are different concentration and levels of roads. In any network, this is the case. Our software should be no different. To me, this is so obvious it's stupid.

I'm not going to spend much time on this item, but it should be mentioned. Yes, theoretically, you CAN do all this in OO just as you could in a procedural language. But I could also use gotos instead of control statements and I could use assembler for everything. The point is why would you not want to be organized in a more productive way? And that's all I'll say on that.

We all know that objects aren't very useful by themselves for the most part. There's always the odd RNG type class that can be reused, but if you're doing anything even remotely useful, you're not going to have these kinds of independent classes. The opposite is just as dangerous however. Having a huge amount of classes that all operate together is not very useful because it's a maintenance nightmare. And that's the problem most large applications have. So it should be obvious the need for independent groups of classes. A certain number of classes should be able to work together, but at some point there has to be a limit. This is the reasoning behind a cluster. It should have a specific functionality and be independent from other clusters. This doesn't mean the clusters can't interoperate, but it has to do so via the super cluster. So whenever there is an error, it doesn't backtrack through the call chain. No, it goes up to the cluster and it tries to fix the problem. If it can't it either cleans up the execution thread or passes it up to its super cluster.

I'm also going to make each cluster have a standard interface so that they can be easily replaceable. They'll be extensible of course, but you'll be able to access all its functionality through this single interface no matter how much it has been extended. You can also have direct access to this functionality if it is known ahead of time. In fact, this will be automatic in my development environment.

This system also clearly defines who owns what. Your so-called GC will work quite differently under the hood than what you're used to. Passing objects around will become very controlled and the need for a GC will not be as great. But if you wish to use one, it will be local to the cluster. The super cluster can of course monitor its activities. The GC will not be a GC in the normal sense. There'll be a memory manager for each cluster. When you allocate memory, you specify whether you want the memory manager to deallocate it automatically, to use the stack or scope for deallocation, or manual deallocation. Most people will use only use one form, but all allocation methods will be compatible with each other. Even if you allocate something that you want garbage collected, you can still manually deallocate it, and vice-versa. You can of course tell the memory manager to only accept certain kinds of allocations and notify you of any inconsistencies. This is mostly to enforce your organization's guidelines.

Notice too that you can automatically ignore manual deletions if you tell the memory manager to garbage collect everything no matter what. In this way, you control how things are done and the since the super cluster can invade its containing clusters to change the way certain parts work, you can fine-tune your application without any need to change a single line of your original code... even for how memory is handled. And since clusters are independent, this makes garbage collection much easier. Heck, I don't even see the reason for a GC if your clusters or modules are well written. This is why I'm against GC's. If your data is well organized, there's no need for it. And with clear boundaries and ownership, much of the code to handle memory management can be automatically generated without a GC. So yes, there are alternatives to GC. Dare to see in color and not in B&W.

So there are three types of objects. The first one is somewhat similar to what we currently use. Then there are clusters which can execute threads. The third type of object is raw data somewhat like a structure in C, but with more power. Also note that even though I use the word "object", these are quite different than what contemporary languages use. I hesitate to use that word, but a grouping is generally known as an object so I'll use that term. I also haven't showed what the implementation will be like for leaf objects inside clusters. I'm still working out the finer details, so that will have to wait. All I can say for now is that objects will not have inheritance as you know it in C++ or Java for example. Much of the confusion will be removed. The private keyword will not exist as you know it. Virtual functions will be unnecessary. In fact, there will only be two types of access. Internal and external to the class. The external part can be either commands or properties. Of these properties, they can be linked to both data and/or methods. After all these changes, I think I'm allowed some slack to say that they're not the same as what we use now.

Clusters will have a default container for sub-clusters and a link to its parent. If it has no parent, there will be a stub there instead that will have default actions. A cluster also has a main execution entry point with a channel for data. There is also an output channel. So with a common interface to exchange data, connecting clusters together will be much simpler than it has been in the past. These input and output channels can expose common protocols for even easier interconnectivity. With a common entry point and command/data channel, a super cluster can inspect its sub-clusters to see if they have the necessary functionality before connecting them. In this way, dynamic updates will become much easier. And I already mentioned that clusters will be responsible for their own internal resource management. Any resources it can't manage will be passed up the hierarchy in the same way errors are passed up.

This brings up an obvious advantage when it comes to fault tolerance. Instead of generating exceptions that can collapse your whole system, the cluster is responsible for handling errors that the object who caused the error can't handle. It doesn't backtrack along the execution path. This is important. Now the cluster can try and fix the problem and resume execution or it can pass it up to the super cluster for it to fix by either trying another cluster or whatever else is in place to handle the error. It could just as well signal the cluster to clean up and terminate. In each case, the rest of the system can continue operating and finding a solution is not dependant on the caller. It is the responsibility of what controls the resources. This is a major departure from the way we currently do things.

Anyhow, the list goes on and on as to how this model of BOTH horizontal and vertical processing fixes current problems. Exceptions sucked, but are now fixed. Threading sucked, but is now fixed. Concurrency sucked, but is now fixed. Replacing components used to be virtually impossible at runtime, now it's simple. Objects sucked hard, but they too have been drastically updated. Fault tolerance sucked, but is now much improved.

I am fully aware that at this point, they are just ideas. And I haven't gotten into the details of what's involved inside a cluster. The thing to keep in mind is that I've put forward alternatives. I'm hoping that some people will see how some of this is different and how they could be beneficial. I do know that on the surface, they look similar to what you use or have seen. I'm hoping that soon enough I'll be able to have something in motion so that you can appreciate the differences. There are still many details to work out at the lowest level, so that will take time. And words cannot really do it justice.

I suppose a simple example would not hurt. Take for example opening a file. Currently, we usually check the error code or trap an exception. If the exception isn't caught then it backtracks along the execution chain. Now consider if the open file command passed the error automatically to its parent super cluster along with the filename and other associated information. The super cluster can now pass this information to the GUI sub cluster to display an error message and some kind of option like choosing an alternate file for example. Then the super cluster can replace the filename and retry the open file command. The key here is that there is a centralized location for resource management and handling of subcomponents. So you can have standard recovery practices for the same types of errors. It should also be noted that you can fine tune the error recovery. If you wanted the leaf object itself to try and correct this error, you can do that too. Sometimes, the fact that the file doesn't exist is perfectly OK. But if you run out of memory or hard drive space for example, it can be automatically recover by notifying the user without putting this directly into the main flow of your source code.

There are some weird things you could do like create backups of all data in clusters so that if any of them crashes, you can easily restart them without loss of information. It'd use up a lot of space, but you could theoretically keep the system running long enough until you can fix the bug and update the cluster without ever shutting down the entire application. I'm also planning that you could move clusters to other machines at runtime with the click of a button. The other machine can be completely different from the source. Heck, it could be alien technology and it would work just by implementing a few minimal details. The ability to port to an unknown system with almost no effort will open up a whole new area of support for all types of hardware that never existed before.

Everything in this entry is the tip of the iceberg. While there may seem to be an abundance of parts to this system, it's time we move into the future. Most of the parts will be automatically generated anyhow. I doubt if you'll ever see any of the high level parts if you just write a normal application. The fun part is that other applications will appear as regular clusters with specific functionality. So add a super cluster to your computer, link this application as a sub cluster and you can add a different GUI, resources or anything you like without ever modifying the original application. You want two users over the Internet to use the same application? Click of a button. You wrote a game, but didn't make it networkable? Add a filter to the input devices so that it can merge commands from a remote computer. Done. Could you imagine writing an application as if it only ran on one computer and have it automatically distributed over many machines without changing a single line in your main application? Imagine that we could just add a remote cluster to our application that would link up to a search engine. You could pick and choose which search engine you want. All this with the click of a button. This feature could be used for many things. Web browsers could link up to sites in a completely new and infinitely more powerful manner. There's just too many possibilities.

This is how I think things should be. And I see no reason why we're not there now other than false hype and reluctance to admit that maybe there is a better way. At the same time I know that many of my ideas will change over time as the quirks get worked out. Yet I can't help thinking we should be programming with much more ease and power than we are now. I've already got the most basic part of my environment working. The rest is creating some standard interfaces for commonly used features and working out the details of the compiler for what I've talked about in this article. It's all gravy after that.

Object = Goto

This may seem like a bold statement. And I'm sure this idea will get described with a few choice words. However, it seems like I'm not the only one who thinks objects are dangerous, at least certain features.

The part I want to get into is the calling mechanism, but first we should look at the other problems objects introduce. An obvious one is multiple inheritance. This causes name conflicts that have to be specifically disambiguated. There's also the confusion in base classes being able to be the same. Does the compiler create one instance or two? I propose to get rid of inheritance completely. It's not needed anyhow. I've never needed it. Anyone who's actually needed it just thinks they needed it and are so engulfed in their programming language that they cannot think outside the box so to speak. They see an inherited class and think this is the only way.

Another problem I've talked about is the coupling of data and methods that act on this data. This is the definition of an object actually. I think the very basis is flawed. Not that it can't prove useful on occasions. It just creates too many problems when building larger applications. Again, I believe there is a much better way.

Something else I've discussed is the protection mechanism in C++ and Java. I've said in the past that if you've used the keywords virtual and private in the same class definition, you should be banned permanently from ever programming again. The reasons are related to the one mentioned in the last paragraph. It comes down to inheritance and to a bigger extent the fact that an object should never be shielded from itself. An object should always have access to everything inside it. So if you declare certain members private, but declare certain methods virtual, then you have half-virtual methods. If you're going to couple methods and data, don't go half-way and corrupt the whole idea behind using an object. And don't think that only the data that the virtual method affects should be made protected. No, ALL members should be protected, and NONE as private. The private keyword should give an error and refuse to compile. I would go even further and say that the private keyword should never be used.

Now we get to the real culprit. Method invocation. Allowing methods to be invoked at any time on any object is our generation's goto. This is also related to coulping, but even if you use interfaces, the ploblem is the same. There are no boundaries. Any object anywhere can basically create any object it wishes and start calling methods on it. I don't know about you, but most code I've seen consists of initialisation, method calls and control statements. Tracking all these method calls is what maintainers have to find out about. What do they do? Where are they? Is the source available? Can I change it if it fails? This has to be done everywhere. This is also where I see a lot of code duplication. One person does it one way. Then someone else comes along and finds an easier way to do things, but missed a few places where this same thing or something close to it is being done. Now your maintenance problem just went up exponentially. Maintainers usually know to try a compile by undefining some of the old methods, but this gets more difficult if there are other parts of your software that still need those calls or if your "easier way" uses those calls itself.

Have you ever had mutually dependant objects? Can each one call methods in the other? There is nothing in the language that stops this. Now imagine hundreds of objects all calling methods in one another. What a mess! And there's no real way to avoid this. It's what we're taught to do. There is one entry point and then an object starts calling methods in other objects until the application terminates. This is not the way to write software.

There's always been something that bothered me about C++ when I first used it. When Java came around and I saw my University professors drool over it, again something really bothered me about that language. It was just a gut feeling at the time though. I couldn't put my finger on what was bothering me so much. C++ wasn't so much of a problem because I could easily revert to C if I wanted and at the time, much of the code was writing wrappers for C functions. That wasn't pretty either. Now I know why I had those misgivings.

I'm willing to bet that in the future, when we look back at the programming languages of the past, Object Oriented Programming as it is today will be considered the worst paradigm ever conceived. It just doesn't make sense to use it. That's why I'm considering OOP dead. It's no good, so I'm putting it in the trash. BTW, those of you who are reading this and are thinking that I'm just spouting whatever crosses my mind, I want to reassure you that this is not an idle thought. So if you're using OOP, you may want to ask yourself what problems it solves? It certainly doesn't solve modularity. It doesn't solve libraries. Most interfaces still only publish functions the same way C did. It doesn't make maintenance any easier. Many OS and large scale applications do not use OOP. And I've mentioned many very real problems with objects that other languages do not have.

All in all, objects are just as dangerous as gotos. I'm not saying objects can't be useful. But just like gotos, they present the same risks. OOP = Spaghetti code. The funny thing is that I don't have a problem with gotos if they're used correctly. I like to code in assembly, so gotos are the only tool we have for execution control. A goto certainly does not scare me. An incorrectly used goto does. What happened 40 years ago was curious however. A paper stating that gotos were harmful eventually led to the complete disuse of this statement from software. Many programmers are only told it's because of spaghetti code. It has problems with scope even for languages that don't use scope as C++ or Java does. The problem is that you don't know what variables can change or what state they'll be in when a certain block of code executes. In OOP, you get the very same problem with unrestricted method calls. So should we do what we did with gotos and stop using them completely?

There's a right way to use gotos and a right way to use objects. Without any restrictions, people will use them both incorrectly. But as with all tools, skilled users can do things that aren't always the norm, but do actually work and are consistant with the rest of the software. But then you get people that have been brainwashed and see it and point their fingers at the ugly goto. These people usually don't understand the reasoning behind not using gotos. There are perfectly reasonable uses for gotos and they do exist in production code. A common point of continuation after a set of control statements and having gotos point to this location is much cleaner than several breaks and if statements all over the place. But a beginner will most likely find it odd, or worse cry wolf.

However, just like gotos can be properly used, object can also be properly used. But not in the way the designers of current languages think you should use them. Would you not find it odd if one day you were driving down the road and all traffic lights had been removed? Whenever you have an interconnected network, you need guidelines on how this traffic is to be controlled and maintained. What is this system in OOP? If you're scratching your head, you're not alone. There is nothing out there. No traffic lights and no stop signs. Nothing to direct the interaction of all these objects. We chuck a bunch of objects together and the objects are free to do what they want without any real plan. This is the goto and spaghetti code of our generation. It will go down in history as one of the worst design decisions for programming languages ever.

There is a better way. That'll have to wait for another edition. For now, it's important to realise that nothing in programming is inherently dangerous. Gotos are not dangerous. Objects are not dangerous. What *is* dangerous is when these things are not used correctly. So the question arises... Do we do away with them or can it be fixed? With gotos, control statements were created. The gotos are still there. Not only in the language, but inside the control statements themselves. Control statements are abstractions for gotos. If we go by analogy, a logical question would be if we need an abstraction for objects just as we did for gotos. That sounds funny because objects were supposed to be an abstraction themselves. Of what, I'm still not sure. A sewer network perhaps. But at least a sewer serves a purpose and it all goes in one direction. And that, more than anything is an indication of the RIGHT way a network of objects should work.

There is a difference between a network of objects that only has one execution point and one that has multiple execution points. This discussion would take up much space and I'll follow this up in a future article. The thing to remember is that every situation has a different way of doing things. I've talked in earlier articles about how writing threads for one execution unit (one core) is very different from writing threads for multiple cores. There's a very good reason for this. In a single core, you don't want to start another thread if the CPU is doing some useful work. Otherwise, the thread you created will just slow things down by interrupting the current thread. With multicores, this is not a problem because you can actually execute both threads at the same time. This is a completely different situation than before. So the same thing happens with a network of objects. Things have to be controlled differently. Not just that, but they have to be designed differently too. The networks will not even look alike.

In this article, I've mentioned many things from previous entries. All my ideas are coming together and all the solutions are falling into place. I have a cohesive plan to solve many, if not all, of the problem mentioned in my blog. I haven't divulged much in the way of these solutions, but I'm getting there. This entry is the beggining of this process. It took a little while, and now I'm almost at the point where I have a comprehensive list of what doesn't work when it comes to programming languages. In short, a list of what sucks in software development. These are the things that I've declared dead or things that I've said don't work. Also, don't jump to conclusions that I won't include certain things just because I said they suck. No, I rarely disagree with ideas. All these languages had an idea behind them. They had very good reasons to come into existance. Again, it's their implementations that I have a problem with.

I like the fact that I'm not bound by such vague definition of terms in the computing world. Intermediate language is NOT necessarily bytecode. Keeping track of memory is NOT necessarily a GC. Dynamic compilation is NOT necessarily a VM. The world does NOT revolve around Java. What I find most troubling is that the definition of these terms are so vague that people will associate them with anything. More disturbing still is the fact that certain people will attach these terms to different ideas and dismiss them as reinventions of the wheel. In actual truth, I'm not disapointed. I'm actually laughing my head off. If only because I can see what others can't. So when you want to move forward in whatever you decide to do, don't ever listen to people that are set in their ways. I can see what works and what doesn't without any bias because I'm not attached to any language or tool. So if you are ever faced with two arguments, be wary of the one that has emotional attachment. Ironic that most people tend to choose the wrong side because of the emotional response and the determination in their argument.

What does this have to do with the way we use objects? It has to do with brainwashing. In order to see the truth, we have to detach ourselves from the programming environments we use. How many people would have even considered questioning objects in the way I've described it before reading this article? For many people, objects have always been there. No reason to question it. Actually, objects are even more dangerous for this very reason. That's what I've been trying to get at in the previous two paragraphs. Not only are objects dangerous, but there are certain things that are always right in front of us that we never bother to question them.

Recognising these traps such as objects is critical to advancing the computing world. I'm willing to move forward. Are you ready to not only think outside the box, but completely destroy it?

Notation and Quotes Online

Today, I thought I'd give a shout out to everyone's that quoted me online in their blogs or website. And a big thank you to those who said I was wasting my time and insinuated I was bonkers in some fashion. To me, this is an indication that I am either actually crazy or I'm actually on the right track. I'll place my bets on the latter.

I've been criticized for my use of terms and rightly so. I am very direct. I'd rather build than use fancy terms. That's one of the reasons this blog was created. Because I could no longer build. Or rather I could no longer build as fast as my capacity would enable me if I had the right tools. After looking around, I found that there was nothing out there.

Here's a few things to note about the way I look at things and the way I think:

1. I don't care about notations or what it's called as long as it works.

2. When I code, I see it all in assembler no matter what language I use.

3. I don't like seeing power go to waste. Whether it be 3D or CPU instructions or any kind of hardware that goes to waste.

4. When I have a discussion, I'd much prefer to talk to *you* than a quote.

5. I actually do know what I'm talking about.

That last one may not be obvious though. I've been criticised for my use of "object" for example. And as a commenter said, my definition of encapsulation is not the norm. For 99.99% of us, when we use an object, there's usually both data and methods inside. So that's my definition. Nothing more, nothing less. Remember that I see things in assembly. In assembly, it'd be a bunch of disconnected data and methods. Nothing more, nothing less.

So I do tend to use certain terms in their most basic meaning. If I say "class", I probably mean class as you would use it in C++ or Java. I may even use them interchangably because although in "research" terminology, there is quite a difference, when you actually want to do something, classes don't really exist, only the object or instance.

Ok, enough about that. In almost all blogs and other web sites that quote me, they seem to revel in the fact that they can point out something somewhere that seems to suit my needs. If this were so, I wouldn't even talk about it. They seem to miss the bigger point that these things they point out don't suit ALL my needs. Just because Java does this and SmallTalk does something else, this doesn't fix my problems. It's like someone prior to 1900 saying he wants a flying carriage and everybody else exclaiming that it's old technology because birds already fly and we already have carriages. That's all nice, but putting those technologies together isn't so simple. So you bloggers that say I'm reinventing the wheel, I say back that you don't even know what a wheel is.

I've come to the conclusion a while back that the only way I can really explain what I want is by creating it. So that's what I'm trying to do. I've written plenty of parsers, parser generators of every kind (some are on sourceforge), compilers and all that. But it takes a whole different magnitude when it comes to actually designing a new platform. So I have to make sure I get things right. Oddly enough, I've agreed with 99% of what people have commented on. The 1% that I disagree on is how they're used, implemented, designed and whatnot. The ideas themselves are not necessarily bad. This has caused many to not understand where I stand. Well, it's easy. Just look at the tool and tell me who's in control. If it's the programmer, then I'm for it. If it's the other way around, I'll ridicule it as much as I can. Hey, there's got to be some entertainment, no?

Then there's the Java fanatics. My goodness, these people are adamant aren't they? Nothing can pierce their shield of hype. Yes, Java can compile to native code. Good for you. I could compile BASIC to native code too. Bunch of good that did me. They miss the entire point. Why would I want to go to native code? What's the purpose behind it? An assembler programmer knows. It's the flexibility, power, unbelievable speed, and the fact that any new hardware becomes readily accessible. I want to bring that power to the masses. And then when I hear someone say that Java does all this back in '95? Heck, C didn't even do this back in 1969-73. Must be fun to live in a dreamworld though. Ignorance is bliss I suppose.

This is something else I have to mention. Assembler speed is so much faster than anything else you can use. People pick out this algorithm or that. Well, that's fine, but overall the speed difference is so great that most people just don't understand that their computer could be running at least 10 times as fast and be that much more responsive. There's no reason why this speed should be wasted.

So I'm not looking for half solutions. I'm looking for the whole package. Anyone can point things out. Putting them together into a seamless and consistant solution is not so easy. And there's nothing out there that suits my needs.

Now, to those who have quoted me in a good light, I thank you. You know who you are. Unfortunately, he's as real as Java portability.

That brings up another question. Why would I want to write software to run on top of another piece of software? For games, the objective is clear. But when it comes to programming in general, it doesn't make much sense. The Java fanatics claim it works well. Ok, but why the resistance to something better? I'd rather write code for the machine instead of a virtual platform. Virtual platforms have the exact same problems as other real (hardware) platforms and bring even more problems with them. What we need is a way to program where it doesn't matter the platform, virtual or not. Now do you see where I'm getting at? I don't make a distinction between a hardware platform and a virtual one. That's why I don't see the point in virtual platforms at all since they don't physically exist. I think the problem is that people think this VM platform is somehow special. Well, no. It's like yet another computer. A limited one at that. Not to mention that it doesn't even exist.

I've also been told that I'm contradicting myself with bytecode, especially with my last entry. What people don't realise is that bytecode is just some form of intermediate representation. Is an AST bytecode? Is an RTL bytecode? Is an object file bytecode? Heck, is source code bytecode? Where do you make the distinction? It's not just that. But the Java proponents think that bytecode was invented by Sun specifically for Java. So I try to avoid having to explain this all over again. It seems like if Java does something right in its users eyes, then the arms go flailing in the air and they start running about in circles. No, even if Java did actually do something right, it isn't the whole package that I'm looking for. This falls under the pointing things out category. I can point to the moon and then point to my car. Doesn't mean I can fly to the moon with my car. That's what the Java fanatics don't get. Nevermind that by the time the car starts, the moon will have crashed into the Earth.

I will use an intermediate language. I've said this from the get-go. Now watch the floodgates open and the Java fanatics come pooring in pointing their fingers. I don't want to use bytecode in the sense that I don't want another instruction set. I want to leave enough information that it can be optimized properly on the destination platform. But this will live side by side with native code for distributed code. Applications compiled for only one platform will not even use the intermediate language at this stage. So is bytecode the answer? Obviously not. There are other issues as well that I won't go into now. But it comes back to control.

I guess my saying that I don't want to use 40 year old technology sparked a few comments. Perhaps I should have qualified that as technology that did not take off 40 years ago and are being brought back from the dead. I can only assume I'm the only one looking to the future. edit: I suppose I should also mention that I'm trying to get a rise out of some people. What I'm really after are alternatives out there if any. I want to see what's out there and decide what's the best solution for my environment.

Another thing I want to bring up is the lack of context when people quote me. If I'm talking about C, then I'm talking about C. It doesn't matter that there's something else out there if that's not what I'm talking about. For example, saying exceptions will solve a problem doesn't really help a C programmer. Never mind that the solution is not viable anyways. Lisp proponents are especially bad for this. This is how a conversation goes with a Lisp programmer:

User: "I need something good with lists."
Lisper: "Use Lisp. That's what it's great at."
User: "Ok, I'll use Lisp, but I also want something extra."
Lisper: "Use Lisp. It'll do everything you need."
User: "I am using Lisp. But I want more."
Lisper: "No no. Lisp is the solution. Everything else is just a variation of Lisp anyhow."
User: "I already said I'm using Lisp, but not everyone likes Lisp. So I want something else as front-end."
Lisper: "You have to use Lisp. It's great. You want lists, it's built for it!"
User: "I am using Lisp."
Lisper: "Use Lisp."
User: "I am."
Lisper: "Use it."
User: "Can you hear me?"
Lisper: "Lisp!"
User: "Hello?"
Lisper: "Everything is Lisp!"
User: "..."
Lisper: "Use it."

Now on to a bigger problem. The problem of writing applications. I'm talking about business applications and large distributed systems. All over, I've been criticised about reinventing the wheel and that you can't be bothered with low level minutia if you're going to be writing a huge application used by multiple corporations for example. Well, that's like saying you can't be bothered with rivets when building a cruise liner. In both cases, I'm pretty sure your ship will sink. My whole reason for repeatedly mentioning low level constructs is because you need a good foundation before being able to build larger applications. This is the whole problem nowadays of not being able to build and maintain systems larger than a certain size. My whole point is that this foundation is flawed. If the low level "abstractions" are flawed, where does that leave us? With a ship that has no chance of floating.

I'm not saying to write things in that low level. Quite the contrary. I think we shouldn't even have to deal with them. What I want is the option to be able to fix it if it is flawed and to add to the foundation if new features and hardware comes out. More than that, if you understand how the foundation is built, then you can build more stable support and platforms on top. Get it? I'm all for large scale infrastructures with the least possible effort.

I want to talk about abstractions a little too. What I've seen so far is mediocre at best. Objects? Messages? All these different paradigms? I thought I was bad with analogies, but the computing world has topped me. Objects are nothing more than a bastardisation of the procedural paradigm by giving it accessible state information. It's spagetti code without an explicit goto. If you don't like goto's, you should hate objects too. They're just as dangerous.

Another thing people forget is that as a programming environment developer, I have to be able to convert these abstractions into concrete concepts. It's all nice that the regular programmer doesn't have to deal with this, but I do. And the way these abstractions can match the underlying hardware will have a lot to do with how well the language will work on that system. By "match", I mean converts or can be transformed to be used on the said hardware. Some people think that these abstractions should not reflect the underlying hardware. It should be a way to better put down our ideas. While I agree to some extent, there should be different layers. At the very top, a completely disconnected abstraction would be ok, but there should be many layers until you can reach that level of abstraction. In today's world of programming, there's only two levels. Abstraction and reality. There's no in-between. There's no progression. And that causes a lot of frustration.

So when you built a distributed system, you should program at a higher level than you would programming a function or a class. You should be dealing with connecting different parts of your system together without worrying about small details. That's what I've been trying to get across. There should be a layer for each level of complexity. I know I'm bad with analogies, but to me, it's like putting a faster engine in a car to go faster. At some point, you're going to reach a limit. So you have to use something different like a plane with jet engines. In programming, these paradigms are fine for small pieces of software, but they'll only get you so far. At some point, you have to use bigger concepts that encapsulates all these lower paradigms. By "encapsulate", I'm using the traditional dictionary meaning.

Note that as you go to higher levels of abstractions, you're dependent on lowel level abstractions. That's why I say it's a bad idea to abstract away primitive types completely unless you're programming at a really high level of abstraction. This would require a little more than just using objects for example. I cannot stress enough the importance of a good foundation.

Finally, I'd just like to say to all bloggers that have quoted me... all four of you... I hope you'll one day understand the world I see for the future. The things you point out do not work. They haven't worked for a very long time. And the failure to recognise these failures is very dangerous. I implore you to look at the real reasons why software development sucks and to seek out answers. I've made my case and I want something better. But keep making noise and telling me where I'm wrong. I can't learn if no one tells me.

The Java Fallacy

This is not a Java bashing session. Quite the contrary, I am writing this as a reference for anyone that says Java can solve all my problems. While it may come across as bashing in certain areas, it is only a side-effect. I will explain what I want and how Java fails in these areas. So when someone says "use Java", I can simply point them to a section in this article. I will be adding to this entry as more people try to tell me how great Java is.

1. Portability.

Portability means that you can take your code and have it run on another system. The system I want to deal with is the machine itself.

Java: So far, I've yet to run a Java application natively. So Java just isn't portable natively. End of discussion.

2. Extensibility.

I want something where I can expand the language or even add specialised functionality for specific systems such as epoll on Linux and the system tray on Windows. The list of useful specialised features is too long to ignore.

Java: By its very nature, Java fails miserably at this. To get a so-called portability, it sacrifices extensibility. To bad it failed at both. JDBC anyone?

3. Threading.

Threading is very hardware oriented. As the hardware changes, a language needs to be able to keep up.

Java: We all know the fiasco of the Java threading model. I'm tired of waiting for what Sun will finally decide on.

4. Multi-language support & application control.

Imagine a world where you could use Java if you wanted to, but it would compile to native code and be usable with many other languages. Where you could save your Java source and later load it as C++ or even Perl code. Where specialisation and use of specific hardware features would be possible such as writing codecs and using vector operations, but in a portable way. Where you would control the dynamic aspects of your software rather than the other way around.

Java: The Java VM has to be in control. End of discussion.

5. Speed.

I want to be able to write fast code if I want to.

Java: As of yet, Java is still extremely and painfully slow.

6. Memory footprint.

I'd like the application to use a little memory as possible. Or at least a respectable amount.

Java: Uh, no! I'd like to run more than one application, thank you!

7. Distributed code.

I'm still working on this area, but I want something where I can use multiple computers together in a seamless fashion.

Java: Java does not implement sockets correctly, so this is not viable. Not in any respectable fashion anyhow. Java does not scale well. I mean, for the longest time you couldn't even multiplex sockets. That's kind of sick.

8. Development time.

I'd like something where I don't need to reinvent the wheel every time.

Java: Unlike what many Java enthusiast would lead you to believe, Java is slower than C++ and other languages such as LISP when it comes to developer time. Only for people that have less than 3-4 years of experience is Java faster on average because other languages have more power, hence more risks and higher learning curve. For people with about 10 years experience, C++ and LISP is much faster to code in than Java.

--
Notice that we haven't even got into the language itself. Please realise that I do not want to bash Java. In fact, I'm quite sick of it. Remember that just because you may like Java does not mean it's the holy grail. There are a great deal of things wrong with Java. I've mentioned several of them above and will continue to add to them.

So when I say that I don't want someone to yell out "use Java", it's because I don't want to start bashing Java all over again. I'm tired of it. All the excuses put forth that tries to put Java in a good light are fallacies. They're not true. As tired as you may be of hearing how bad Java is, I'm tired of explaining why. I still don't understand how people can disregard that VM's have been tried 40 years ago. They didn't take off back then and they're no better today. I don't want to go back in time. My whole blog is about the future.

If you want to read about how the Java saga will end, I suggest reading some history books. This has all been played out before. I already know how it will all end, so trying to push 40 year old arguments just doesn't fly.

While these comments may strike a nerve with some people, I'm hoping they will look at these issues seriously. Why is Sun adding templates after 10 years of resistance? It's because Sun knows Java is on a decline. They're hoping this will revitalise development. Look for more timed releases in the near future. Also look at the "leaked" memo from Sun developers. I also know of no advanced programmers that enjoy Java. This may be speculative, but these same advanced programmers know of no one else they know that enjoys Java either.

I want something that's fun, fast, isn't a memory hog, has fast development times, is portable natively, is extensible, has consistant threading and concurrency, has working sockets, that is in control of its operations, can be easily distributable, supports multiple languages at the source level, has fast startup times and can take advantage of the underlying hardware. Java is NONE of these things. Well, you may think Java is fun. I don't. The rest is uncontestable.

So when someone tells me to use Java or Java already does this. Well, that goes smack against the truth. I'd rather go with facts as opposed to hype, otherwise we are bound to repeat history.

Catch-22

I have a problem about portability that I can't seem to resolve. I need to be able to transmit code/software over a wire.

While this may not seem like much of a problem, this is concerning a new programming environment I'm working on. Is there still a need for source code protection? In the open source community, of course not. So no problem there. In the commercial world, things are very different. You can't just give away code that the company has paid you to write. Well, you could I suppose. But don't be surprised if someone shows up at your door with some legal documents or even the police.

My problem lies in the fact that different computers may have different CPU's and hardware. Let's take this simple example:

const int limit = 8;
int a[limit] = {2,3,4,5,6,7,8,9};
int b[limit] = {18,17,16,15,14,13,12,11};

for(int i=0;i<limit;i++)
{
  a[ i ] += b[ i ];
}


Simple enough, no? Now, if I compile this in any way to CPU instructions, I have to compile for the lowest common denominator. Otherwise known as backwards compatibility. Not exactly true, but you're making your software run on old technology. While this is acceptable for some applications, it'd be nice if it could take advantage of features available on more recent CPU's such as vector processing and threads with multi cores.

In the example above, we could compile to bytecode for example, but then we need a VM (and I don't want to get into 40 year old technology) and more importantly, it doesn't take advantage of vector processing if it is available. With MMX or ISSE on the Pentium IV for example, you can process the arrays 2 or 4 items at a time respectively doubling or quadrupling the execution speed. If it's compiled down, the source code abstractions may be lost and these optimizations may become more difficult.

In statically compiled code, oftentimes the computer is queried for its features and all possible code for different versions of the CPU comes prepackaged. The problem with this is that you have redundant code, so the executable is bigger. Not only that, but usually a check is done before executing these routines to make sure the most optimized version is used, oftentime offsetting the performance advantage.

A bigger problem is that of portability across platforms and CPU's. A different CPU cannot use a different instruction set unless there is a mapping between the two. Possible, but this just becomes another kind of bytecode. Again, I don't want 40 year old technology.

Oddly enough for data, this isn't a problem. Data always comes down to atoms. There are only 3 fundamental atoms and only one is really necessary. Integers and floating point are the most common. You could also have fixed point notation if the precision needed is limited. Integer and fixed point notation are done with the same instructions. Floating point requires a different set of operations. In effect, data always comes down to 3 properties:

  1. Integer or float
  2. Size in bytes
  3. big or little endien


That's all you need to know. And usually an entire program will store all numbers with the same endien-ness. That means there's only size and floating point vs. integer. Of course, other primitive types may exist, but these are the most common. Therefore, data is easily transferred. However, the problem of reverse-engineering remains for companies that wish to keep their code secret.

So this comes back down to the fact that I need to transmit code over a wire. Encryption is not an option as the computer has to be able to read the code. If the computer can read it, then so can its user. As a side-note, I think people who write copy-protection schemes don't get this fact.

In my programming environment, the above code would be stored a little different in a format not unlike that of Lisp, but with certain extensions. While it would look cryptic enough, it would not be undecipherable as you can convert it to a higher level language.

Short of using the actual source, is there any alternative? I don't see any way of supporting commercial endeavors that wish to keep their code secret. If I just use source code, or the intermediate representation of this source code, all my problems disapear. But so does all closed source corporate interest.

Catch-22 if I've ever seen it. Maybe this is why we're still using 40 year old technology. Perhaps Richard Stallman was onto something when he said all software should be free, as in freedom to view and change the source. However, I doubt he had this in mind.

Anyone see a way out of this? If not, I'll just use some form of intermediate code.

Anonymous Comments Enabled (Software Blog)

I'm opening anonymous comments. I'm going to try it out for a while and see how it goes. I'm still undecided on this, so we'll do a test run for now. Good idea? Bad?

Well, This Sucks

No article today. I had one written, but after checking another page, I clicked on the tab with the article so that I could submit it, but there was a delay and I clicked the tab again just as the X showed up. Bye bye article.

Decoupling, Abstraction and Atoms

For someone who likes low level programming, I'm reading about a lot of high level terms lately. Anyone who does things at a low level is usually more concerned about concrete ideas and the physical properties of what he or she is working on than the terminology used to describe them. Sure, you may need a blueprint, but the implementation itself usually doesn't require knowledge of how to create a blueprint.

Decoupling. What's it about? Basically, it's interdependance between systems. In simple terms, if you have class A that uses class B then that's coupling. Class A can't work without class B. If you change how class B works, you also have to change class A unless there is some standard protocol. And now we get into the area of decoupling. If there is a common interface between the two, then you could theoretically change class B and still have it work with class A as long as the interface is still there. So the coupling is now on the interface and not class B itself.

There is another more serious kind of coupling and that is when a class uses another object out of its own accord. Ie. via a singleton or some global mechanism. There is no way to accurately determine what objects are coupled with what other objects. There is no interface to use in this case. A redesign must be done (which may include interfaces).

Decoupling is related to abstraction in that both of these terms usually deal with objects although it can be used for functions as well. So abstraction is simply a way to organise your data and code in a more 'usable' format. The 'object' in Object Oriented languages is that abstraction. Instead of using primitive types and functions, now most everything is an object and has a different way to do things. In an optimal world, each object should be independant from others (decoupled). But in practice, an object that isn't reliant on others isn't very useful.

Ok, oversimplified discussions aside, what does all this have to do with anything? My suggestion is that code and data need to be decoupled. Also, objects and primitive types should be decoupled. Primitive types are atoms. Atoms hold a special place in programming languages and computing because the computer can only operate on these primitive types. Now objects should still be able to hold state information. So what exactly do I mean by decoupling code and data?

First, we have to accept the fact that data on its own does have its uses. They do not always have to be placed in an object with methods. An object that only contains data should be acceptable. Then there should be other objects that operate on this data. So we need two categories of objects. One for data and one for computations. In this way, we can pass data along to different objects for processing. If you've used Linux or Unix in general, then you're familiar with command pipes. After one program is done processing the data, it passes it on to the next in line. Why this obviously useful methodology has all but been adandoned is beyond me. It has proved itself for over 20 years. And realistically, in the world of the Web, many of the more common server side code is passing session information from one request to the other. But it is not seen in that fashion for the most part.

Actually, if you look around in specific niches, the idea of pipelining is coming back in full swing. It lends well to the idea of multiprocessing if there is a lot of data to process. Each program can be run at the same time as long as they stream the data instead of processing all data at once before passing the results along.

There is a very good reason why this works so well. It is simply an extension of how hardware processors work. Instructions basically read data in, process it and then passes that along to the next instuction. CPU manufacturers have taken advantage of this pipelining in their hardware architechture to provide much speed improvements.

Notice in all cases, the decoupling of code and data? While each 'program' does have state information as it processes the data, the data itself is seperate from the software. How many times do we pass along the entire object instead of decoupling the data? The idea was that the object was supposed to protect against corruption and mishandling the data. I think this is a backwards view. If the object is the only thing that can 'handle' the data, then only the object can provide functionality to manipulate it. So we subclass the object and add our extra functionality. But what if that functionality can be used elsewhere? See the problem with coupling data and code? I see this all the time and is one of the major problems with the OO paradigm IMNSHO.

Take a list for example. The list data structure should be seperate from what acts on it. A real world example is a user class as in my backgammon server. Everything revolves around this class. In fact, I can't think of anything the server does that doesn't act or require a user. Because everything needs this class, making its members private seems like a useless overhead. If C++ had provided properties, I could have specifed certain properties as read-only and provided direct access to the socket mechanism to the user's input and output buffers and socket handles for example. But there are no properties in the C++ standard, so I ended up doing the worst of all possible options in an OO world. I made all members public. GASP! Other classes were better handled such as the game rules class and RNG classes where these can be mostly self-contained. But there were no appropriate constructs for what I wanted to do overall. Writing get and set methods is unacceptable. I'm not sure who thought of this, but it's just awful.

So what should have I done? I've given a lot of thought to this and I don't know that there is a solution. Even properties would not have been enough. The socket handling mechanism needs access to the input and output buffers of each user as well as updating its state which can then lead to processing user message (again pipelining). Do I make the socket mechanism a friend? What about the message processing facilities? EVERYTHING updates a user. There seems to be no consistent and clean way to handle what is essentially coupling. No, what would have solved all my problems would have been to seperate all data from the user class. The user class would provide basic initialisation and functionality. But the data part of the user could be passed along to whatever part of the system needed to update it. The only thing missing is a standard way of doing these updates. Sometimes I think the worry of corruption or mishandling the data causes more trouble than it's worth. Primitive types don't have the same restrictions as objects, so are we intentionally giving ourselves more trouble than necessary?

Perhaps having a validation mechanism in place for raw data would be useful. I don't know. What I do know is that coupling is a very serious issue that the OO paradigm fails to resolve. I'll even go further and say that it makes it worse.

In fact, I'll go further again and say that most software process data in this pipelining fashion. Video players are an extreme form of this where the video data is passed through many codecs before finally being displayed. This could not be accomplished if objects were used. Web browsers evidently are pipelined just by the nature of sockets and streams. Word processors are pipelined when doing searches or any kind of formatting. I'm hard pressed to find something that is NOT pipelined. If you think about it, in overall programming practices, it would seem logical to pass along this data and have each 'station' process it before passing it along. But is that what we do in OO? No, we extend the class. To me, that's backwards.

I think this is one of the main reasons why OO is giving so many people problems. It doesn't adequately represent what they are trying to do.

Also, objects that contain both data and code is contrary to any real-world system. For example, sure, a car has tons of parts. But these parts pass fluids, electricity, air or force from one part to another. This is how things get done. When fuel goes into the valves of an engine before ignition, this fuel is not protected by a capsule. And the spark plug does not ask this capsule to please take some of this 'spark' and light the fuel for me because I obviously have no clue what I am doing. No, it is passed along in raw format. The sparkplug knows what to do.

This is what I don't like in the current way operator overloading works. For primitive types, at the most basic level, it's the CPU instructions that act on the primitive types. But if you try to extend this with more complex types, it's the types themselves that handle the operators. If you look at it, the operator function acts on data in both objects of the arguments. This is ok in this case because both arguments are the same type. In real situations though, we often pass data along to incompatible classes. So instead of passing along the data, we pass along the object and this results in unecessary coupling.

While objects do work great for certain situations, I think they bring their own set of problems. I propose to decouple data from classes when the need arrives. If you look at objects that handle XML and SQL, you can see what I'm talking about. While this encapsulation is in accord with the OO paradigm, it sure is a lot of hassle. I think all this relates to much of what I mentioned in the last blog entry about requesting "resources" and being able to act on them. Only in this case, you pass it along to the next "process" in the chain as well.

Are these common problems? This coupling of data is my main problem when I use OO. How pervasive is this problem? And should the pipeline methodology make a comeback? I think we have to take a step back and really look at what's happening when we code. What are the real objectives and do they really fit the OO paradigm? Is bare data too much of a risk? Unix has been using it for years. Was I wrong in making my user class public? All that's in it is data. I find it weird that I ended up using the pipeline methodology even though I had to jump through hoops to do it. Interestingly, the system works great because of this decision to make the user class public. Not in spite of it. But it should have been easier overall and I don't like using things that seem to contradict the accepted way of doing things (as far as the spirit of the language goes). What do you say about OO and coupling? And although C++ streams haven't been discussed, I think they fell out of favour a long time ago. Is it related to this coupling issue? I think so. Also, I admitted to something that in the programming world would be looked at very negatively by making my user class public. Have others had to create ugly solutions? In my view, it isn't ugly. It's just incompatible with OO. But it's perfectly acceptable and has been used for ages. And it works great.
December 2009
S M T W T F S
November 2009January 2010
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 31