Archive

Quick Test

Here’s a very simple question:

How many times can you subtract 5 from 73, and what is left ?

Find out what your answer means by clicking here.

  • An imperative programmer answers, “you can subtract it 14 times and the remainder will be 3.”
  • A functional programmer answers, “you can subtract it as many times as you wish, and you always get 68.”

Improve

« Nobody’s perfect », they say. We all wish for improving ourselves in some areas. Want to lose some weight? Become a better dancer? Spend less time debugging your code? Sound smart in meetings?

There are three exceedingly simple steps to improving yourself. These are, in order:

  1. Identify what you are doing, precisely, that you would rather not do anymore.
  2. Find a way to stop doing whatever you identified in step 1.
  3. Gather enough willpower to follow the way you found in step 2 until you succeed.

Now go forth and conquer!

What?

Fine. I said those steps were simple, not that they were easy. They can still be helpful, though: even if you cannot seem to improve, at least you can find out which of these steps is giving you a hard time, and concentrate on that specific area.

You need to stop

There are always two ways of looking at any given improvement. You either see it as “I started doing something“, or you see it as “I stopped doing something“. Improvement is change, and change means something ends and something else begins. You start being a good dancer, you stop trampling your partner’s feet. You stop writing buggy code, you start spending less time debugging.

We bloggers love splitting people into groups: you are either a can’t-start person, or a can’t-stop person. If you want to quit smoking, but always end up lighting another one, you are acting as a can’t-stop person. If you want to exercise daily, but always find a good excuse not to run your laps, you are acting as a can’t-start person. And you had better find out which group you are in.

Because if you are a can’t start person, and you think of potential improvements in terms of starting doing things, trouble is coming your way.

Step one is all about looking at your problem from the other side. To start doing things right, you need to stop doing them wrong. As you stop making mistakes, what is left usually counts as improvement.

food_anotherslice

Ask and accept

Some humans are blessed with the ability to see, in a clear and unmistakable fashion, what went wrong about something. Enlightenment comes in a slap-your-forehead moment where the root cause of your problems is discovered.

Most of us experience trouble as a hazy and painful feeling that seems to come from everywhere at once, with no clear cause and no clear idea of how things ended up the way they did. If you cannot really understand what you are doing wrong or why you end up in trouble, consider asking someone else.Whether an expert opinion, a different angle on the situation, or the act of putting your issues in words and sentences, you will get something out of it.

This reminds me of Bob. When I was still a young intern, without much experience in the ways of men, an older developer joined my team. Despite his reasonable technical skills, Bob had a conflictual relationship with our manager, and this had a negative impact on team morale. I had been told our manager disliked it when people were late for work, even though he did not insist on the matter too much, and my experience with him confirmed that information. Since Bob was at least fifteen minutes late every morning, I decided to share that information after a quite gruesome clash, thinking it would help :

“You know, he gets angry when people are late. If you can’t come in earlier, you really should tell him about it.”

What do you mean? I’m not late.

You came in at 9:25 am this morning.

No way, I came in at 9:00 am!

I suspected that Bob, out of pride, would deny being late in the morning, but that he would mull over the notion and come in on time the next day. I was wrong, and he was thirty minutes late the next morning.

It is very important to carefully examine any criticism before rejecting it. When someone you know takes the time to explain that you’re doing something wrong, the least you could do is wonder if they are right, or why they thought they were right. Criticism is free advice, carefully selected to apply to whatever you do that annoys others most.

Even if Bob really was on time every morning, my advice was still worth considering because it indicated that some people thought he was late, which is quite important in a corporate environment.

Mental triggers

Once you have identified what you need to stop doing, you can move on to step two: find a way to prevent it from happening. Since you cannot keep thinking about it all the time (and even if you did, it would reduce the efficiency of whatever else you were doing), you need to find a way to remember about your decision when it actually matters.

If you experience a feeling when you perform the unwanted action, you happen to be in luck, because it is far easier to associate your decision to stop with that feeling.

While I have always been comfortable in one-on-one conversations, I used to have a lot of trouble speaking up in groups, because I tend to take a short time to think before I speak, and this means someone else in the group is going to start speaking before I can gather my thoughts. If there were pauses in the conversation, I could certainly pass off as the wise experienced guy in the corner who only speaks up when nobody knows what to do anymore, but most of the time I looked like the shy silent guy in the corner who has nothing to contribute to the discussion.

