BeejiveIM is the first multiprotocol IM application for the iPhone that supports the new background notification features of firmware 3.0. Yesterday I went ahead and bought that application, curious to see how well it would work.
And just now my phone vibrated and on the display, there was an IM message a coworker sent me via Google Talk. The user experience was exactly the same as it would have been with an SMS – well – nearly the same – the phone made a different sound.
So the dream I had many moons ago (6 years – boy – how time flies) has finally come true, with one difference: Whereas back then the MB cost CHF 7, now it’s practically free, considering that I’m unable to actually use up my traffic quota and even then, it’s only CHF 0.10 now.
So let’s keep that in mind and also consider that SMS pricing hasn’t changed in the last six years.
So while IM was 52 times cheaper than SMS back then, now the price advantage ranges from somewhere between 3500 times cheaper and infinity times cheaper.
SMS pricing needs to be looked at. This just cannot be.
Like a clockwork, about one year after the release of PostgreSQL 8.3, the team behind the best database on this world did it again and released PostgreSQL 8.4, the latest and greatest in a long series of awesomeness.
Congratulations to everyone involved and might you have the strength to continue to improve your awesome piece of work.
For me, the hightlights of this new release are
parallel restore: I just tried this out and restoring a dump that usually took around 40 minutes (in standard sql/text format) now takes 5 minutes.
The improvements to psql usability just make it even clearer that psql isn’t just a command line database tool, but that it’s one of the best interfaces to access the data and administer the server. psql hands-down beats whatever database GUI tool I have seen so far.
truncate table reset identity is very useful during development
no more max_fsm_pages makes maintaining the database even easier and removes one variable to keep track of.
A year ago, I was comparing mobile phones, I bought a Touch Diamond and regretted it and then I bought an iPhone 3G which I used for a year and now I even upgraded to the 3GS. Now that I just got yet another comment to my post about the Touch Diamond, I thought I should recycle that comparison table from a year ago, but this time I’ll compare my assumptions about the iPhone back then with how it actually turned out.
So, here’s the table:
Quick dialing of arbitrary numbers
actually, using the favorites list, and even using the touch keypad with its very large buttons, I never had a problem dialing a number.
Acceptable battery life (more than two days)
meh – two to three days, but as I’m syncing podcasts every day, I get to charge the phone every day as well, so this doesn’t matter as much
usable as modem
it is now (using a little help for my Swisscom contract). As I was bound to my old contract with sunrise until may, I would have been able to use my old phone in an emergency, but that thankfully didn’t happen.
usable while not looking at the device
I got really dependent upon the small button on my headset plus the volume hardware buttons on the side of the device, both allowing me to do 90% of the stuff I was able to do on the old phone without looking at it.
quick writing of SMS messages
actually, I’m nearly as fast as with the T9 – having all keys at my disposal eliminates the need to select the right word in the menus, but not having the physical keys lets me wrestle with typos or auto correction which removes a bit of the advantage. It’s not nearly as bad as I have imagined though.
Sending and receiving of MMS messages
works now. I missed the feature about once or twice in the 2.0 days, but usually sending a picture via email worked just as well (and was cheaper).
yes, directly via ActiveSync – but since February, our company went the Google Apps route, so this has become irrelevant.
usable todo list
media player usage
integrates into current iTunes based podcast workflow
straight forward audio playing interface
yes (see my note about the button on the headset above)
straight forward video playing interface
actually, the interface is perfectly fine
acceptable video player
kinda yes. Using my 8 core Mac Pro, it’s quick and easy to convert a video, but lately I’m using my home cinema equipment for the real movies/tv series and the iPhone for video podcasts which already come in the native format. Still, it’s no generic video player capable of playing video in the most common formats and it doesn’t really support playing from any server in my home network.
yes. TouchTerm works very well – much better than any of the mobile Putty variants (Symbian an Winmob)
note quite. Actually usable with the speakerphone or headset, but not as useful in general use due to the inability to run in the background
OperaMini (browser usable on GSM)
not needed any more due to UMTS and near-flat rates.
Nearly all my gripes about the iPhone have either become irrelevant or turned out not to be a problem after all.
Combine the very acceptable performance as a phone with the perfect performance as a podcast player, music player, acceptable gaming platform and perfect mobile internet device, then it becomes clear that the iPhone has become the perfect phone for me.
I upgraded to the 3GS mainly because of the larger capacity, but now that I have it, the speed improvement actually matters much more than the capacity increase as 32 GB still is not enough to fit all my audio books, so I’m still limited to all my music, all unlistened podcasts and a selection of audio books.
But the speed improvement from the 3G to the 3GS is so incredible, that I’m still very happy I made the purchase. All the other features are either not quite ready for prime time (voice control) or not really interesting to me (video recording, compass).
Still. After looking for the perfect phone for 8 years now, I finally found the hardware in the iPhone.
Now, I’m no Python programmer by any means. Sure. I know my share of Python and I really like many of the concepts behind the language. I have even written some smaller scripts in Python, but it’s not my day-to-day language.
That chapter about string handling really really impressed me though.
In my opinion, handling Unicode strings they way python 3 is doing is exactly how it should be done in every development environment: Keep strings and collections of bytes completely separate and provide explicit conversion functions to convert from one to the other.
And hide the actual implementation from the user of the language! A string is a collection of characters. I don’t have to care how these characters are stored in memory and how they are accessed. When I need that information, I will have to convert that string to a collection of bytes, giving an explicit encoding how I want that to be done.
This is exactly how it should work, but implementation details leaking into the language are mushing this up in every other environment I know of making it a real pain to deal with multibyte character sets.
Features like this is what convinces me to look into new stuff. Maybe it IS time to do more python after all.
Ruby at least knows of the concept of private methods and fields which you can’t call from your additional methods, but that’s just Ruby. JS knows of no such thing.
This provides awesome freedom to the users of these languages. Agreed. Miss a method on a class? Easy. Just implement that and call it from wherever you want.
This also helps to free you from things like
which is lots of small (but terribly inconventiently named) classes wrapped into each other to provide the needed functionality. In this example, what the author wanted is to read a file line-by-line. Why exactly do I need three objects for this? Separation of concern is nice, but stuff like this make learning a language needlessly complicated.
In the world of Ruby or JS, you would just extend FileInputStream with whatever functionality you need and then call that, creating code that is much easier to read.
And yet, if you are a library (as opposed to consumer code), this is a terrible, terrible thing to do!
We have seen previous instances of the kind of problems you will cause: Libraries adding functionality to existing classes create real problems when multiple libraries are doing the same thing and the consuming application is using both libraries.
Let’s say for example, that your library A added that method sum() to the generic Array class. Let’s also say that your consumer also uses library B which does the same thing.
What’s the deal about this, you might ask? It’s pretty clear, what sum does after all?
Is it? It probably is when that array contains something that is summable. But what if there is, say, a string in the array you want to sum up? In your library, the functionality of sum() could be defined as “summing up all the numeric values in the array, assuming 0 for non-numeric values”. In the other library, sum() could be defined as “summing up all the numeric values in the array, throwing an exception if sum() encounters invalid value”.
If your consumer loads your library A first and later on that other library B, you will be calling B’s Array#sum().
Now due to your definition of sum(), you assume that it’s pretty safe to call sum() with an array that contains mixed values. But because you are now calling B’s sum(), you’ll get an exception you certainly did not expect in the first place!
Loading B after A in the consumer caused A to break because both created the same method conforming to different specs.
Loading A after B would fix the problem in this case, but what, say, if both you and B implement Array#avg, but with reversed semantics this time around?
You see, there is no escape.
Altering classes in the global name space breaks any name spacing facility that may have been available in your language. Even if all your “usual” code lives in your own, unique name space, the moment you alter the global space, you break out of your small island and begin to compete with the rest of the world.
If you are a library, you cannot be sure that you are alone in that competition.
And even if you are a top level application you have to be careful not to break implementations of functions provided by libraries you either use directly or, even worse, indirectly.
If you need a real-life example, the following code in an (outdated) version of scriptaculous’ effects.js broke jQuery, despite the latter being very, very careful to check if it can rely on the base functionality provided:
Interestingly enough, Array#call wasn’t used in the affected version of the library. This was a code artifact that actually did nothing but break a completely independent library (I did not have time to determine the exact nature of the breakage).
Not convinced? After all I was using an outdated version of scriptaculous and I should have updated (which is not an option if you have even more libraries dependent on bugs in exactly that version – unless you update all other components as well and then fix all the then broken unit tests).
Firefox 3.0 was the first browser to add document.getElementByClassName, a method also implemented by Prototype. Of course the functionality in Firefox was slightly different from the implementation in Prototype, which now called the built-in version instead its own version which caused a lot of breakage all over the place.
So, dear library developers, stay in your own namespace, please. You’ll make us consumers (and your own) lives so much more easier.
Update: I’ve actually written this post yesterday and scheduled it for posting today. In the mean time, digg has found an even better solution and only shows their bar for logged in users. Still – a solution like the one provided here would allow for the link to go to the right location regardless of the state of the digg bar settings.
Recently, digg.com added a controversial feature, the digg bar, which basically frames every posted link in a little IFRAME.
Rightfully so, webmasters were concerned about this and quite quickly, we had the usual religious war going on between the people finding the bar quite useful and the webmasters hating it for lost page rank, even worse recognition of their site and presumed affiliation with digg.
Basically it all boils down to digg.com screwing up on this, IMHO.
I know that they let you turn off that dreaded digg bar, but all the links on their page still point to their own short url. Only then is the decision made whether to show the bar or not.
This means that all links on digg currently just point to digg itself, not awarding any linked page with anything but the traffic which they don’t necessarily want. Digg-traffic isn’t worth much in terms of returning users. You get dugg, you melt your servers, you return back to be unknown.
So you would probably appreciate the higher page rank you get from being linked at by digg as that leads to increased search engine traffic which generally is worth much more.
The solution on diggs part could be simple: Keep the original site url in the href of their links, but use some JS-magic to still open the digg bar. That way they still get to keep their foot in the users path away from the site, but search engines will now do the right thing and follow the links to their actual target, thus giving the webmasters their page rank back.
How to do this?
Here’s a few lines of jQuery to automatically make links formated in the form
be opened via the digg bar while still working correctly for search engines (assuming that the link’s ID is the digg shorturl):
piece of cacke.
No further changes needed and all the web masters will be so much happier while digg gets to keep all the advantages (and it may actually help digg to increase their pagerank as I could imagine that a site with a lot of links pointing to different places could rank higher than one without any external links).
Webmasters then still could do their usual parent.location.href trickery to get out of the digg bar if they want to, but they could also retain their page rank.
No need to add further complexity to the webs standards because one site decides not to play well.