Friday, August 31, 2007

Javascript scoping and this

Javascript has been a surprising language, mostly because the difference between my experience with it now, and when I touched it in high school. Going along with the theme of seeing everything as the proverbial functional nail, there's been a bunch of things to get use to, such as how scoping work works in javascript.

Javascript is a lexically scoped language (scope determined when function is defined, not when it's executed). This much, I think I get.

However, unlike Java and C++, "instance methods" of Objects doesn't include attributes in its scope. One has to explicitly refer to it. So let's say I have something like the code below. Just something simple, where one wants to process each element in a list. Of course, one can do this with a for loop and it wouldn't be an issue, but since playing with Ruby, I've found that iterators were more clear when writing code. It's probably bad design, but for the sake of argument, let's say that tile's draw() method takes the Renderer object as an argument.

function Renderer() {
this.tiles = new Array();
}
Renderer.prototype = {
draw: function() {
this.tiles.each(function(tile) {
tile.draw(this);
});
}
};

This will not work, because apparently, "this" inside the anonymous function of each() doesn't refer to renderer, but (I think) to the anonymous function. So draw() will usually complain something about how the renderer doesn't have the right properties.

This is a bit odd, since this would work in Ruby. The only way I've found around this is just to throw "this" into a variable, then refer to that variable.

function Renderer() {
this.tiles = new Array();
}
Renderer.prototype = {
draw: function() {
var my_renderer = this;
this.tiles.each(function(tile) {
tile.draw(my_renderer);
});
}
};

According to javascript's scoping rules, this works. But to me, it looks rather ugly. Anyone know of an easier way to get around it?

Monday, August 27, 2007

Using Firefox 3 as a XUL runtime environment

Using Firefox 3 as a XUL runtime environment

Some other post about it

This tidbit is actually rather exciting. Firefox uses a rendering engine that reads XML to determin how its user interface is laid out. And now that they're going to release it as a runtime environment, it should be possible to create desktop clients like one develops for the web. So instead of an API like Swing, or the like, you have a declarative language for rendering layout for desktop applications.

In addition, it should also be possible to transmit user interfaces from application to application and platform to platform more easily with such a declarative language for layout. I imagine being able to drag and drop interfaces from your desktop to your mobile device as a metaphor for "taking things with you."

I'm sure other people that have been paying attention in this field saw this coming for a while. Adobe's AIR (Adobe Integrate Runtime) is aiming specifically in this field. We'll see how this plays out, but likely, developers will choose one or the other for a specific strength, and each will have their own niche. You can try out Firefox 3's current alpha. It's been much more stable in the last couple of weeks.

Sunday, August 26, 2007

Using anonymous functions inside functions

I was reading an article on Javascript and its use of first class functions. I'd quote it if I could find it again, but basically, it extolled the virtues of being able to create anonymous functions, blocks, and closures easily in Javascript. One of the things that it claimed was that creating local functions only used within a method makes the code much more readable. I was skeptical, but as I was refactoring this function, I thought I'd give it a shot even though I was coding in Ruby. Ruby also allows for the creation of first class functions.

It's just a helper function that generates a bookmark button--however, what gets generated depends on whether a user is logged in and whether a user had already bookmarked the page.
  def bookmark_button(page, user, indicator_id)
if page.bookmarked_by? session[:user]
"Bookmarked!"
elsif page.done_by? session[:user]
link_to_remote image_tag('heart_add.png', :height => 16, :width => 16) + " Bookmark again!",
:url => { :controller => :bookmark_list, :action => :add, :page_id => page.id },
:loading => "Element.toggle('#{indicator_id}')",
:complete => "Element.toggle('#{indicator_id}')"
else
link_to_remote image_tag('heart_add.png', :height => 16, :width => 16) + " Bookmark!",
:url => { :controller => :bookmark_list, :action => :add, :page_id => page.id },
:loading => "Element.toggle('#{indicator_id}')",
:complete => "Element.toggle('#{indicator_id}')"
end
end

Well, I thought it was pretty straightforward to read, though half of it was duplicated code. It wasn't very DRY. So instead of fudging around with another way to structure the control flow, I tried my hand at using blocks. I ended up with this:
  def bookmark_button(page, user, indicator_id)
bookmark_link = Proc.new { |label|
link_to_remote "#{image_tag('heart_add.png', :height => 16, :width => 16)} #{label}",
:url => { :controller => :bookmark_list,
:action => :add,
:page_id => page.id },
:loading => "Element.toggle('#{indicator_id}')",
:complete => "Element.toggle('#{indicator_id}')"
}

if page.bookmarked_by? session[:user]
"Doing this"
elsif page.done_by? session[:user]
bookmark_link.call("Bookmark again!")
else
bookmark_link.call("Bookmark!")
end
end

As you can see, I put the link_to_remote() code into a block, since the only difference between the two is the label. In addition, it is possible for the block to use variables that are in this method, but outside the block, even if the execution is outside the scope of this function, if the block is ever passed outside of bookmark_button. I know in javascript, this causes memory leaks in IE. I haven't heard that it's a problem in Ruby yet.

But in this case, I'm just creating a function inside a method to make things more readable and cleaner. I think for the most part, it worked pretty well. As long as it's not overdone (notice I didn't create a proc for the labels), it should make for more readable code, and you don't pollute the class namespace with methods that are only used in this one method. I should get use to this. tip!

I'm quitting Eclipse, like people quit crack

I'm finally swearing off Eclipse with my Rails development. When I first started using Eclipse with Java projects, it was admittingly pleasant, once you get use to how to set it all up. Colors everywhere, as well as trees to keep organized, and automatically run ANT.

Then I started using it for Rails, because of its relatively low learning curve with RadRails. And with a Subversion plugin called Subclipse, I was hooked.

Well, the honeymoon has ended, I've finally swore them off. I'm on a computer that only has 512MBs of RAM, which really should be more than enough. One could argue, "Just get more RAM!" However, Eclipse eats up more than 140MB of memory. Add that to Firefox 2's voracious appetite for memory (about 120MB until I changed the settings to get it down to about 80 to 100MB), and my computer often slowed to a crawl. having to wait more than a second for anything interrupts my train of thought. I get bored waiting, and often sidetracked--I get knocked out of my zone.

It's been a long time coming, but I've finally switched to command line SVN. It's just that any tutorials I've found were too long winded. This recent one at the top of google's rankings, isn't bad at all. In addition, the bug in Rinari, an emacs mode for Rails, got fixed. So the two reasons to stay with Eclipse is no longer around.

Even though it takes forever to figure out how to change any setting in emacs (like freaking font size!), I figured it's better for me, as I've gotten a bit comfortable in Rails. I need to keep expanding and learning--so if I have to do anything in emacs in the future, I'll have to learn elisp.

The contrast is amazing. Emacs only takes up 4.3 Megs. Switching between different Desktops doesn't take forever now, watching the screen re-draw in slow motion.

I hear rumors that Firefox 3 has better memory management. Thank goodness. It's no longer the lite browser that just popped up. I liked it better when it was more responsive. Granted, they've crammed more stuff into it since they've started, but it shouldn't keep eating up memory to the point of crashing! I'd be looking forward to that. In the meantime, I'll enjoy all my memory breathing room.

Thursday, August 23, 2007

Review of Facebook app building experience and where things might go

I've been missing in action for a while, because during the first week of August, I finally got around to figuring out how to build a facebook app. I'm involved with a non-profit organization that wished to create an alumni database. I had written a prototype for them the year before in a week, but I never put it up. I didn't get the help or traction that I had hoped for, so I delayed working on it until this past summer, when they had another summer conference.

It's a good thing too, because facebook didn't release their full API until around May. The app is a good fit for what it needed to do, since it allows alumni to find each other. I hacked it out in 4 days, which was both good and bad. I had to bypass a lot of the discipline and good habits I cultivated on my own projects in order to whip it up.

The hardest thing about facebook apps is simply figuring out how the whole thing hangs together. When you don't know the thing is put together, filling out the long form to setup your facebook app, becomes difficult as nothing makes sense.

There are two major parts to a facebook app. One is a profile box, which is the draggable box you see in people's profiles. And the second is the canvas page, which is a kind of "home page" for your app, if you will. You application is hosted somewhere else outside of facebook. The API just lets you create an interface in facebook. It's my recommendation that you read this page on architecture in the facebook wiki before getting started on any of the "Getting Started" pages.

As you can see from the ASCII diagrams in the architecture page, your application's canvas page is called by proxy through facebook servers. That means every time someone visits your canvas page through facebook, facebook will pull your application's canvas page and display it. Conversely, the profile box is data that is pushed to the facebook servers. This makes sense in two faces of the same coin. Facebook has a LOT of users, and chances are, you can't scale as facebook has. Having lots of people bang on your server out the door would wreck havoc on you. Secondly, facebook doesn't want its profile load times to depend on 3rd party servers. If it has all the information pushed to it, facebook can quickly serve profile pages without having to rely on the latency of its 3rd party applications.

I won't go through how to make a facebook app. Plenty of places already do that well, especially this one for Ruby. However, to give my review, I will say that I give it 3 out of 5 stars. "A" for effort, but there's more improvement to be had down the line.

While the API is a step in the right direction, coding for it has felt clunky at best. This is mostly due to documentation being a bit all over the place, but especially the lack of a test environment. There is no way to set a production, test, or development environment for the same application. The only way is to simply create another application as a "test", and point it to your development machine. Then in your code, it has to switch between the development API key and the production API key. In Rails, you'd use the RAILS_ENV global variable to determine which environment you were in. As a result, there's quite a bit of setup to do before you can start hacking away.

Facebook also provides FBML, a reduced HTML, specific for facebook elements. Some of them are quite handy, such as a friend finder, and it gives you an immediate look and feel that blend in with the rest of facebook. However, debugging it isn't much fun at all. Since you can't set environments, facebook assumes all apps are production, and therefore will not show errors and stack traces. Therefore, one has to tread softly, or cut and paste back and forth to their tools.

That's right. Tools. Facebook does provide tools to test out your FBML and API calls. But it would be much nicer if it were integrated in a development environment for the application.

All, in all, it's not been too bad of an experience, outside of wrestling with the setup and FBML, but there's a lot of improvement to be had. While many have said that Facebook is a walled garden like AOL was in the 1990's, I currently don't see much of a decentralized social network solution that addresses privacy that is popular amongst developers.

The only thing that is a remotely good candidate is the combination of OpenID with Microformats like XFN. But I think it's going to take a demonstration from another successful startup to get more developers on this bandwagon. OpenID is also not yet ubiquitous as a concept in the minds of developers, let alone the common web user. Once this happens, it will be much much easier for social applications to personalize a user's experience right out of the box.

And this isn't personalization based on where your stats, but personalization based on what your other friends have done in the very same application. The web app won't know anything about where you live, or where your friends live, but if it's a book store, it will know everything about what books you like, and what books your friends like, and be able to draw conclusions to better serve your experience based on that.

I hope that is an indication of the things to come. Apps will know more about a user's habits as related to their function, and yet not know who this user is to protect privacy. This will be especially useful with mobile devices, since we carry them with us. Any mobile application that knows if you come into contact with your friends in real time will have a tremendous utility value in producing information useful in a social context. We still have to wait, however. The mobile industry is still not as open as we'd like for open development on mobile devices as a platform.

As an aside, I imagine that the reams of data (anonymous, of course) would be a great boon to social scientists. We might see a revolution in that field, especially if it's combined with decentralized computing concepts.

Wednesday, August 22, 2007

How to find your way along the tracks

I started helping out with the local Chicago Ruby scene. It was a small meetup group, but I was asked to do a small presentation on how to get started in Rails. Radiant CMS apparently gets things up and running quickly, so there is a blog for the group.

I wasn't able to make it to this one, so I recorded an mp3 of the talk as well as slides. (as a side note, I remember Zenter allows for slides and recording...but it wasn't up since their acquisition by Google.) Apparently, it went well. Thanks to Ray for getting on the ball with it. Many hands make light work.

At the next meeting, I'm to take the group on a splunking adventure through the rails source. It'll be a bit of work remembering what I was doing at the time, but it should be ok. I just need to make sure that I'm on the ball with everything that I'm doing.

Thursday, August 16, 2007

The new YC.news

This ended up to be a long comment on YC.news, now turned Hacker news. I figured it was worth reposting here on my blog:

When I was working at an engineering job at a research lab, I was told what had to be accomplished. Of course, the degree of freedom, amount of creativity, and problem solving you can do varies from project to project, but in the end, I went to bed happy knowing in the back of my mind that someone, somewhere asked for whatever you're working on--that's why you're getting paid. When you're a startup founder, however, you aren't even sure of that, mostly because of the nature of startups and the markets they decide to persue.

A startup can be successful in an already crowded and proven market--especially if the market sucks (online dating comes to mind). But often times, where startups shine is where others fear to tread, and that's in potential markets, unproven markets, and useless markets (until you prove that it isn't).

