maanantai 13. syyskuuta 2010

Google Chrome extensions - my first experience

I have been ignoring browser plugins, not counting rare cases and adblock. Developing one has crossed my mind but there's never been a good reason to jump over the initial barrier. Today, I finally did, since a plugin seemed a sensible way to enhance a javascript application that I have been developing a week or so.

My project was to integrate existing html/css/javascript/css so that some data was fetched from a public game server. I just needed to parse a list of moves from browser's DOM. I thought first that Firefox and greasemonkey would be the best option but it seemed to me that only a single custom javascript file could be used. I don't believe that is the case for such a famous scripting engine but I didn't want to waste my time so I changed plans and headed for Google Chrome.

Chrome's basic development page was almost helpful enough to get everything done. A critical misunderstanding was cleared by founding out a question/answer from, though if I had read the whole Chrome page, I wouldn't have had that problem either.

In that site, there's sample applications that are neatly put in one page with links to API. Also the Hello world application was just what it needed to be. Overall the site is solidly done. However I would have liked also samples that weren't fully functional with particular aspect in mind. Or maybe FAQ. By the way the problem I had was opening new tab with existing resource. It was directly doable as a popup but not as a new tab. The latter needs function calls instead of configuring init file.

So how about technical side of the coin? Basically extensions work almost purely with javascript/css/html and I got my existing app to work with minimal changes. Though because of security issues, I had small inconvenience by defining a Chrome specific listener in a script that was defined in my app's html file. Maybe it's possible to work out it away, dunno.

The extension architecture looks solid: one has a background script that stays alive behind the curtains, so to speak. Message passing is in important role; you use them to localize script environment which makes sense security-wise but also forces user to separate the app into components. The API seemed straightforward and has lots of callbacks using higher order functions. It is a beautiful way to propagate events. Maybe in some cases the code can have too many inner functions but that's mainly my own fault for using anonymous functions.

Debugging felt somehow harder than normally but it's probably because I needed time to understand how things work. Anyway, Chrome's basic development tools provide enough to understand simple problems.

Public deployment of the extension via Chrome's repository would be probably easy but I haven't done that yet. I first want to make the app solid so that people won't rate it poorly. Later versions would suffer because of it.

What I gather from all this is that Chrome seems great browser for enriching the web and I intend to write small extension later since I find it fun to create a javascript application due to its dynamic nature.

perjantai 16. huhtikuuta 2010

Application's element selection and traversal based on eye movement

A lot of today's computer usage involves moving between hypertextual links. Unfortunately mostly used method is mouse which puts stress on wrist. There are some alternatives, like providing keyboard shortcuts or combinations to select the wanted element but it's not optimal.

One could imagine instead a system where eye movement was tracked. This could be done for example by using lenses that are put onto eyes (similar to those used for enhancing eye sight). The problem is how a signal can be sent without annoying the user or other problems. An infrared solution is possible, perhaps.

What I find interesting and important for a cheap solution, is that most traversing across the screen is not needed to be very accurate. One can imagine that programs would expose their elements for the application-agnostic tracking softare, and it would pattern match to nearest element, depending on what mode user had put on by keyboards. Of course, this can be automatically context-sensitive when switching between programs. For example, when browsing, the important elements are html's reference and input elements.

For the selection action, a keyboard press, or a wink of an eyelid is sufficient.

torstai 8. huhtikuuta 2010

Factorscript - jQuery and Factor proof of concept

A couple of weeks ago I released first version of Factor playground, which is a Factor language learning environment. It contains a javascript interpreter which can be used for example to draw on HTML5 canvas.

I thought it would be cool to have an interface to jQuery from the Factor interpreter so that one could script whole web page without single Javascript expression. I made a crude attempt at it, which I'll now shortly go through.

My first problem was how I can include script without putting it into Javascript string, which would be cumbersome and ugly-looking. I accidentally read an article how John Resig had done in his microtemplate Javascript: just put everything inside <script text="text/html">

Web browsers will ignore that kind of tag, and it's easy to fetch the content with ordinary DOM crawling methods when the script is given a class or id attribute.

It also seems there's no problem with having many script tags with the same class file, and that the order jQuery fetches them is from the top to the bottom, so it is possible to create dependencies between multiple script tags. For example, I created a word for modifying the css property of a div that has class "box" and put it on top.

edit: I was informed that one could create her own type for script, e.g. "application/x-factor". Thanks Chris!

The (first) jQuery interface word I show is named $2. It basically takes four arguments, value, attribute, property and selector. Selector is a string (or jQuery object), property is method name, like "addClass" or "css", attribute in our case is "background-color" or "color" and value is e.g. "green". It's all very crude at this point; we can't even query for a value from an object, which needs a javascript-to-Factor-object-translation However, we can proceed now with a new word "box-css" that uses $2.

