Friday, September 28, 2007

The Linux loop

I'm using X but something does work.

Use Y

I am using Y but something different doesn't work.

Use Z

I am using Z but something else doesn't work.

Use X

etc...

Wednesday, September 26, 2007

Data and type safety.

What's the difference between :

String path = ...


and

File path = ...


?

For that matter what's the difference between:

int imageId = ...


and

ImageId imageId = ...


?

What is the point of creating an class for an object that contains one piece of data? Well...

In languages with a compiler enforced typing system, like java, it's good practice to leverage the type system wherever possible. Creating types for things like paths or ids can prove very useful. By using the type system the compiler will help you catch more errors earlier. This make the code easier to write and maintain.

When should we create a class for a type? If you look at InteleViewer's code base, we don't always substitute implicit types (of the form "int id") with explicit types (of the form "ImageId id"). The main reason is that sometimes it doesn't give us anything and the class can add a layer of bureaucracy that just serves to make the code more complex.

There's really a set of cases that determine how important/useful it is to turn an implicit type into an explicit type.

Cases:
- You have a 1 variable primitive type in which all values possible for the primitive value are allowed values for the implicit type but you don't do anything that actually needs to rely on the type.

You generally don't need to worry about this case unless your app is getting confusing enough that you want to use the compiler to check your code.

- You have a 1 variable primitive type in which all values possible for the primitive value are allowed values for the implicit type and you are often doing operations on it (formating, funky math etc..)

If you're doing operations on it (especially operations that take an object of the same type as a parameter. Like addition, for example.) then *always* make a class for that type. Dates are fairly good examples of this. They have a mapping to longs but we generally want to manipulate them in respect to each other. File objects are another good example (I think every value String more or less makes sense as a path).

- You have a 1 variable primitive type but there are some values that are valid for the primitive type but not valid for the implicit type.

I generally make a class for this if the value escapes from the object/code module it's in. The reason is that things can get dangerous across module boundaries.

You generally want to defend against badly formated implicit types across functional boundaries so that errors are caught early. Having an explicit type guarantees that the data you're getting as a param is well formed.

- You have a 2 (or more) variable implicit type.

Always make a class for this case.


Oh, one last thing.. Always make your data types immutable if at all possible. See ya.

Sunday, September 23, 2007

Amazon vs Amazon. A catfight.. to the death!

The dollar (US) to dollar (CN) parity has been quite an interesting development recently. Unfortunately it means that Canadian resellers (like amazon.ca) are in danger of being over-run by more aggressive competitors like amazon.com. Consider these prices differences:

For

The Age of Turbulence, Alan Greenspan's latest literary masterpiece, is (at this writing) 26.46 CDN and only 20.99 USD

The story is much the same with DVDs too. Take, for example the BBC's fascinating documentary series on the life and times of other species throughout the universe, Doctor Who. The third series is 87.49 CDN at amazon.ca and only 69.99 USD at amazon.com.

With the Canadian dollar and US dollar parity how are Canadian resellers like amazon.ca going to compete with US resellers like amazon.com? While some might argue that this is only a short term inbalence and that the laws of economics will take care of things, I suspect otherwise! I would suggest massive, arbitrary government intervention to help Canadian resellers maintain their high prices.

P.S.: I am not a crackpot.

Tuesday, September 11, 2007

Stupid Linux/X-Windows tricks

Linux doesn't include a GUI component however most Linux distributions will ship with some form of X-Windows. X-Windows has a broken copy and paste implementation that has been the bane of my existence for the last 3 years.

I've just run into an example of how this brain damage makes my life unpleasant. I bring this up here because every time I mention that copy and paste is horribly broken on linux people deny it. Try this on your linux box.

I've opened about 20 files in gedit (a very simple editor that works as a normal window/mac program does.). I've written something in the first tab, copied it, closed the tab and tried to paste it into the next tab. It doesn't work. It doesn't work because you've closed the window that contains the thing you've selected. No other operating system does it this way. Other operating systems, at least conceptually, store whatever it was you copied to a system clipboard. You can then quit the application and your data is safe.

The current linux situation means that I have to copy and past my text into some other window or application so that my clipboard contents don't go away when I close the tab that used to contain the information. This is totally absurd. You want to know why I'm not an Linux fanboy? It's because of stuff like this.

Thursday, September 6, 2007

How to do preferences

Recently, codinghorror ran a blog entry under the title of Was The Windows Registry a Good Idea?

http://www.codinghorror.com/blog/archives/000939.html

Now I don't want to be caught dead defending the registry so I won't defend it. What I want to tackle are the various comments to the blog posting which suggest alternatives that are clearly inferior or, alternatively, blame the registry for other issues entirely.

First up Jeff Atwood himself:

How appropriate. I post about the aggravating nature of the registry last night, today I get to "fix" a DVD-R drive that mysteriously fails to load with error code 39, by making this cryptic registry change:

