Things I learned. http://thingsilearned.posterous.com cat /dev/thoughts | grep learned >> /var/log/posterous posterous.com Wed, 29 Feb 2012 15:34:00 -0800 [OS] Windows 8 http://thingsilearned.posterous.com/os-windows-8 http://thingsilearned.posterous.com/os-windows-8

The preview of next version in Microsoft's Windows platform is out. There's lot of opinions out there about their new Metro UI and new consumer/app driven architecture. Instead of adding to the noise that's filling the tubes of the interweb, I thought I'd just note a single observation that came to me.

In the Desktop mode, the Start/Windows button is now gone. This observation has been mentioned all over the Internet as well. But the most interesting thing to me is this.

In the place of Start/Windows button, we now have the Internet Explorer.

2012-02-29_09-25-11-1024_gallery_post
Decade ago, Microsoft laughed at the notion of web being a viable computing platform. Now, it replaced the most iconic representation of Desktop UI, the Start button.

To me, this is very exciting.

I love the future.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/307790/icon2.jpg http://posterous.com/users/37loT9ujHGj7 Timothy Kim Timothy Timothy Kim
Wed, 05 Jan 2011 14:04:00 -0800 [UX] Problem with Stack Overflow. http://thingsilearned.posterous.com/ux-problem-with-stack-overflow http://thingsilearned.posterous.com/ux-problem-with-stack-overflow

This might not be something that I learned but it's something I realized today. Close enough. :P