But how do you figure that out? And given that you see a potential, how do you find a creative solution to build a business from it?

I don't think anyone can tell the future when it comes to these things. But you can certainly learn to get a good intuition for it. One of the ways to do that is to constantly read broadly about interesting things that are going on in the fringes of any number of industries. By interesting, I mean, things that you didn't know that stretchs your understanding of the world and perhaps your imagination a little bit more. When you start to get your finger on the pulse of possibility, you're able to see blooming solutions where others only see wilting dead-ends.

In addition, when you dig deep enough into any topic, it gets quite interesting. You'll start to find that all subjects are intertwined in one way or another. The way all subjects are compartmentalized in school is just so students don't get confused. But really, all subjects are inter-related. Sociology's studies on coordination and biology's study on social insects actually relates to optimization. Weather phenomenon actually relates to crytography. This inter-relatedness works to your advantage in finding creative solutions to make a business out of your new market, because creative things are usually a combination of old things put together in new ways.

Contrary to popular belief, creativity isn't often completely out of nowhere, just as masterpieces don't just materialize in front of masters. For every masterpiece you see hanging in the galleries, there are hundreds of sketches and throwaway paintings that you don't see the master artist practicing on. By the same token, a creative solution for a startup isn't just a stroke of inspiration from nowhere. It's a culmination of a slow absorbing of interesting tidbits that you've gathered and processed in the back of your mind until you've put the relevant pieces together.