http://forums.techguy.org/hardware/572840-dvd-burner-stopped-working-drivers.html

(see post #4 -- remove "LowerFilters" from the "{4D36E965-E325-11CE-BFC1-08002BE10318}" key under HKLM\System\CurrentControlSet\Control\Class)

Works like a champ now. :P
Jeff Atwood on August 29, 2007 06:10 PM


I too have had problems with lower filters causing problems. This isn't the fault of the registry this is a design flaw in windows.

Installers have the ability to make changes to settings that are not available to the user. In my case an installer (probably iTunes) added a lower filter then the un-installer neglected to remove it. It's a good thing I had read Mark Russinovich's blog posting which, among other things, mentions that..

"...Unfortunately, although you can view the names of registered filter drivers in the “Upper filters” and “Lower filters” entries of a device’s Details tab in Device Manager, there’s no administrative interface for deleting filters. Filter registrations are stored in the Registry under HKLM\System\CurrentControlSet\Enum so I opened Regedit and searched for $sys$ in that key. I found the entry configuring the CD’s lower filter: ..."


..other wise I would have assumed that the CD-ROM had died. The lower filter registry key problem is one of not having any interface in the GUI proper for managing lower filters properly.. OR that the system is so blinding stupid that it can't .. well.. I'll let Mark explain this one:

"When I logged in again I discovered that the CD drive was missing from Explorer. Deleting the drivers had disabled the CD. Now I was really mad. Windows supports device “filtering”, which allows a driver to insert itself below or above another one so that it can see and modify the I/O requests targeted at the one it wants to filter. I know from my past work with device driver filter drivers that if you delete a filter driver’s image, Windows fails to start the target driver. I opened Device Manager, displayed the properties for my CD-ROM device, and saw one of the cloaked drivers, Crater.sys (another ironic name, since it had ‘cratered’ my CD), registered as a lower filter:..."


Essentially if you have a CD-ROM with a lower filter thingy and you delete the file on the HD containing the filter thingy's code, then windows tends to disable the entire device and not give the user any useful feedback as to what is going on. This, not the registry, was Jeff's problem.

Ways of screwing up user preferences. Here's a bad suggestion:

"I personally like XML and ini configuration files, but they should be kept in the dir with the rest of the application's files IMO."


User's preferences can never go in the same directory as the app. If they did the application would not work with multiple users. Consider the two cases:

1 - Multiple users with multiple accounts sharing the same app. Every time one user would change a pref, all the other users would get it.
2 - A user running an app off a remote hard disk. Like the previous case all setting would be shared.. oh and there are also concurrency issues that will result in corrupt preferences.

Here's an note of interest: Applications on the mac used to store their settings inside themselves. They actually wrote their settings into their application files. This isn't as crazy as it sounds because the Mac had a way of storing resources like strings, images etc.. as real resources (as opposed to ad-hoc twiddling inside a binary file) inside the application program binaries and these things could be modified while the application was running. This was deprecated when appletalk became available and people started launching applications over a network. It caused race conditions if two people were running the same app and modified a setting at the same time.. oh and both users would interfere with each others settings.

(It actually had quite a few other problems too, not the least of it was was the possibility of corrupting the application file.)

Here's a point about speed:

"Yep, go with those ini files (or xml)!

Then deal with the performance hit of searching out keys or trying to update values. "


Someone once told me the key to bending a spoon is to realize there is not spoon. It's much the same problem when optimizing code.

There's no significant overhead with using a "ini" or "xml" file approach. This is especially true when it comes to making changes and writing them out.

What you do is you read the whole config file into ram and turn it into a data structure. You then use the data structure and make changes to it. You can then re-encode this data structure back into an ini file (or whatever) and flush it to disk at your leisure. I prefer to do flush it on a separate thread so it doesn't block the thread making the changes. You can also extend this system to automatically save/flush the preferences for you by simply detecting any changes made to the data structure, setting a timer for, say, 30 second (to batch any changes that might occur slightly after the first change), then write out the data structure in a background thread. It's loads of fun. I've implemented such a beast at least twice now. The net result is all your accesses to the prefs are super fast 'cause they are in memory..

"Don't forget to implement proper locking logic to handle multiple users hitting the same ini file."


Multiple users will not hit the same file because you've got one files per user per app as I've already mentioned.

"I'm sorry, I left off this gem:
"The registry is a single point of failure."

If you have a bunch of configuration files in a directory somewhere, and you delete those files... Isn't that a single point of failure?"


No that would be "n" points of failure skillfully dispatched with one stroke. You can simulate this in another way by getting a gun and shooting your hard drive. Go ahead; try to find a way of saving preferences on a had-disk that gets around that baby.

The point of having different programs save their settings in different files is that if a program is, let's say, writing to the registry and the power goes out or it crashes, that it doesn't leave the entire registry file in an indeterminate state. Microsoft has had to almost re-invent the concept of a journaled file system in registry form to get around this little problem. No wonder it took them so long.

"As others have pointed out, .INI files have their issues to (inconsistent format, can be scattered around, multi-threaded access), but *nix has made it work relatively well. That said, I pity the fool who has to look at sendmail.cf for the first time."


First off, no preferences file, whether it be .ini or XML should have to be edited by the user. It is up to the GUI application itself to offer a way of accessing its preferences.

Secondly, preferences file should not be scattered around! If they are then they will, most assuredly, not be in the right scope. That is, user preferences must in a place that is associated with the user so that users don't tread on each other. They cannot be in the same folder as the application.. They cannot be in the same folder as a neighboring application. They can not be one level up or one level down. They cannot be in any of these places for the same reason; a reason I explained above: multiple users. User preferences files must be in some sort of user specific folder.

Thirdly! (I thought I'd surprise you by using an exclamation mark on that one) As an operating system designer, you're going to want to offer an API for doing preferences. As has been made obvious by the comments posted to Jeff Atwood's blog, most programmers don't have a deep understanding of how to do preferences properly and, for that matter, writing a good preferences API is not an easy thing. Since your system is going to offer an preferences API, you might as well make the FORMAT for the files it produces standard. Why not XML? Yeah, yeah I know...

"Your article reminded me of this quote;-

Those who do not understand Unix are condemned to reinvent it, poorly.
-- Henry Spencer"


Given that UNIX is very poor to begin with that's pretty bad.

Yeah, ok so that was an off-topic unix jab.. I'm allowed 1.

"For instance, when I upgrade and reinstall Windows, most of the games I have installed on my secondary drive are instantly broken because they store cd-key and (redundant) path information in the registry. The game vendors' support teams will tell you to reinstall all your games and patches. Personally, I'd rather search forums and spelunk through the registry to manually recreate the two or three registry keys the game is looking for."


This isn't so much the registry's fault as it is an asinine windows convention. Quite a few programs tend to store, what are really string resources or required configuration information in the registry. This belongs in applications DAMMIT!

I suspect this whole thing got started when you absolute needed to register things like dlls or go knows what other type of thing in the registry. You see, the windows not only stores user preferences but also stores system configuration information as well. One could argue that this was its original purpose, really, and it just grew to contain preferences information as well.

There is a huge habit of using installers and de-installer do play with system settings both in the registry and to add icons to the desktop, the start menu, that quick launcher thing etc.. or to do things like install DLLs or some other damn thing (low filters!). This is a major irritation on windows and the primary reason why installers exist. If you look at the mac, installers are rare. This is because mac programs tend to be self contained and there's no cultural convention for installers installing icons in the docs or desktop. In fact, one could argue that you treat applications as icons and just drag them to you applications folder to "install" them. This is much better than an installer system in which so much can go wrong. Even after years of work on the windows installer system it still sucks balls. Sure it's not hopelessly broken any more as it was in the windows 95/98 days but it's still really bad. Installation is something the Mac really gets right.

"Ever tried to make a single entry in an ini-file readonly for the user?
I wish you lots of fun...

Only with the registry you could administer hundreds of machines in an easy and consistent way.
Only with the registry there is a way to double-click a .reg-file and enter its content automatic into the registry.
and on an on and on.
Registry is like a database, ini-files are like chaos."


People did this sort of thing with our application InteleViewer. This configuration is not supported! If you do this with our apps then phone our support line we will not support you. In the end what we did was write the functionality people were trying to reproduce into our app in an decent, easy to use way. It's also far more powerful too since it does what you were trying to achieve in an explicitly supported way! It's called roaming user preferences and it rocks.

Also, I think I should point out the existence of LDAP.

"...I do wish they'd adopt the same plist configuration format found in OSX, its XML based, very flexible and easy to work with.

Ini is kinda primitive when compared to plist, and Unix's convention of having no convention here is a poor idea."


Actually I agree with this one.. Come to think of it, the way MacOS X stores user preferences is exceptional. It does everything I've advocated here.

1 - It stores user preferences in the user's home folder under a special folder which is actually accessible to the user.
2 - Each app stores its preferences it their own files.
3 - The files is and XML format called a p-list.. There's even an editor with the development tools.. Which is good since while XML is, in theory, human readable/editable without an editor, no human would ever want to actually try.
4 - It's got a nice API baked in for dealing with application preferences.
5 - There's a well understood convention that no application should ever put a setting in its preference file that is essential to the functioning of that app.. All this to say that if you get fed up you can simply trash everything in the preferences folder and be assured that nothing will break.. You can also trash a spefic preferences file of a single malfunctioning app if you suspect it to be the source of problems.. I've actually done this many, many times while on the mac and it's amazing how often corrupted preferences files are problems.
6 - There's also a convention that you're not supposed to edit these preferences files by hand!!!!


Anyways... I suppose my main point here is that if you're going to try and build the ideal user preferences system you'd better bone up on the way the Mac does it.. Same deal if you want to look at creating a better installation system.

Ok I'm done..