Stack Overflow (http://www.stackoverflow.com) is a yet another question and answer site and it claims that it's better than the other ones out there. And to their credit it is. It allows people to vote up and down questions and answers so that good questions and answers are immediately visible compare to scroll scroll nature of most forums out there, which sorts threads by time. It also allows people to edit old questions and answers so that it can evolve to be better Q&A even after the initial questioner and answerer has lost interest in the topic.

Another problem that Stack Overflow tries to solve that other Q&A sites can't is filtering of bad content. Forums are notorious for this problem. There's no way to know if a solution proposed by a poster is worthy or not. Stack Overflow solves this problem by repution points. It rewards people for creating good contents by giving them points. It's a small thing but it does motivate people.

But this creates another problem. Stack Overflow has a barrier of entry to its features that can only be unlocked by earning reputation points. You need 15 points to just to vote things up. 2000 points to edit. This barrier I think is too high for a site that claims to be "The Wikipedia of Long Tail Programming Questions"

I often see answers that can be improved through my quick edits but I can't do so. Here's what typically happens for me.

  1. I have a problem
  2. I search google
  3. I click on a Stack Overflow link
  4. It either solves my problem or at least points me in the right direction.
  5. I finally solve my problem and gain a knowledge that I can contribute.
  6. I come back to the site to add my knowledge but all I can do is add another answer.

At this point, Stack Overflow becomes just another Q&A forum for me. So, I leave.

Stack Overflow wants me to work hard on their site to prove that my contributions are worthy, when I already have useful content that I can contribute RIGHT NOW! This high barrier of entry has kept me from being a valuable content creator for Stack Overflow.

In contrast, Wikipedia just lets me edit. Although I rarely create new content, I constantly make good edits. I'm aware of the fact that my little edit will never be awesome as those power Wikipedia editors, but this doesn't neglect the fact that my contributions are valuable.

Long tail is all about cultivating one time users. It's about realizing that cumulative knowledge infrequent users are greater than those of few power users. Until Stack Overflow lowers the entry barrier to its content contribution model, they really shouldn't be calling themselves "The Wikipedia of Long Tail Programming Questions."

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/307790/icon2.jpg http://posterous.com/users/37loT9ujHGj7 Timothy Kim Timothy Timothy Kim
Fri, 24 Dec 2010 10:07:00 -0800 [Language] Functional Programming http://thingsilearned.posterous.com/language-functional-programming http://thingsilearned.posterous.com/language-functional-programming

With the advent of Web 2.0 and AJAX, Javascript is quickly becoming the most important language of this decade. And because of JavaScript's functional nature, functional programming paradigm is getting a mainstream spotlight. As for me, it was JavaScript that introduced me to functional programming and led me to dab with LISP and Haskell.

At first, it took me a while to see the power of functional programming. Yeah, you can pass functions around and use closure to make objects with private properties but I still wasn't convinced where the power of functional programming is coming from. Until I ran into this program:

.1. (define dx .0001)
 2. 
 3. (define (deriv f)
 4.   (define (f-prime x)
 5.     (/ (- (f (+ x dx)) (f x))
 6.        dx))
 7.   f-prime)
 8. 
 9. (define (cube x) (* x x x))
10. 
11. (define cube-deriv (deriv cube))
12. 
13. (cube-deriv 2) ; returns 12ish
14. (cube-deriv 3) ; returns 27ish
15. (cube-deriv 4) ; returns 48ish

Here is what's going on. Line 1 defines our dx or small change in x. The function in line 3 is a function that takes a function as a parameter and returns its derivative, f-prime. To do so it just uses Newton's Differential Quotient directly:

2e182ba47dd0ff925c5b7a4acf0522a2

Then, on line 9, we define a cube function, f(x) = x^3. And finally when we pass in cube function into the deriv function, we get the derivative function back, f'(x) = 3x^2!

Of course, lines 13~15 doesn't return the exact value of f'(x), but we can make it better by just adjusting dx.

This way of defining derivatives is straight out of math text book. No procedural nor object oriented language can possibly dare think about doing this. My mind was blown. I became a believer in functional programming.

In case you weren't sure what the fuss was about functional programming, hopefully this helped in convincing you.

As a bonus here's the same code in JavaScript:

.1. var dx = 0.0001;
 2. 
 3. var deriv = function (f) {
 4.     return function (x) {
 5.         return (f(x + dx) - f(x)) / dx;
 6.     };
 7. };
 8.
 9. var cube = function (x) { return x * x * x; };
10. 
11. var cube_deriv = deriv(cube);
12.
13. cube_deriv(2); // returns 12ish
14. cube_deriv(3); // returns 27ish
15. cube_deriv(4); // returns 48ish

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/307790/icon2.jpg http://posterous.com/users/37loT9ujHGj7 Timothy Kim Timothy Timothy Kim
Tue, 07 Dec 2010 08:25:00 -0800 [Web] Korean Music services. http://thingsilearned.posterous.com/web-state-of-korean-music-services http://thingsilearned.posterous.com/web-state-of-korean-music-services

I listen to LOT of music and I can categorize the musics that I listen to in two categories: published in US, and published in Korea.

To purchase music that are published in US, I use Amazon MP3. To stream them, I use YouTube, Pandora and Grooveshark. And if they are worthy of CD purchases, I just use Amazon again.

The problem lies with the musics that are published in Korea. There are specifically 2 problems last time I checked (which was like a year ago).

  1. Browser: Korean web space is very IE centric, thus preventing Mac/Linux user like myself from using music services from Korea.
  2. Payment: Because the service targets Korean population only, they have no means to accept foreign payment methods, i.e. foreign credit cards, bank transfers.

To work around this problem, I've been importing Korean music CDs from YesAsia. This is very cumbersome and slow. Buying it then waiting for 2~3 weeks to arrive at my doorstep. And finally ripping them to my digital devices. :(

But now that the web space in Korea has much improved (lot of the major sites support non-IE browsers!)[1], I've decided to dive in and try to see if it is possible for me to enjoy Korean music from the comfort of my American home.

I used Naver to sort out top 5 most popular[2] Korean music services and compared them in 5 different categories: price, DRM, non-IE browser compatibility, iPhone/Android App, payment methods. And here is the result:

  Price (40 songs + streaming) DRM Free Downloads? Non-IE support for streaming iPhone App Android App Foreign Payment
Melon ₩7,000 Yes No No (iPad only) Yes No
Soribada ₩7,000 Yes Yes Yes Yes No
Bugs Music ₩7,000 Yes Yes Yes Yes No
Naver Music ₩7,000 Yes Yes No No No
Music Soda ₩7,000 Yes No No No No

To my surprise, they all were priced equally. Is there a price fixing going on here? Another thing that suprized me was DRM free nature of the service and relatively good support for non-IE browser support all around.

It seemed like Soribada and Bugs Music are the best services for foreigner like me. Too bad none of them supports payment from foreign credit card. But I think I can get around this problem by just asking my parents in Korea to pay for it. :P

To make the final decision between Soribada and Bugs Music, I delved into usability of the site. I looked at 3 things: front page, streaming player UI, and music search.

1. Front Page

Soribada

Soribada

Bugs Music

Bugs

For some reason, Soribada's blue theme was more inviting than Bug Music's orange theme. But that's not the important thing. Bugs Music uses almost a third of their front page estate in selling their service, where as Soribada lists their music right from the top.

Bugs lists 19 songs on the front page and Soribada lists whopping 27 songs. I highlighted the portions of the page that are related to listening to music to accentuate this point:

Soribada

Soribada-highlight
Bugs Music

Bugs-highlight
Soribada is a clear winner in this case.

2. Streaming Player

Two sites uses two totally different approach to streaming player UI. Soribada embeds the player right inside the page. Player is always there starting from the front page at the bottom and never goes away. And the player lists pops up within the page without creating a new window. This is nice that you don't have to manage two windows to find and play music.

Soribada-player

Bugs Music goes the opposite direction. When you want to stream music, it creates a new popup window that contains the player and the playlist in one view. Music will continue to play even if you close the main window that launched this player. I personally do not like this because it's yet another window that I have to manage, but I can see some people preferring this UI.

Bugs-player

I can't pick a clear winner here because this depends on your own preference. But I like Soribada better.

3. Search

Both services provide search suggestions as you type. Bugs Music provides bit more suggestions than Soribada but nothing major. But the search result page are vastly different.

Soribada, uses two column view. On the left hand side panel, it lists matched artists and albums. On the main panel, it lists all the music matches. Both columns contain links that jumps directly to the content you are looking for.

Soribada-search
Bugs Music has two column view as well. On the side panel, it lists all the category it searched and number of results under that category. When you click on the links, it filters the search results displaying only that category. On the main panel, actual results of those category is listed. But instead of listing songs first, it lists artists.

Bugs-search
It feels like Soribada cares for music more than Bugs Music. Just like in the front page, soribada makes jumping to the songs that you want to listen to easier. Soribada is the clear winner here.

I think I will be using Soribada to satiate my need for Korean musics. Only if I can figure out how to pay for it. :(


[1] I think this can be attributed to prevailing presence of smartphones like iPhone and Android devices which uses Webkit based browsers.

[2] Not really, just top 5 search results. :P

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/307790/icon2.jpg http://posterous.com/users/37loT9ujHGj7 Timothy Kim Timothy Timothy Kim
Fri, 03 Dec 2010 23:17:00 -0800 [Twitter] "I feel like someone just burned my diary" http://thingsilearned.posterous.com/twitter-i-feel-like-someone-just-burned-my-di http://thingsilearned.posterous.com/twitter-i-feel-like-someone-just-burned-my-di

A simple GET request to Twitter API reveals basic information about your Twitter account.

http://twitter.com/users/show.json?screen_name=highwind

And looking at the value of created_at will quickly tell you when your twitter account was created. As for me it was "Thu Jun 14 13:38:12 +0000 2007". Assuming that I was in Washington D.C. area, it was Thursday morning. And according to my old blog, apparently I wasn't doing much.

Out of curiosity I wanted to know what my first tweet was almost 4 years ago. So I head over to twitter.com. On my twitter profile page, only way for me to get to my oldest tweet was to just scroll scroll scroll... This got ridiculous real quick. Thinking that Twitter API should solve the problem but too lazy to read the documentation, I googled to see if anyone created a tool to find my oldest tweet[1].

First tool I came across was called Tweet Scan Backup. The service scans your tweets using Twitter API and creates a zip file of a csv file that contains all of your tweet. The service worked as it was advertised and gave me a link to download the zip file. The oldest tweet it found was from November of 2007. It was missing 5 months worth of my tweets!

Upon further googling, I found many reports saying that you can only retreive up to 3200 tweets. Anything older than 3200 was just not retrievable in any way. People were screaming their blogs off about atrocity of Twitter for not releasing their old tweets. Some people went as far as saying "I feel like someone just burned my diary". I was midly upset but not mad enough to blog about it... oh wait...

Although there seem to be reports of Twitter claiming that the old tweets are some where safe in their hidden bunkers[2], it is somewhat disturbing that one can't get to it easily. Recent Google Facebook debacle of open data on top of the Wikileaks controversy really makes you think about cloud storage. As a heavy user of cloud services, and a developer who creates web serivces that captures user data, this is an issue that cannot go ignored.

As a user, I doubled checked to see if I have a local backup of all my cloud data (which I do now, including tweets). As a developer, I must take extra caution in storing user data. I guess I shouldn't close down dickensurl.com. :P


[1] As my tweet from yesterday states, there was a tool already made.

[2] http://www.readwriteweb.com/archives/confirmed_twitter_is_saving_all_your_tweets_after.php

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/307790/icon2.jpg http://posterous.com/users/37loT9ujHGj7 Timothy Kim Timothy Timothy Kim
Thu, 02 Dec 2010 11:34:00 -0800 [JavaScript] The mystery of toString global function. http://thingsilearned.posterous.com/javascript-mystery-of-tostring-global-functio http://thingsilearned.posterous.com/javascript-mystery-of-tostring-global-functio

While browsing jQuery source, I ran across jQuery.isFunction. Here it is for your convenience:

function (obj) {
    return toString.call(obj) === "[object Function]";
}

What this tells me is that toString is infinitely wiser than typeof operator[1], and it is a global function. And since in browsers window object is the global object that all global entities get tied to, I figured window.toString exists.

But after quick googling, I couldn't find any documentation on global toString function. No where in the official ECMAScript documentation mentions global toString function. Neither does any other documentation on window object lists toString as window's method.

Just to test it out, in Firebug console I typed in toString === window.toString. This returned false. Other global functions returned true, for example eval === window.eval returned true. Thinking that this is weird, I tried it on other browsers. And to my surprise, toString === window.toString returned true in all other major browsers: Google Chrome, Opera, Safari and Internet Explorer.

Since window global object is not a standardized feature[2], I just thought Firefox was quirky in not attaching toString to window object. But after reading further into ECAMScript documentation, I finally found where this magical toString method is supposed to be.

If you read the section 15.2.4.2 of the document, it clearly states that the toString function that jQuere is using should be a method for Object.prototype object. So I quickly turned back to Firebug and typed toString === Object.prototype.toString. And it did return true! It was the other browsers that were incorrectly attaching the toString function to the window object.

Just for kicks, I checked toString === Object.prototype.toString and window.toString === Object.prototype.toString in other browsers. Here is the result:

  toString === window.toString toString === Object.prototype.toString Object.prototype.toString === window.toString
Firefox 3.6 false true false
Google Chrome 8 true false false
Safari 5 true true true
Opera 10 true true true
Internet Explorer 8 true false false

To my surprise, Chrome and Safari behaved differently. It was Safari and Opera pair and Chrome and IE pair that behaved the same. Only Firefox was following the ECMAScript standard.

Is this useful to any JavaScript programmers out there? Probably not. But it was pretty interesting. :)


[1] typeof [] gives you "object", where as toString.call([]) gives you "[object Array]".

[2] According to w3schools.com, "[t]here is no public standard that applies to the Window object, but all major browsers support it."

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/307790/icon2.jpg http://posterous.com/users/37loT9ujHGj7 Timothy Kim Timothy Timothy Kim