I noticed that most people who spoke up in group discussions said things that were mostly irrelevant and generally only served as an anchor to remind others of what the position and motives of that person were. A precious few people, however, seemed to always grab the attention of others and say something interesting and relevant. Among these was Jamie, a nice lady in her mid-thirties. After observing her for a while, I noticed a pattern in her way of speaking up: she would repeat the last sentence that was said.

…and we should test if the government servers can handle the load.

Test if they can handle the load, yes. I just received a report about…

By repeating the sentence, she was able to start speaking faster than anyone else, and she used that time to think about what she was about to say next. Not to mention that repeating someone’s sentence implies some level of agreement, which is always good to have in a meeting.

So I started training. Whenever I missed my turn in a conversation, I felt frustrated, which reminded me of my decision to use Jamie’s technique. So, on the next try during the same conversation, I did not think silently about what I had to say and instead repeated the last part of what the speaker said. After a while, I did not have to think consciously about it anymore.

Without a feeling to anchor your reminder to, you will have to find something else.

One trick is to artificially increase the time before you can take the unwanted action. For instance, I live in a flat in Paris and my fridge is a ten-second walk away from my desk, so it’s easy for me to stand up and fetch a quick snack without thinking. I once spent my holidays with a friend who lives in a large house in the countryside, where the fridge was two floors below my appointed room and it took a full minute of navigating slippery stairs and cold, narrow corridors before I could get to said snack, which means I never got to eat without thinking. The longer it takes you to start an activity, the greater the chances that you notice “Hey, I’m about to do this, and I decided I wouldn’t do it anymore!” and desist from doing it.

If the activity is continuous (such as “not washing the dishes“) you can try to make the consequences of that activity as obvious as possible. If the house (or source code) is a mess, then adding small amounts of messy laisser-aller are unnoticeable. If the house (or source code) is cleanly arranged and organized, any amount of mess is going to stand out and be very obvious. It is easier to keep a house or project clean, than it is to clean it up later on.

The will to go on

Finding enough willpower to enforce your decisions can be hard. A good strategy is to know your weaknesses and exploit them. For example, if you hate mediocrity and often think that “I’m worth better than that“, then thinking of unwanted activities as shameful and worthless can give you that little boost you need.

You can even shame yourself into respecting your decisions by telling other people about it. Ask other people to look over your source code daily, even if it’s not an actual code review, and you will often be too ashamed to leave undocumented methods and badly named variables around.

<div xmlns:cc=”http://creativecommons.org/ns#” about=”http://www.flickr.com/photos/avlxyz/2684089255/in/set-72157606283805523/”><a rel=”cc:attributionURL” href=”http://www.flickr.com/photos/avlxyz/”>http://www.flickr.com/photos/avlxyz/</a> / <a rel=”license” href=”http://creativecommons.org/licenses/by-sa/2.0/”>CC BY-SA 2.0</a></div>

Javascript Tips, Part 1

It is advised, when deploying a live website, to group all your Javascript files into a single one, and reduce its size by removal of all unnecessary clutter. You obviously get a few nasty surprises the first time you do this, such as dead code (or debug-only code) being included or two incompatible files being included together. The usual answer to this, like with any integration-related issue, is to perform continuous integration, and generally make sure during development that the final product works as it should.

Tip #1 — Keep it all together

I generally keep all of my javascript together in one single file, which is accessed through http://domain/all.js or something like that. Of course, that file is in fact generated from a well-tended garden of neatly arranged source files, but the intent is that every single visit on the development website will bring along all the code that could possibly conflict with it, to identify issues as soon as possible.

This means I have access to a Javascript preprocessor, because generating a single file already involves reading all the files.

Tip #2 — Conditional inclusion

Difficult bugs appear on platforms with  no debuggers, which means you need to be able to track the progress of your application with logging. You don’t want to have those log lines appearing on the live website, though. In the same way, runtime assertions are useful while developing, so you get a clean “Expected string, got array” error message right after you call a function with incorrect parameters, instead of a “object has no member charAt” ten stack layers deeper. Yet, assertions use up room, and tend to die in a flashy and unprofessional way on a live website.

An overly intrusive preprocessor can prevent your code from running if not preprocessed. It also means whatever tool you use to edit Javascript source cannot recognize the syntax anymore, which is bad. The solution (which I learned from the PHP preprocessing techniques of the folks at IntellAgence) is to embed preprocessing information in comments.