: box-css "css" ".box" $2 ;

Next, we can set the background-color and color property by adding string values to stack and calling the just made box-css-word.

"yellow" "background-color" box-css
"blue" "color" box-css

This will be transformed into simple jQuery call such as 

$(".box").css("color", "blue") 

and similary for background-color. There are also words for method calling that have only one or zero arguments, $1 and $ respectively. Instead of $, $1, and $2 there could be just $. It would take an array containing the arguments for jQuery call. I guess that would make the code more readable.

The interesting case is when we want to add an event to elements.We need to delay the interpretation of user specified computation, which in Factor is called a quotation. In our case we want to get a reference to the jQuery object $(this). We can achieve this by creating a quotation with named parameter that pops the value from stack which is put there by the interpreter.

[| this |
  "calculation_click" "addClass" this $1
] "click" ".calculation" $$
So in the above we have selector for class "calculation", and event named "click", and a quotation to be executed when user clicks suitable element. Notice we have used $$ to bind the event with quotation but we also have another jQuery call inside that quotation. It takes "this" as parameter but it can be named however one likes, since the name is just a local variable. Moreover, there is no problem to reference "this" many times inside that quotation; so multiple changes to an element is possible in one go.

In conclusion, I have shown how to use an embedded language interpreted with Javascript to manipulate DOM. 

Beware that it uses Javascript's eval a bit, so you might want not to read content from another sites. The implementation is also slow since the emphasis will be on educational aspects, at least for some time.

The demo can be found here:

tiistai 9. maaliskuuta 2010

Virtual desktops with content pull from update queue

I'd like to be able to quickly glance over all the content updates on my apps. For example, if I'm coding in one virtual desktop, and different friends would send me messages via IRC, and Skype. A widget should notice that there's certain kind of updates available, and I would be able to pull those updates to the current virtual desktop as a preview window. Just by pressing one key I could go through all the updates and quickly interact with them.

I think this would lead to some kind of efficiency improvements, and could be quite neat. Here's the idea in a bit more detailed way:

lauantai 6. maaliskuuta 2010

The pure lie of Haskell (ghc)

When I stumbled upon Haskell, I was so impressed with the concept of its purity. Functions that don't have IO types in their signature, are guarenteed to be side effect free, and are called pure. You can trust that when you evaluate a pure function with the same arguments, you will always get the same result and that nothing suspicious happens under the hood, e.g. ejecting DVD out of your computer.

Here's a quote from Real World Haskell (which is great, btw).
Haskell strictly separates pure code from code that could cause things to occur in the world. That is, it provides a complete isolation from side-effects in pure code. Besides helping programmers to reason about the correctness of their code, it also permits compilers to automatically introduce optimizations and parallelism.

That is what most Haskellers brag about. But they don't mention that in the (only?) viable industrial strength compiler (GHC) let's you to by-pass this with evilness called unsafePerformIO

Its type is IO a -> a  
Basically, it let's you to perform an IO action in an pure context. Also, it's not even type safe as the documentation points out.

I must say I have been quite angry once I found about this, although it doesn't seem to concern others as it doesn't affect much the everyday use of the language.

I think it would be nice to have a compiler option for checking that unsafePerformIO or any other hack is not present in any used code path. This would be important for example when one setups a public environment to evaluate Haskell code. It also would drop the risk of getting malicious code from open source library you are including in your project without the need to manually check (or grep it).

Of course, I'm not denying the need for unsafePerformIO, it's just that it ruins the whole beautiful idea in one quick shot. There is no way to enforce pureness because of it.

One way to make the situation better would be to require modules to explicitly document functions that (transitively) are using backdoors. That way the type system would work as always, but at least people would know the risk via documentation.

At least, the morally right thing to do would be to mention unsafePerformIO when one introduces Haskell, as it's a little cheap to sell something that isn't there. Luckily, the separation of IO and pure code is still very useful in practice as it guides to better division of programs, and one needs to be explicitly aware when she's breaking the rules.

perjantai 5. maaliskuuta 2010

Introduction for the curious

Hi, I'm Henrik.

I'm quite enthusiastic about programming. Recently I've been studying Haskell, Clojure and Factor, which all are sophisticated functional programming languages. All of them have distinct philosophies behind them, and coding in them twist your mind into different dimensions. Haskell has powerful static type system. Clojure is dynamic in nature and has macro facilities. In Factor code operates on implicit stack.

So one thing what I'm going to talk about is features and quirks of those languages. Occasionally I probably will also discuss the current trends in software industry and maybe the possibility of alternative education. We shall see.

Lastly, I would like to suggest you some reading and videos: recommendations and advanced topics
You can also find more about me in my homepage.