So as far as I can tell, Paul Graham views hackers that are startup founders not as just really really good programmers. He believes what makes these people good startup founders is their innate curiosity in the world around them, and the willingness and drive to keep on learning about it to produce and create solutions--which lead to profit if attacked in a business way. That not only drives their strengths as programmers, but as thinkers and builders that change the world and will make money doing so. Not trying to put words in his mouth, but that's my best summary thus far.

Therefore, if you buy into that, then I think the direction into the new YC news as Hacker news is a good change. It will allow people to keep seeing and learning interesting things so they have a better gut for potential and emerging markets, as well as helping them along in their creativity for novel solutions. That is, at least my take on it.

Of course, we'll see how it actually all plays out, but I for one, am looking forward to the change.

Thursday, August 02, 2007

Parallel array processing with zip()

When I'm working in Ruby, it's a blast, but a lot of the concepts are borrowed from functional style programming, and I'm not sure what things are called. Often times, I end up writing the same boiler plate code over and over again, refactoring it into a function that I add to the standard library on my own, while knowing there's probably a built-in function to do that. It was like that with inject(). Today, I discovered zip().

I run into this particular problem when I want to line up arrays with one another, and perform an operation on the same corresponding element of each array--much like a parallel map function. For example, vector addition and multiplication is like this. When you add arrays, you take the the nth element from each vector and add them together.

Usually, I write something like this:
a,b = [1,2,3], [2,3,4]
class Array
def parallel_map(b)
result = []
each_with_index do |e, i|
result << yield e, b[i]
end
end
end

a.parallel_map(b) { |ea, eb| ea + eb }

Which is pretty ugly, as I shamefully admit. However, due to the post I last mentioned about Erlang, as well as this post on Ruby talk, I (finally) made the connection that there's such a function in ruby, and it's (also) called zip().

The solution then would look something like this:
a.zip(b).map { |i, j| i + j }

MUCH better. That means something like dot_product is a lot more elegant now.
def dot_prod(a, b)
a.zip(b).map { |i, j| i + j }.inject { |t, e| t += e }
end


To be honest, I've read the reference API on Ruby's enumerable, array, and hash libraries before. However, at the time that I read zip(), I was thinking, "I'm not sure when I'll ever need to do that.", and just put it out of my mind. :P
tip!