Language Integrated Query has definite implications for Testing
I know I just talked about the conceptual complexity of C# and Java, and C#’s Language Integrated Query (LINQ) is another example of why that is. However, it provides a feature that can potentially aid in properly unit testing database bound objects. The way Linq is implemented, it works on anything that is IEnumerable. That means you can have an List of objects or a database bound collection of objects and your interface to query the contents is identical. Put in other terms, you can write your queries once and they will function the same regardless of the back end implementation. Technically speaking, that means you can swap out databases fairly easily.
So, how does this work? You might ask (esp. if you are a Java developer). The book Professional C# 2008 from Wrox publishing does a good job of walking you through the transformation. Essentially, the query is performed in the object space rather than in the back end space which may not support queries anyway. First lets look at Java’s file filtering API:
File[] files = File.listFiles(new FileFilter() {
public boolean accept(File file) {
return file.getName().contains("like_it");
}
});
This helps set the stage, because it’s the same principle. From here on out we are using C#. The equivalent C# code uses something called delegates which in some ways resemble Ruby’s code blocks you can pass in to certain functions. The starting code looks like this:
List<Widget> widgets = new List<Widget>(Repository.GetWidgets());
List<Widget> filteredWidgets = widgets.FindAll(
delegate(Widget w)
{
return w.Name.Contains("like_it");
});
filteredWidgets.Sort(
delegate(Widget w1, Widget w2)
{
return w2.Name.CompareTo(w1.Name);
});
As you can see it’s the same principle. Instead of anonymous inner class mess with Java, you are using delegates in C#. Very little difference here. Apparently C# has something called extension methods which I can only imagine they got the inspiration from Ruby or something similar (yes, Ruby is one of my favorite languages). Essentially the extension methods let you create static methods that accept the object you want to extend and lets you work with the public interface for that object. The twist is that you can call the extension method on your object as if it were part of the original API. This is how the core of LINQ is implemented. LINQ adds the following extension methods for the IEnumerable interface:
- Where
- OrderBy
- OrderByDescending
- Select
- ... and more …
Using the extension interfaces our code sample gets rewritten as:
IEnumerable<Widget> filteredWidgets = Repository.GetWidgets()
.Where(
delegate(Widget w)
{
return w.Name.Contains("like_it");
})
.OrderByDescending(
delegate(Widget w)
{
return w.Name;
})
.Select(
delegate(Widget w)
{
return w;
});
It’s further refined by Lambda expressions. Lambda expressions have existed in venerable languages like Smalltalk and Lisp who claim the origin of all useful language features (tongue in cheek here). They also exist in Ruby. Essentially, they let you rewrite the whole delegate clause to take up much less space and read more elegantly:
IEnumerable<Widget> filteredWidgets = Repository.GetWidgets()
.Where( w => w.Name.Contains("like_it") )
.OrderByDescending( w => w.Name )
.Select( w => w );
This is further simplified using new keywords. To the best of my knowledge the keywords map back to the extension methods with lambda expressions. I’m not positive about that. However, there is a key distinction here. Unlike the work we’ve done thus far, a LINQ query is nothing but an execution plan. Similar in concept to how your database server will take your query and create a plan for it. The query plan is not executed until you start iterating over it. The final results of the LINQ query are below:
var query = from w in Repository.GetWidgets()
where w.Name.Contains("like_it");
orderby w.Name descending
select w;
OK. So let’s be straight about this. The concept of LINQ is pretty cool. It also helps simplify some otherwise complex filtering you would have to do on your objects. However, it appears to be strictly run in the object space. I can’t be certain because I haven’t read up on DataSource bound LINQ queries yet. There are some analogs to Hibernate’s HQL. If all the processing is done within the object space you run the risk of having very long running queries when dealing with large data sets. LINQ works with any object implementing IEnumerable, so there is nothing that says you have to keep all objects resident in memory. I’m pretty sure that the DataSource only loads what is needed at one time. Since the query is run as you iterate over it, you don’t run the risk of running out of memory when your query delivers a large result set.
For most CRUD based applications (like blogs, etc.) LINQ will work pretty well—particularly if you are dealing with limited result sets. However, if you deal with very large result sets involving joins you may have some performance problems. Those are the types of things that databases were designed to handle well. Like I said, I don’t know if there is a mapping to the underlying database querying through LINQ if it is working on DataSets. It’s still a potential performance problem that has plagued other languages and frameworks doing something similar.
All in all, I think LINQ has been done in a pretty slick way. What it allows you to do is focus on the logic of the query and how it is supposed to work for you. It is data agnostic, so it doesn’t care if it is working with lists, sets, databases, or a custom object that implements the IEnumerable interface. That really helps out when you need to mock up some base data to run your queries against in your unit tests. The fact that you can use this process with any list also opens up some unique possibilities for dealing with lists of data on screen. Hope you enjoyed this intro to a C# topic that piqued my interest.
Java and C# suffer from the same ailment
I have an interest in language design, even though I have no direct outlet for it at the moment. So as I’ve been contemplating what I like and what I don’t like about the languages I have been exposed to, I’ve realized that both Java and C# are suffering from the same core ailment. That ailment is the conceptual complexity underlying these platforms. I have to say platform because both Java and C# use a virtual machine that has been used to host other languages as well. C# without the CLR is like Java without the JVM: useless. This is in stark contrast to the almost sublime conceptual simplicity of Lisp, Smalltalk, and even Ruby.
Both C# and Java have bolted on several different features to deal with the underlying complexities, much like the English language has imported words from several different languages. English, technically a Germanic language borrows significantly from Romantic languages like Latin, and even some Greek. We won’t mention some import words from vastly different languages like Japanese (kimono, karaoke, katana, kanji). So it is with Java and C#. A short list of concepts shared by both languages include:
- Autoboxing
- Attributes/Annotations
- Dynamic binding (.Net 4.0 has a DLR and Java 7 has new JVM opcodes for this purpose)
- For each style iterating
- API document generation
- and more…
The problem isn’t so much the features in and of themselves. The problem is more subtle than that. In order to deal with the complexity of the language itself, these features are necessary. In some ways, a language like Lisp has conceptual appeal, even though its syntax is hard to wrap your head around. If everything is a list, from parameters passed in to a function to data values, and the language is built around set theory, it maps pretty well to a discipline of math. Heck, with Lisp a function is just a list of operations. Although perhaps in some ways Lisp is too conceptually simple.
The problem I’m getting at is being able to form a reasonable hypothesis of how the software is addressing your problems. I remember reading a PR piece on how Java was better than C# that had a small snippet of code asking how many method invocations there were. The two or three line snippet actually ended up invoking an unexpectedly large number of methods, from attribute accessors to delegates and some other magic. The intent of the developer was clear, although the impact of the code was unexpectedly complex. That’s not to say that C# is bad. The article was a PR piece to help Java developers still feel good about themselves. However, Java is just as guilty. Have you ever tried to debug dynamic proxy code? Have you worked with features that injected functionality into your code for you (Spring/Hibernate comes to mind)?
Other than the general second law of thermodynamics, what is it that drives languages to be more complex? Rather than truly seeking simplicity, both Java and C# have progressively moved toward sweeping the inherent complexity under the rug. Essentially moving the problem from something the developer has to worry about to something the platform has to worry about. To paraphrase my wife’s favorite movie:
There are three kinds of pipe. You have nickel, and you can see where that’s gotten you. You have bronze, which is very good… until something goes wrong. Something always goes wrong. And then you have copper, which is the only kind I use. from Moonstruck
Programming is a complex process. Translating the sometimes conflicting desires of a human into something a computer can understand is not easy. That complexity is further compounded by the moving parts we need to work together to accomplish our goals. My goal in exploring the world of language design is to find the right path for true simplicity. While we are approaching on that ideal from different programming paradigms, we haven’t quite reached the ideal yet. It feels like we live in a world where there is only nickel and bronze, and copper has yet to be discovered. I’m not the only one thinking about this for sure.
.NET Culture Shock 19
In my transition to learning C#/.NET I’ve run into what is my biggest hurdle: culture shock. The technology behind Java and the JVM and the technology behind C# and the CLR are becoming more similar than different. However the culture behind the technologies are like night and day, oil and water. I supposed if we were going to liken it to eras gone by, the Java culture would be more like the 70s hippie culture and .NET would be like the 80s yuppie culture.
One of the things I liked about Java was the share and share alike mentality. There are thousands of open source projects in Java, many of them with free integrations into your IDE. If you needed help with anything, there was someone with a clue that could help you—and they would. Much of what I expect out of an IDE came from the Java world. The concept of refactorings included and automated in the IDE was a major breakthrough, and now no Java IDE wanting to be taken seriously can exclude that feature. Thank you JetBrains for introducing the world to the way it should be. When .NET first came on the scene I don’t think Microsoft was ready in this regard. When the MS peddler came to my company I asked about refactoring tools in Visual Studio (this was around 2003), and the guy looked at me sheepishly. “But with .NET you can design one interface and use it on the web or on a desktop…” he fumbled. When I said I don’t do that every day, and I need something that helps me do my job better every day he wrote it down. I don’t think I was the only one to raise that objection because by the next release of Visual Studio they had the beginnings of refactoring tools included.
The Java culture works well with venerable organizations like the Apache Software Foundation. In some ways the Java culture mirrored the meritocracy already ingrained at the ASF. However, the one thing that hurt Java in the long run is also the one thing that made it better as a first language to learn. It’s that just about every major infrastructure piece has been freely distributed under open source projects. Sure, you get what you pay for in terms of set up and configuration, but even that got better with time. The free aspect is what undermined the ability of companies to make money. Why spend tens of thousands of dollars on a license when the free option was there? Just put an intern on it and it will cost less than the commercial option. Of course, that meant that it was equally easy to play with these tools yourself and make yourself more valuable to the company.
The .NET culture is a pay and share alike mentality. While there are a number of open source projects, they are fewer and farther between. Even so, plugins we expect to be included with the IDE like JUnit integration or ANT/Maven/Boost integration for builds either are non-existent or require you to pay a hefty fee. There’s an NUnit for .NET projects, and by the looks of it is a bit better off than the JUnit 4 equivalent. However, unlike JUnit 4, Visual Studio doesn’t have a plugin for it. In fact, it never will because Microsoft has its own testing features it’s wanting to push. You can incorporate NUnit, but it’s a bit more involved. Or you can use TestDriven.NET, which is not cheap.
The pay and share alike culture extends to the community surrounding .NET as well. When you need help, it’s hard to find what you want online. The only people volunteering free advice shouldn’t, and I’m not convinced that I’d be getting my money’s worth if I paid someone either. While the MSDN has gotten better, it still has a long ways to go before it is truly usable. Part of the problem is that it is so big, trying to find the answer you need is quite difficult. Even when you find it, there’s rarely enough depth to be able to put it to good use. Many .NET books are well in excess of 1000 pages. Rather than focusing on one corner of the technology and bringing the user through the process of solving a problem, the books focus on comprehensively covering all of the API and assume that the reader has more knowledge than they do. Or they are written down to a third grader, and the happy medium is no where to be found. I’m sure the Head First book is good, as they usually are.
Bottom line is that there are obstacles in the .NET world that impede self learning. It’s not insurmountable, and many of the obstacles are cultural in nature. The Job market for Java still doubles .NET, but enough key customers insist on the technology you can’t completely ignore it. Additionally, any new languages you learn can open your eyes to new and better ways to solve problems. I’m still hunting for my go-to resources in the .NET space. It’s going to be an interesting ride, and I’m actually looking forward to it.
What's Black and Blue and Eats Kids for Breakfast? 1
That would be the beast under my desk I built over the past couple months. Allow me to indulge for a moment. This is the first time I’ve had a machine that was better than you could get from a retailer. I also have the satisfaction of building this thing with my own hands. It’s running 6 AMD cores at over 4GHz each, has 8GB of fast RAM, Windows 7×64 Pro, and a few other goodies to boot. My thoughts are organized into the following sections: overclocking, unexpected effects of screen size, and why did I do all this?
Thoughts on Overclocking
I’ll admit my complete ignorance of many of the finer details of overclocking. These days motherboards have made this a fairly trivial task, as long as you stay within operating parameters. Many motherboards have automatic overclocking modes, with varying levels of success. I’ve read people bragging about getting their AMD Phenom II 1090T Thuban x6 processors up to about 4.4GHz with air cooling. More commonly, the numbers were around 4.1GHz. I found that for me, cooling was not a major problem. It was voltage sag. I’ve got an MSI motherboard, which doesn’t have as many power phases as the competing Asus motherboard. As a result I have to race the CPU voltage higher than spec to compensate for the voltage sag of using the CPU above it’s rated speed. Anyone will tell you that this is potentially dangerous. It could render the $300 chip dead if you are not careful, so easy does it on pushing the voltage up. That said, $300 is a price point I can risk for some additional speed that you just can’t buy.
I currently have my front side bus at 240MHz, which pushes the CPU to about 4,080Hz and the RAM bus to about 1,600Hz. My RAM is rated for 1600Hz with memory timings of 6-8-6-24-1T (which was Greek to me until I started reading up on it). Basically, the RAM is still operating within spec on my overclock. I also didn’t have to slow down the timings to compensate for system stability. I’m not willing to push both the RAM and the CPU, but it’s nice to have some fast RAM. When I ran the Windows Experience test, I hadn’t sped up the RAM yet. At its last test I got a score of about 7.6 (out of a possible 7.9) for that subsystem.
Overall, I did a good job balancing the components on this build. The Windows Experience ratings for the different subsystems were all within a couple tenths of a point of each other. The lone straggler was the IBM SSD boot drive that got a rating of about 7.3. It’s lousy write performance hurt the score a bit, but it’s a boot drive so I’m not complaining.
Screen Resolution has Many Side Effects
I’m sure part of the reason my Windows Experience rating for the GPU was as high as it was has to do with the fact that I’m running at 1280×1024. When I originally purchased that monitor, it was about the best you could do without spending ungodly amounts of money. Of course, video cards these days look at that resolution and laugh. Essentially the video cards don’t see any distinction until you get up into the 1080p high def range.
Something that I wasn’t expecting was the increased sensitivity of my mouse. I purchased a Razer Lachesis gaming mouse with up to 4,000 DPI sensitivity. That means every inch the mouse travels the cursor travels 4,000 pixels. When you only have 1280×1024 pixels on screen, that’s way more distance than is called for. A slight bump of the mouse will send the cursor off the screen. I had to lower the sensitivity to a usable level. It’s good to know that I have the extra there, just in case I decide to push a stack of monitors as one screen.
Why Go Through All the Trouble?
Honestly, I’m tired of complaining about my machine. I’ve been running underpowered gear for a good long time. I haven’t been able to enjoy PC gaming in the least due to my mediocre gear. Nor have I been happy with the screen real estate for programming and other activities. So I decided to treat myself. Overall I spent a little over $2100 USD on this machine, including the fancy keyboard, mouse, and the full Windows 7 Pro install. The price is right about what I wanted to pay, which is a good thing. I still have a few more accessories to get, so when all is said and done I’ll probably add another $700 to the rig. I need a new monitor (at least 1080p), a second video card to keep up with the increased resolution, and MS Office.
All that aside, I do have some experiments to try out, and some new programming ventures I want to expand into. With a rig like this, I have something powerful enough to keep up, and enable some more esoteric things like using your GPU for calculations. Imagine not being limited to just what your CPU can push. I’m looking forward to my new endeavors.
To All API and Library Designers
Creating APIs and libraries can be a difficult task. There are many concerns that you have to worry about such as design consistency, correctness, function, performance, security, and the list goes on. Something that typically gets lost in the list of concerns is usability . I know you might be thinking I’m nuts because APIs and libraries don’t have a graphical user interface. Yet they do have a user interface. The users of APIs and libraries are developers, and they use the exposed functionality provided by the API. Here are a few pointers that will cause developers to shout your praises rather than curse your name:
- Error messages/Exceptions should be clear
- Design patterns should be consistent
- Documentation should be useful
I’ll spend a little more on each topic to flesh out what I mean.
Error messages should be clear
Whether your language uses exceptions or another method of notification; the user of your API needs to know if they are the cause of the problem, and more importantly what they can do to fix it. Let’s take the example of bad parameters. They happen, particularly when a user doesn’t understand what is written in the API docs or it’s just an honest mistake. When a function has a half dozen parameters, it really helps to know which parameter is causing the problem. A generic “invalid parameter exception” with no indication of which parameter isn’t very helpful. If the parameter has to be within a certain range, say so.
There’s nothing more frustrating than spending a whole day trying to figure out what you are doing wrong, searching forums for possible clues, only to turn up empty. The more you can help your users (the developer) stay focused on writing software, the better. If an exception is caused by something outside of your control, it really helps to give that information back to the developer. They may be able to fix something that your library depends on.
Design patterns should be consistent
Whether you are using formal design patterns or simply a programming idiom to help convey the intent of the API, use it the same way throughout your API. There is nothing more confusing than having exceptions to the rule. We get enough of that learning English, we don’t need it in our APIs as well. The problem with exceptions is that they raise the mental complexity of the API. Every time a developer accesses a function, they have to consider is this function operates differently (or worse: which difference applies here?).
There’s no question that designing a consistent API is very difficult. The nature of the problem is trying to find an abstraction that helps the developer solve a problem. The problem is that if you choose the wrong abstraction you will make it harder to solve the problem or write the API. It’s a delicate balance. However, if you find yourself always needing to break your abstraction in a couple of places, perhaps you chose the wrong one to begin with?
Documentation should be useful
Developers really need two types of documentation. Many API writers recognize the importance of API docs (such as JavaDocs or .Net Docs). In order for these to be useful, the person referring to the documentation needs to know more than the parameters and the name of the function. They need to know what the function does for them, and if there are related functions that handle different tasks what they are. In an API reference, that is sufficient. You just need to refresh the developer’s memory, and help point them in the best direction if there are related (but different) functions.
What usually gets lost is describing the design patterns or abstraction the API is using. It’s one thing to know what the functions are, it’s quite another to be able to put them together in the right combination. Writing down the API design approach also helps the API developers understand how they are supposed to be solving the problem. Also, by writing down the API approach, you see just how difficult it is to convey. If it is too hard to explain, it is too hard to understand, and far too hard to use. Without this foundation, the examples of how to use the API make a lot more sense.
Conclusion
The three concerns I listed here are the top frustrations I have with any given platform. Whether it’s Java’s extensive APIs, the .Net library, Ruby’s API, etc. I’ve come across violations in at least one of the three concerns. My biggest frustration at the moment has to deal with bad or confusing error messages. The worst thing you can do as an API writer is have your users play “bring me a rock” with your API. It really helps to know that parameter X is invalid because it is not within the range of Y-Z. It does not help to know that at least one parameter in a list of seven is invalid: go figure out which one and how to fix it yourself. Additionally, if the network gets dropped and you no longer have a connection to a server, that information needs to make it to the developer instead of other exceptions that are just a consequence. For example if the problem is a file permissions problem, throwing a null pointer exception only confuses the user. They will quite rightly think you don’t know what you are doing. Understandably, proper exception handling is important. Which exceptions do you expose, and which do you handle internally? When the system breaks are you doing something unexpected as a fail-over? Java’s Remote Method Invocation API failed terribly in this manner. Instead of completely failing to call the remote object, it would silently fail over to an unencrypted HTTP tunneling approach first—even if the original connection was encrypted. That’s an epic security failure. Be reasonable, and sometimes it is better to fail completely than it is to fail over to something insecure without notifying the developer in any way.
C#, .NET, and COM--They should be better friends 2
With my new job comes a new language and platform to learn: C#/.NET. All in all, it’s not a bad language but there are some design decisions that are making things more difficult than they probably should be. The problem stems from the interoperability problem of .NET and some COM interfaces. The core issue is the “Variant” type that is used in COM. So, a quick history lesson:
Once upon a time, there was a set of separate platforms that used COM to tie them together: C/C++ and Visual Basic. VB was the limiting factor, so COM’s design was modeled after VB features. One such feature was the evil “Variant” type. Honestly, I think Microsoft is trying to live this one down because it was thoughtfully removed from .NET. In fact, Microsoft has come up with a new component model, using the CLR as the unifying feature. Unfortunately, COM is still the bridge between managed and unmanaged code. And COM still includes the Variant type in some APIs I absolutely have to use.
Problem: C# does not have a variant type. The interop library does not have anything to wrap variables into a variant type, at least that I can see. The method call that I need to use requires two output parameters of the Variant type (specifically VT_BOOL). The marshaller is not converting the bool type for me properly. Every resource I can find through Google is missing key information I need to pull everything together. I’m supposed to sacrifice three chickens, howl at the full moon, and dance the watoozi. So here I am, three chickens less, neighbors complaining about the noise, and thoroughly embarrassed about my dancing—but no closer to a solution.
I need this call to work:
void IsPortAllowed(string imageFileName, NET_FW_IP_VERSION ipVersion,
int portNumber, string localAddress, NET_FW_IP_PROTOCOL ipProtocol,
out object allowed, out object restricted);
The “out object” parameters (the last two) are a VT_BOOL type, which at its roots is still a variant. So I need to allocate a Variant object in COM space, and get results out of it in C# space. So far I have been frustrated. Please help me come up with something that works, and doesn’t involve sacrificing chickens if possible.
Concurrent Programming Lessons, and some abstract thought 1
Taking a break from my self serving blogging about my machine geekery, I’d like to jot down my thoughts on building a concurrent language that merges some powerful concepts from other existing languages. Based on lessons from Erlang, Ruby, and JavaScript I think it is possible to approach a working model for how to do safe concurrency in an object oriented manner.
First, let’s examine some concepts from Erlang, or Concurrency Oriented Programming:
- The world around us is concurrent
- Each cogniscent being maintains their own state
- Exchange of ideas is performed by passing messages
- By responding to messages, each cogniscent being may change their state
Based on these operations, Erlang makes a few restrictions. Variables are write-once (i.e. immutable once set). Because of this, Erlang does not need locks, mutexes, semaphores, or other fancy concurrency control mechanisms the popular languages use. All reads will be the same, regardless of timing issues. Processes are first class citizens, and no memory is shared between processes. Again, the same evils apply. If information is passed from one process to another, it is done by sending messages. The approach echoes observations smarter people than myself have seen in using SAX vs. DOM for XML parsing. The event (message) based architecture of SAX was less memory demanding and easier to maintain throughput in highly concurrent systems (i.e. web servers) than the DOM alternative. There’s a few more things in here that deal with reliability such as the VM’s ability to monitor and restart processes that fail. The end result are programs that scale easily with the processing nodes available, both local CPU cores and remote machines.
Next, let’s examine some concepts from Ruby, or Object Oriented Programming:
- The world around us consist of things
- Things can act on other things, or can be the recipient of actions
- Each thing should maintain its internal state
- Things act on other things by sending messages (i.e. calling methods)
Based on this set of basic rules, there is a fair amount of overlap between the highly concurrent Erlang concepts and the object oriented view of Ruby (or Java, or C# if you prefer). In practice there are a few different types of things. First, there are things (objects) that cannot act on their own (i.e. value objects like color, money, or dates) but will respond accordingly when acted on by others. These value objects never change state and are completely passive. Next there are objects that represent the current state of the world. These business objects, as some call them, maintain their own state and respond to messages from other objects. In some cases, the business objects will act on other business objects. Finally, there are things that act, or service objects. A service objects are a little different than the physical representations of the other two types of objects, but they take care of complex logic, workflow, etc.
Finally, let’s examine JavaScript, or Prototype Based Programming:
- There are no object descriptions (classes), only objects
- Objects can send or respond to messages (i.e. calling methods)
- Objects should maintain their internal state
So there is some overlap here as well. The major difference between prototype languages and object languages is the lack of a class. In essence, instead of defining how an object should look and behave using a class, you copy an existing object prototype. In the copy process you can extend the prototype by adding methods (new message receivers), properties, or whatever you like. You can also simply use the object as it is. There is a side effect here, that is the system tends to have fewer objects overall compared to your object oriented system. That helps with pesky matters like garbage collection. However, the objects tend to be a bit more powerful.
Now, some personal observations based on working with these languages:
- I come from an object oriented background, it makes sense to me so it’s hard to make the mental shift to the other programming approaches.
- There is a fair amount of overlap in the concepts, to the point where we can start formulating how to merge them.
- Defining a class for an object that will have only one instance seems a bit excessive. The system has to keep the definition of the object and the object resident in memory. Perhaps the prototype approach can help reign that in.
- Tying a process to an object gives us the concurrency of Erlang and the familiarity of objects. Essentially, the messages are methods and each object manages itself in its own process. Garbage collection can be much quicker since the collector can be optimized for one process’s data.
- Straight value objects don’t necessarily need their own process, they can run within the process (object) that uses them.
I’ve also identified a few challenges with the process/object approach as well. Processes will have to be monitored to see if they are still in use. A special garbage collector would need to be written for that purpose. The Erlang concept of a write-once variable matches the mathematical ideal well. For example, X=X+1 is a mathematical impossibility but a common programming concept in many languages. Yet, objects need to vary their state over time. Special distinction needs to be made to differentiate state that can change vs. state that cannot change. In some ways the concept of a Map for maintaining the internal state of an object is a natural approach. It might be how Erlang programmers maintain state in their processes.
There are a few things that I am concerned with, no matter what the language is or how concurrency is performed:
- Security. There’s bad people out there wanting to do bad things. Unfortunately, most security models are more of a pain to work with and consequently don’t get used.
- Internationalization. We live on a planet with many languages and cultures. At the very least UTF should be the default internal representation of strings. This is still a field the industry is trying to figure out.
- Robustness. Error handling has to be given special attention. If you get it right, you will help people create software that won’t easily break. If you get it wrong, you will help people create monstrocities that break more easily.
- Testability. Anyone who has done unit testing seriously has learned that the design of the code affects how easy it is to test. The easier it is to test, the easier it is to catch bugs, and the less likely people will complain about writing unit tests.
- Scalability. The platform should make it easier to take advantage of new features like multicore processors and remote machines. Ideally, the software performance should scale along with the hardware. I hate jumping through hoops to do what should really be done in the platform.
These are just random thoughts. Please shoot holes in them. I know I’ll have to figure out a lot of details to make something like that work.
What can go wrong with your build? 1
It’s been a while since I’ve built a computer. The last one was a dual processor 400MHz AMD Athlon box, at the time that Pentium 800MHz machines were being sold. At that time it was underpowered, and lack of real application support for threads really hurt the machine. I didn’t make that mistake this time, but there are a couple of things that can go wrong that have for me. The problems are a combination of hardware and software.
The first problem I ran into was physically putting all the components in my machine. I actually have plenty of room to put more components, but I ran into a few tight fits. Lesson #1: add your components to the motherboard before you put your motherboard in the case. It is a lot more difficult to use an AMD clamp for your heat sink when you can’t reach your hand in the case. While we are on the subject of heat sinks, if you choose to get an aftermarket oversize heat sink for your computer, understand how they are designed. That means to pay attention to airflow, and know that they are not designed to have a case fan on the side just above the heat sink. As it is, I’m probably going to have to cut a notch out of my side fan.
I had couple issues with my front panel connectors. At the end of the day the problem was me, but there was an issue with the quick connect with my motherboard. The quick connect assembly had a loose pin, once I reset the pin it worked as designed.
My main frustration right now is with Ubuntu 10.04. The new Ubuntu is very nice, and is quicker than it’s previous incarnations. Part of the evidence of that is my boot time is under 10 seconds without resorting to fancy RAID or SSD configurations. Most everything is working perfectly except for Adobe Flash and sound. As a result, I can’t watch videos or retire my laptop (which I use to watch videos). I have tried just about everything that I could dig up about ALSA and the sound drivers. Ubuntu can find the correct driver, but it can’t deliver sound to my headphones. Ubuntu is a short term solution, and it won’t stop me from doing my programming. I won’t waste any more time with this problem.
So far so good...
I can finally boot up my machine, but there are a couple problems at the moment. First, the power button and LED isn’t working. Probably just mixed up the two right now. I can fix that. The other is the audio doesn’t seem to be working. I’m not sure if it’s because the problem exists between the chair and keyboard, or if there is something wrong just yet. Linux works pretty good, with all six cores churning without a problem. Much less resource usage than the old laptop. The MSI auto overclock got my machine up to 4gHz without trying, but there are some stability issues I have to work out. I’m going to have to work with manual settings. At 4gHz, the processor chugged along at 32-35° C which gives me hope for a higher overclock, assuming I can get the timings down.
My biggest fear came true, but I can do a little mod to the case to fix it. The Zalman cooler is too big for my Azza Helios case. I think there is enough room around the case fan ridge to cut into it without having the fan actually hit the cooler. As you might expect, the codecs that come with Ubuntu don’t seem to be multi-threaded and the resizing algorithm is a bit off. What that means is that choppy video is still choppy whether I have a 1gHz CPU or six 4gHz cores.
I’ll work the hardware problems out this weekend, so I don’t kill myself tonight.
Minor update to my build
I’ve purchased enough to get the machine running. The processor is the same, but the RAM is now:
- G.SKILL PI 4GB (2×2GB) 240-Pin DDR3 SDRAM DDR3 1600 (PC3 12800)
It’s a little slower throughput, but faster latency and less expensive. I’ll expand to a full 8GB later.
I’m going to put Ubuntu Linux on it first, then I’ll switch to Windows 7 after I purchase that. It hurts my feelings that Windows 7 is so expensive, but in order to do some of the things I want to do, I’ll need to use it. To provide some context, one new license (not OEM) of Windows 7 Professional (and yes, I need professional) costs roughly the same as:
- 8GB of RAM
- A 6 core processor (AMD Phenom II x6)
- Two ATI 5770 video cards (crossfire, oh yeah)
- A 24” monitor with 2ms response time
- 3TB of hard drives
- Motherboard, case, and Blue ray drive
- 6 licenses of MS Office Home & Student edition
I don’t know about you but that seems a bit excessive. Windows 7 Home edition is still more expensive than the Home and Student edition office suite. Think about that. MS, think about that.
Older posts: 1 2