Need some logging?

/*<*/ log('Hello'); /*>*/

Need to check something at runtime?

/*[*/ Assert.areEqual(x,y); /*]*/

A simple regular expression can remove these from the final code, but you can also selectively disable them by removing the second slash of the first comment :

/*[*  Assert.areEqual(x,y); /*]*/

Tip #3 — Named anonymous functions

Quick reminder: Javascript allows you to define anonymous functions using a lambda-like construct:

function(x) { return x + 1 }

This acts like a function literal (pretty much like a string literal works for strings, or an array literal works for arrays). In fact, if you’re doing any kind of serious Javascript, you probably have anonymous functions all over the place, such as callbacks to asynchronous operations:

$('button').click(function(){ alert('Hello') });

Or you might be defining member functions for your classes:

className.prototype.setFoo = function(x){
  this._foo = x;
};

When you get a runtime error, the debugger displays a stack trace containing the names of the functions and the places where they were called. So, if you were using many anonymous functions, you get neck-deep into layers of “anonymous” on your stack trace. Sure, you can click on every single one of them to understand what is happening, but it is way faster to get that knowledge from looking at meaningful names.

Javascript allows you to give names to anonymous functions. In fact, this is how recursive functions can be defined as lambdas (a feature that OCaml lacks, for instance). So you can write the following and see it appear in a stack trace:

$('button').click(function _onButtonClick(){ alert('Hello') });

className.prototype.setFoo = function _className_setFoo(x){
  this._foo = x;
};

I start all names with underscores, because a simple /function _[A-Za-z0-9_]*/ in my preprocessor can identify and remove all those names when I don’t need them.

Tip #4 — Are your callbacks called?

The Javascript function model lets you write a function that forwards whatever it was doing to another function. You can even log some information along the way…

function trace(f) {
  return function () {
    log('%o.%s(%o)',this,name(f),arguments);
    return f.apply(this,arguments);
  }
}

The preprocessor instructions for conditional removal let you do this only in specific circumstances:

className.prototype.setFoo = /*[*/ trace /*]*/
(function _className_setFoo(x){
  this._foo = x;
});

It can also be quite practical to use a variant of the trace function that stores all functions it traces in an array, and removes them from the array the first time they are called. This can be useful when debugging calls to asynchronous functions that you write, because you might forget to call the callback function when you are done, and these bugs are otherwise quite hard to identify.

Tip #5 — Do not rely on closures too much

Closures in Javascript means you can write this, and have the inner function use the variable from the outer function :

function outer(a) {
  var b = a + 1;
  return function inner(c) {
    return b * c;
  }
}

Closures are extremely useful. However, Javascript has a nasty habit of creating variables at global scope whenever you try to write to a variable that doesn’t exist. For instance, the following function is not re-entrant because an accidental typo makes it use a global variable :

function person() {
  var aeg = 18;
  return {
    setAge : function(a) { age = a },
    canDrink : function() { return age > 20 }
  }
}

A good solution, I believe, is to rely on object members instead of variables. Inappropriately using an object member is harder than inappropriately using a local variable, because the former does not default to “look in the global scope”. Besides, every function beyond a certain level of inner state complexity deserves to be adapted to a more structured object style with its data as private members (if only because this is way easier to explore with a debugger).

Google Me!

What does a google search for my name tell people about me?

  • Obviously, I own this website.
  • I have LinkedIn and Facebook profiles.
  • I don’t really participate on Stack Overflow or Wikipedia a lot.
  • I wrote some articles on GameDev.net, which were repeated around on the web, translated to other languages, helped people, and were published in books.
  • Also, I have been participating on the GameDev.net forums for quite a while.
  • I wrote a Master’s Thesis [pdf] in finance in 2007 (namely, market microstructure and game theory).
  • I wrote another Master’s Thesis [pdf, french] in 2007, this time in computer science (GPGPU using CUDA, to be precise). I ended up presenting that work at Calyon (an investment bank) in early 2008.
  • Back in 2006, I wrote a course evaluation system for one of my schools (the Paris School of Economics). It worked, but the code is certainly not something I’m proud of.
  • Back in 2005, I worked on a grid computing framework in C#, NGrid.
  • Also in 2005, I was an intern [pdf, french] at Exalead on bayesian classification of web sites.
  • I play role-playing games and was the main contact for the RPG society at the Ecole Normale Supérieure. I also ran for treasurer [pdf, french] of the entire student association in 2006 (I was not elected).
  • I dabble in Objective Caml randomness and have some thoughts about programming language design.
  • I use Magento.
  • I work for Tangane (and wrote some stuff on their blog).
  • People find it funny when I mention condoms.
  • I used to be a TA in computer science, some of my old papers are still floating around and being linked to.
  • I once played Diplomacy. I’m not a very good player. :(
  • I regularly play Magic : the Gathering. I’m not a very good player either. :(
  • I was present at the Mobility Party 2004, back when I was a developer with int13 (working on Darklaga). I remember playing Half Life 2 for the first time at that event.
  • I signed a petition against Verisign. You sign one petition, and it remains online forever—I have been much more careful about what I do online since then.
  • I wrote small novellas in an even smaller literary society. Actually, I had started writing in college in a (parody) student newspaper [pdf, french].
  • When in school, I worked at the student help desk for windows users on my spare time.

All these are actual links you can find in a google search for “Victor Nicollet”.

If you look deeper (that is, using your brain instead of google), you could also find:

  • Extatica (page is down, though it’s still present on this list). A C++ 3D game engine I wrote back in 2003. Took the website down after I received a Cease & Desist from Extatica (my google ranking exceeded theirs). Ironically, on the latter page, there’s a link to a website where the DLL for my old engine can be downloaded.
  • N’improtequoi, an improvisational theater group. I am their webmaster, as well as a team member.

I don’t really know which is scarier—that so much information about me is available online, or that nobody seems to care about it? :)

Do It Yourself

Unless you’re working in an esoteric field on the bleeding edge of technology, the vast majority of programming problems you face have already been solved many times by many other people, and several of these solutions are readily available on the web or in legacy code libraries you might have access to.

To solve a problem, you can

  • reinvent a particular wheel : the non-factored approach, since you create your own instance of that wheel,  or
  • reuse one of its existing implementations : the factored approach, where several projects benefit from the same piece, including your own.

Both alternatives have costs and benefits that the experienced software engineer is aware of, and these will depend on your exact problem somewhere along the lines of :

1

The time spent solving a problem steadily increases with the size or difficulty of that problem, and is further subject to two important rules.

Non-factored is cheaper for small problems

A factored solution carries some overhead because it is used by several projects with different scopes. The “one click, 200 words” bias happens when non-technical managers hear “leverage an existing solution”, and see a picture of a one-click installer and a 200-word tutorial telling them their particular problem can be solved with two lines of C# code.

HolyGrail grail = new HolyGrail();
grail.doWhatIMean(/* No options here! ^_^ */);

Yeah. Riiiight.

Every one of us has spent days reading up on third party libraries just to decide if they are worth the effort, slaying compatibility dragons to make it talk with the rest of the project, filling hundreds of configuration options that have no relevance whatsoever to the tiny problem at hand, teaching co-workers about the nooks and crannies of that code, and painstakingly wading through less-than-civilized error reporting to solve the obtuse problems that come up on the day before you release.

Even writing your own reusable code is orders of magnitude harder than just jotting down a quick one-shot solution to whatever problem you have. An excessive tendency to build generic code from the very beginning makes your development process look like Dragon Ball Z : you have to power up for fifteen episodes before you can show a splash screen.

This rule is the reason why the red curve stays above the blue curve for small problems.

Factored scales better for large problems

Solving a larger problem involves a larger solution. In a do-it-yourself situation, you have to make the solution larger yourself. When using a factored approach, you already injected an existing large solution into your project, and it only feels small because you’re using a small part of it. With the programming equivalent of flipping a switches, you get to use a larger part.

The solution that involves the most code (the non-factored one, in case you wondered) also involves the most maintenance, documentation and development work. Whether this comes from a thousand-line reinvented wheel or obscene copy-pasting, having a large code base is something you will have to pay for in the long run. You don’t buy code, you rent it.

This rule is the reason why the red curve ends up above the blue curve for sufficiently large problems.

Keeping these two rules in mind, the key to making the right decision is determining where the red and blue curves intersect, and where your project stands. Easier said than done. For instance, what does “problem size” mean, precisely?

Problem size can be, literally, the size of the problem for an obvious metric. A content distribution network like Amazon S3 is a bad choice for 1000 downloads per week, but an obvious solution for 1000 downloads per second.

Could be the things in the application that are similar to the one you’re implementing. Sending usage statistics back to your server is a small problem solved with a vanilla HTTP request. If you communicate with the server a lot, you might want to keep the URL and error handling logic together in one place.

Or it could be the number of features. Displaying data in table format takes two nested loops and some HTML. Sorting, filtering, asynchronous sending or editing involves some rather smart Javascript development, or integrating a tool like jqGrid or ExtJS.

Once, Twice, Refactor

The special case of writing your own reusable code has been “solved” by Agile folks who suggest writing a non-reusable version of the code on the first try, and refactoring it to a reusable version the second time it’s needed. This is your third choice : go with the non-factored solution if you are unsure whether the problem is large enough to warrant the factored solution, and change your mind as soon as you gather enough data.

2

This is a solution that costs less than the factored approach if the problem is small, and costs less than the non-factored solution if the problem is large, while keeping an acceptable overhead when the problem is somewhere in-between.

Of course, writing your own reusable code means that the cost of switching from the non-factored to the factored version is significantly lower than starting with the non-factored version from scratch, because you refactor the original solution into a reusable one.

The advantages are not so obvious when moving from one approach to the other involves throwing away all code and installing a third party application. You do get some benefits—at the very least, you know more about the problem that you did at first, and perhaps your first approach served as a useful prototype to further refine your needs—but doing this can hurt a lot.

So, you end up getting hurt if you don’t know what you’re doing. What a surprise.

Happy Birthday, Pizza!

A year ago, I ordered a €9 pizza from Speed Rabbit Pizza, a Paris-based pizza delivery chain. A meal was had by me. Verily.

pizza

The next evening, I received a text message on my cell phone about a promotional 3-for-2 offer from that very Speed Rabbit Pizza outlet. I had made the mistake of giving them my cell phone number, because they wanted to call me if the pizza delivery man got stuck in a door. I have been receiving such weekly reminder messages every week for an entire year . And since they also had my home address, they could even send me promotional envelopes by mail.

I am quite protective of my personal contact information, and actively avoid doing business with any company that contacts me without my permission, so I have taken my business to Pizza Hut instead.

Total money made by Speed Rabbit pizza from me: €8.53 (without tax)

Total money spent by Speed Rabbit pizza on sending me promotional messages: 52 × €0.07 (text messages) + 5 × €0.7 (postal mail) = €7.14 (without tax)

Total money earned by Pizza Hut because Speed Rabbit sent me promotional messages: around €105 (without tax)

Making your blog post look like a Mastercard ad: priceless.

Can references be null?

I often hear people insist that C++ references can be null.

You can easily create a null reference like this:

int *ptr = 0;
int &ref = *ptr;
// ref is a null reference

First, there is no such thing as a null reference in standard C++.

Like all programming languages, C++ is purely a construction of the human mind, and the concepts of the language have been given arbitrary but meaningful names as part of the standardization process so that the users of the language could understand each other. These could be existing words such as class, aligned, statement, pointer or new ones like rvalue or cv-qualified.

In particular, the C++ standard does define a null pointer, but it does not define a null reference because that concept is not part of the language.

This means that instead of having a standard definition (like a null pointer), null references have a commonly accepted definition that follows a similar schema: a null reference is a reference r such that &r is a null pointer. For the rest of this article, I will follow this definition.

Second, a null reference cannot exist in a well-behaved program.

Since the concept does not appear in the standard, it’s pretty obvious that no place in the standard explicitly mentions an operation resulting in a null reference being constructed. In fact, the description of how references are constructed explains that references are constructed from other values, and by definition values cannot have a null pointer for an address.

In particular, the typical construction of a null reference by dereferencing a null pointer is explicitly mentioned in the standard, and described as undefined behavior.

In short, while many modern implementations will let you create a null reference, this will necessarily involve some form of undefined behavior along the way.

I tend to evaluate programmers on a “would I hire this person?” basis. So, what does the “C++ references can be null” statement tell me about someone ?

  • They might be confusing C++ references with C# or Java references, which can be null. Certainly a NO HIRE for a senior C++ programmer.
  • They might have misread their textbook and genuinely think references can be null in the same way as pointers (except, well, the lack of syntactic sugar for checking if a reference is null or creating a null reference strikes me as odd if that were the case). Again, NO HIRE for a senior C++ programmer.
  • They know it’s not standard, but they do not care about writing standard programs. This is an immediate NO HIRE even for junior C++ programmer.

Then, there are those who know about it, and would not use it because they care about writing standard programs. The convention when discussing C++ is to assume that the program is well-behaved, so most people would parse “C++ references can be null” as “C++ references can be null in a well-behaved program”, the latter being obviously incorrect. I don’t really mind a small misunderstanding, the subject being as complex as it is, as long as it’s corrected quickly.

A person who does not is either someone without much experience discussing C++ with others, or a troll. A definite NO HIRE on a team.

Heterogeneity

John is a fairly adept PHP developer. He is familiar with object-oriented features from PHP 5, has experimented with some PHP 6 features, and is quite skilled at bending the Zend or Symphony frameworks to his will.

But John is not really an SQL expert—sure, he might have written some simple queries and he can fight his way around a normalized database, but he’d rather use a mapping layer on the PHP side. He is no fan of JavaScript either, although he can sometimes hack together a quick solution based on his limited knowledge and online tutorials. And John is in trouble, because web development is ultimately a heterogeneous environment where you have to know three languages to get things going.

There have been many efforts to help out programmers like John by eliminating as many languages as possible from the process. Database mapping tools provide a protective layer that shields SQL-averse programmers from the unfathomable Lovecraftian horror of INNER JOIN. Ready-made components encapsulate clever JavaScript so that server-side developers don’t have to muck in the demeaning task of keeping browsers in line.

I’ve had the pleasure of working on both sides of the fence. Some of my projects were beautifully streamlined 98% PHP – 1% JS – 1% SQL works of art where the various pieces of non-PHP code were carefully hidden away from the prying eyes and trembling hands of PHP developers. Others had a complete architecture designed for each of the three languages, with team members that specialized in certain areas only, and strong conventions on how data had to cross the borders. These were not toy projects, but rather large websites that had to support the brunt of thousands of visits.

The bottom line is that when you’re running a website with the intent to get money out of it, you want as many daily hits as possible, and so the software must be able to handle all of them smoothly. If you are writing your own web software, the burden of optimizing that software is yours as well. This involves identifying bottlenecks and reimplementing them to do less work, so that you will eventually need:

  1. Developers that are familiar enough with the software and any third party elements involved.
  2. Profiling tools that help identify what parts of the software take the most time.
  3. A software model that is flexible enough to allow reimplementing critical pieces.

It is generally observed that [weasel words] the layers of PHP/C#/Java code stacked to hide away the SQL/JS/CSS/HTML underneath will decrease the performance of the software, because databases are queried with SQL and web pages are presented in JS/CSS/HTML regardless of what one-language programmers would like to believe, so the layers end up generating that code themselves, often with hilarious results.

A classic example would be server-side code for displaying a list of objects (displayed here as PHP):

$user_id = Controller::getCurrentUser();
$user    = UserFactory::getById($user_id);
$friends = $user -> getFriendsList();

foreach ($friends as $friend_id) {
  $friend = UserFactory::getById($friend_id);
  View::renderUser($friend);
}

This is an actual excerpt from a piece of code I wrote, with only slight rewording of certain components. A naive implementation would result in a first query reading from the database the data for the current user (with a list of 200 friends), then 200 more queries reading the individual users from the friend list. This results in a slow-loading page, a dead database and an unhappy customer (believe me, I’ve tried). The PHP-only programmer answers with a blank stare, because the code is properly written and well-encapsulated.

Now, here’s the million dollar question: can your mapping layer be configured so that the above code can get all the data in one, two or three queries?

The project I that code is coming from relied on Zend_Db for database work, which could hardly be called anything but naive. The optimization approach was to place a caching layer between the user factory and the database, and configure that layer with rules such as “if the developer calls getFriendsList, the next time UserFactory::getById is called, precache the data for all the users returned in the list of friends”. This meant that only two queries were made, which happened to save the day on that particular project.

Still, my point is not whether your favourite ORM can achieve the same performance as hand-written SQL code. Some of them certainly can.

My point is that to write software that has database interaction as a bottleneck, you need programmers that understand the database interaction layer thoroughly. Whether that layer is a PHP/C#/Java ORM or plain old SQL requests is irrelevant—without knowledge of how data is pulled from the database, there will be no way to prevent or eliminate bottlenecks reliably.

The ORM system Foo can eliminate the need for SQL experts, but it creates the need for Foo experts instead. What is important, then, is whether it’s easier to find Foo experts or SQL experts.

Gremlin : jQuery Growl

I have uploaded Gremlin, a simple jQuery-based Growl system, for elegant page-wide notification needs. Check it out, it’s free and built to be simple.

Javascript signals

Signals operate as a simple way of decoupling dependencies within a project, by allowing caller-callee relationships through an interface that makes both parties anonymous. Assuming a shared signals object is provided, the receiver registers itself on that object:

signals.output = function(text){ alert(text) };

And the sender uses the registered channel to remotely execute that function:

signals.output('Hello');

Signals are the functional equivalent of object-oriented inversion of control, a technique that allows users to configure the behavior of third party code without having to modify it. This is done by removing any explicit dependencies of the third party code on specific behavior units, such as “output a piece of text”, and injecting those dependencies back from the outside as an object or set of objects which hide the actual implementation of those behavior units. Basically, we’re replacing:

function frobnicate(a,b) {
  foo(a);
  bar(b);
  alert('Success');
}

frobnicate(1,2); // Can't prevent the alert box from appearing!

With the slightly longer but easily configured:

function frobnicate(a,b,output) {
  foo(a);
  bar(b);
  output('Success');
}

frobnicate(1,2,function(t){alert(t)}); // Original behavior
frobnicate(1,2,function(){}); // Muted function
frobnicate(1,2,function(t){console.debug(t)}); // To firebug console

Since a given piece of code might depend on several distinct behavior units, I use a record to transmit all that behavior as a single argument. This results in the classic “configure my library with your options object” that can be found, among other places, in jQuery.

This simple approach causes a small number of difficulties:

  • If I want to use a slightly different version of a signals object for another part of the program, I have to manually create a copy of the object and change the copy (basically the equivalent of a pure functional object mutation).
  • In some situations, I might want to handle several callbacks for a single signal. The current approach only lets me define a single function for a given signal.
  • Some functions of the signal set (such as sending a form through AJAX) might rely on other functions of the signal set (display an error message) to handle their own behavior unit dependencies, and I would like those functions to automatically have access to the signal set they belong to, dynamically.

This leads me to a subtly different implementation of signals:

signals = (function(){
  s = function() { this._c = s; };
  s.prototype.channel = function(c) {
    var h = [],
        s = function() { for (var k in h) if (h[k]) h[k].apply(this,arguments); };
    s.bind = function(f) { h.push(f); return h.length-1; };
    s.unbind = function(f) { h[k] = null; };
    return this.set(c,s);
  };
  s.prototype.set = function(n,v){
    var i = function(){ this._c = i; };
    i.prototype = new this._c();
    i.prototype[n] = v;
    return new i();
  };
  return s;
})();

This small class encapsulates pure functional mutation semantics by means of its set function:

var signals = new signals();
var initial = signals.set('xxx',100);
var final = initial.set('xxx',200);
console.log(initial.xxx + ' ' + final.xxx); // Outputs '100 200'

This small piece of behavior is in itself quite helpful, but it gets better: if a function is added to the object, it remains there but is always executed within the context of the current object and therefore has access to its actual values.

var signals = (new signals()).set('show',function(){console.log(this.xxx)});
var initial = signals.set('xxx',100);
var final = initial.set('xxx',200);
initial.show(); // Displays 100
final.show(); // Displays 200

Last but not least, it’s possible to create a full communication channel that can be connected to several receivers and forwards its arguments to all receivers.All receivers are called with the signals object as their context, which lets them access it and behave accordingly.

var unreadMessages = 0;
var signals = (new signals()).channel('setUnread');

// Update the number of unread messages, notify user if they have
// new messages.
signals.setUnread.bind(function(unread){
  if(unreadMessages < unread) this.notice('You have new messages!');
  unreadMessages = unread;
});

// Update all places that display the number of unread messages
signals.setUnread.bind(function(unread){
  $('.unread').html('Messages'+(unread > 0 ? ' ('+unread+')' : ''));
});

// When at page scope, notices are printed by growling
var global = signals.set('notice',growl);
global.setUnread(10);

// When inside a smaller scope, such as a component, display notices in
// a dedicated location
var local = signals.set('notice',function(arg){$display.html(arg)});
local.setUnread(15);