Monday, December 21, 2009

On plants and veganism

Interesting article. I've read pieces about various curious plant mechanisms before and it's funny to see that journalists like to make plants look vivid like animals when telling their stories.

The fact that we empathize more with things that look the most like us is probably no surprise, but it's interesting that we project that bias towards our food phylosophy: we normally consider chicken slaughterhouses gruesome, and yet boiling some chopped onions for soup is perfectly fine.

The irony of onions making us cry is almost poetic.

Tuesday, December 15, 2009

A nice CSS typography trick

I just found out there’s a fairly obscure, but cool syntax to declare line-heights in CSS:

.mytext { font: 12px/14px Arial; }

Notice the slash and the second pixel value. The rule above defines the text to be Arial, 12 px, with a line-height of 14px. It’s short, sweet and it even works in all browsers!

Note, though, that this should be used mainly as a typography trick. For aligning forms and one-off elements, I’d still advise using the regular line-height property to avoid re-declaring fonts everywhere.

With that being said, it’s worth mentioning that most design and typography blogs use higher-than-default line-heights to great effect, as the extra bit of spacing between the lines of text makes content look more classy. For example, look at alistapart.com or smashingmagazine.com and try disabling the line-height via firebug to see the difference :)

So, in summary, those 5 extra characters can go a long way in giving a static site an extra oomph.

Wednesday, November 25, 2009

Opera 10.20 widgets

Widgets now don't need an Opera window to be open. I should play with this when I get some time.

Thursday, November 19, 2009

Friday, November 13, 2009

CSS sniff table

Got tired of googling for this. Yeah, yeah, yeah, I know about conditional comments and graceful degradation and all that. I'm a web developer ffs.

Wednesday, November 11, 2009

Monday, November 9, 2009

Small lisps

I don't normally link to aggregators, but ah, what the heck.

Friday, October 2, 2009

Monday, September 28, 2009

Quote from Douglas Adams

People now looking at the way in which rice agriculture works in Bali are rather puzzled by it because it is intensely religious. The society of Bali is such that religion permeates every single aspect of it and everybody in that culture is very, very carefully defined in terms of who they are, what their status is and what their role in life is. It's all defined by the church; they have very peculiar calendars and a very peculiar set of customs and rituals, which are precisely defined and, oddly enough, they are fantastically good at being very, very productive with their rice harvest. In the 70s, people came in and noticed that the rice harvest was determined by the temple calendar. It seemed to be totally nonsensical, so they said, 'Get rid of all this, we can help you make your rice harvest much, much more productive than even you're, very successfully, doing at the moment. Use these pesticides, use this calendar, do this, that and the other'. So they started and for two or three years the rice production went up enormously, but the whole predator/prey/pest balance went completely out of kilter. Very shortly, the rice harvest plummeted again and the Balinese said, 'Screw it, we're going back to the temple calendar!' and they reinstated what was there before and it all worked again absolutely perfectly. It's all very well to say that basing the rice harvest on something as irrational and meaningless as a religion is stupid - they should be able to work it out more logically than that, but they might just as well say to us, 'Your culture and society works on the basis of money and that's a fiction, so why don't you get rid of it and just co-operate with each other' - we know it's not going to work!

via

SICP videos

Here

Tuesday, September 15, 2009

WEIRD

Goes to show why extrapolating is usually bad. (I just love the WEIRD acronym, btw)

Friday, September 4, 2009

Programmer reads

There goes my long weekend. A compilation of nice articles for anyone who writes code.

Wednesday, September 2, 2009

Friday, August 28, 2009

Tuesday, August 25, 2009

Friday, August 21, 2009

Tightening screws

Kinda funny how everyone was talking about web developers sucking / not sucking, and then someone pointed to this on Reddit: Guido basically giving up on CSS.

I read a comment by Josh Powell on this article that was resonated with me:

Whenever I hear people insult web developers, I remember the time when I was in the workforce for only one year and some java developers came up to me and said "we can't get this whitespace to go away in ie, but it isn't there in netscape" I went over and took 30 seconds to fix it, and afterwards they said "We spent hours on that! How did you know how to fix it!?!" All their knowledge of garbage collectors, destructors, compilers, etc, didn't help them remove the spaces between the last character on the line and the start of the ending td tag.

You may not think that's a big deal, but trust me, lots of real world clients could care less about what gc algorithm you use, but they will have your neck if you can't get their site looking like they want it in IE.

The whole thing reminds me of this one tale:




Once upon a time, there was company that had a big expensive machine that was critical to their business. One day, without much explanation, the machine buzzed and ground to a halt. They tried to restart it, they tried all the usual maintenance protocol. Nothing was making it start again. Management grew nervous. They were losing money for every minute the machine was down. They frantically searched high and low for anyone who could fix it.

After a long week, they finally found one technician who specialized in fixing that particular machine. They rushed him in to the corner of the factory, all the high executives trailing anxiously behind him.

The technician calmly opened a shaft, and looked at the unimaginably complex circuitry for 5 minutes. He reached into his toolbox and grabbed a tiny screwdriver, and then, without much effort, tightened a single screw. "Ok, turn it on, boys", he declared.

The executives looked at each other, a mix of hope and disbelief in their eyes. If the machine was down for a few more days, they'd literally go bankrupt. The workers powered the machine and, stunningly, it started working as if not had ever happened. Everyone rejoyced. With one flick of his wrist, the technician had saved the company. "I'll be on my way then", the technician said, humbly.

The next week, the company got the invoice for the technician's fix. It looked like a ordinary invoice printed in ordinary paper, except for one detail: the amount payable on the invoice was $10,000. A bit disconcerted, the managers called him to get some clarification.

"We believe you made a mistake on your invoice. We were all there when you fixed it and we saw that all you did was tighten one screw."

"You are correct that I only tightened one screw, but you're mistaken about one thing. I don't charge for tightening screws. Anyone can do that. I charge for knowing which screw to tighten."




Obviously not everyone is an unsung hero, but I think the world sure would be a nicer place if people stopped the whole holier-than-thou crapola.

Sunday, August 16, 2009

Mixins in Java

Rather neat framework, leaving aside that I personally would not implement UI on a business logic class.

Status anxiety

A video by Alain de Botton.

Thursday, August 13, 2009

Centmail

Am I the only one who, within seconds of reading this, thought "Centwitter"?

What people spend money on

Just to put things in perspective, think about the budget of hollywood movies and large TV networks. Now look at how much money moves in the real estate, insurance, health care, food and energy industries.

But we already knew that.

Interestingly, reading has its own slice (albeit small). Does that mean it's much more prevalent than other forms of entertainment? Or was there a reason to not group it under entertainment (or possibly education)?

Pascal's Wager

Wikipedia.

A point of view.

Another.

Atheist's Wager.

So much just for saying "be nice".

Wednesday, August 5, 2009

How would you map a map?

This occurred to me today. Imagine we have a list of things.

list = [1, 2, 3, 4]

Given that we have a mutation function "fn", how do we change all of the elements in the list with that function?

If we're just using idiomatic procedural code, we'd use a loop, but since we're fancy smarty pants, we're gonna use higher order functions. Like so:

map(list, fn)

Then the function could have the following arbitrary mutation algorithm:

function fn(x) {return x * x}

Nothing exciting so far.

But the data structure I want isn't a list. It's a map. You know, a list of key-value pairs. How do I map that?

My previous function no longer works because I need to be able to work on the key, as well as the value. The problem is that I can only return one thing. What do I return? The value? The key? A pair?

function fn(k, v) {return [k, v]} //two inputs, infinite output arity

Well, we'd have to follow some sort of convention to get around that infinite arity problem. Even in Java, we could potentially pass a null instead of an Entry and then you'd get a null ref exception inside the map function. Not very nice.

Would it be ok to just give up and throw an error? Hmm. Maybe. If there's no other option, I guess that'd be ok.

Oh, I know, what if we had two mapping functions?

map(myMap, keyFn, valueFn)

Then I can guarantee that I'll get reasonable arities.

function keyFn(k, v) {return k * k + v * v} //one input, one output
function valueFn(k, v) {return k / v} //one input, one output

Is it mathematically possible to have logic that cannot be split into two functions? I'm thinking if we start introducing closures and side effects, things would probably get weird, but I can't really picture how. Can anyone think of a way where this API would fail spectacularly?

Tuesday, August 4, 2009

Thoughts about C# regions

I was playing with my toy parser over the weekend, and was deciding what the syntax to handle large blobs of arbitrary text should look like (for dealing with heredocs, wysiwyg strings, comment blocks, that sort of stuff). I was just about settling for a mix of ideas from Python and some ramblings from one of my older blog posts, but then it occurred to me that there is one type of comment that is unique, implemented in a mainstream language, and that has even created heated debates in some corners of the 'tubes: C# regions.

The debate is that regions are considered by some programmers to be evil. If you're not familiar with the debate, this article presents the point of view that regions are bad, and this other one presents the view that regions are helpful.

My thoughts

Regions do two things:

  1. They create code folding points so that the editor can hide code
  2. They allow those sections to be briefly described by snippet of plain english

I can see why people would argue about the code folding, but at the end of the day, whether you fold your code or not is a personal preference. I'm actually a bit surprised that people would resort to proclaiming the feature evil before, you know, finding that there's a way to turn off code folding in Visual Studio. You'd think software developers would be good at using software. I digress.

The problem with regions that no one seems to talk about (in my opinion) is that the regions aren't usually very informative. They do give me some information, but not a whole lot. Let me elaborate.

Generally, I see regions being used to separate different types of class members: methods, properties, events. Or publics and privates. I suppose that is fine when the code does tend to be event-driven (and a lot of the .NET API is). Spend enough time with that convention and you'll subconsciously learn that you'll find the scope of stateful data within a "Member Variables" region, and that code entry points are likely to be in the "Constructor" or "Events" regions.

My gripe is that this isn't normally written out explicitly in idiomatic #region usage. You have to have this sort of mind map.

Another unfortunate thing is that I find inconsistent organization sometimes: I'd open a region to find this huge list of folded methods. Which ones are top-level functions? Which ones are helper/shared/refactored functions? Which ones are called within tight loops? From which functions? Are there more methods hidden in an almost-invisible region sitting just below the fold in my editor viewport? Why aren't the rest of the methods grouped inside a sibling region as well in that case?

Back to Earth

Now, obviously, a lot of that of that is largely a matter of style, personal preferences and knowing the conventions, but I feel there's still some aspects of regions that are worth exploring.

The debate I mentioned earlier briefly says that methods should be refactored when they are too long. But what does that actually mean in terms of code folding?

By definition, refactoring a large block of procedural code yields a bunch of small functions. Heck, the toy parser I'm working on does exactly that.

The caveat is that refactored-out functions normally have a hierarchical relationship to the function from which they were extracted from.

Imagine we have a parser with a parse function that can call parseNumber and parseString. The function parseString in turn can call parseEscapedString and parseHeredoc, and the parseNumber can call parseHexadecimal and parseImaginary.

So far we have 7 functions and the logical way to group them looks more like a binary tree than a flat array of functions. We could create a "string" region and a "number" region, but that essentially leaves the parse function floating naked by itself in a sea of meta information:

#region parsing functions
public void parse() ...
  #region string parsing
public void parseString() ...
public void parseEscapedString() ...
public void parseHeredoc() ...
  #endregion

  #region number parsing
public void parseNumber() ...
public void parseHexadecimal() ...
public void parseImaginary() ...
  #endregion
#endregion

Which would fold like this:

#region parse
public void parse() ... <- this looks ugly :(
  [+ string]
  [+ number]
#endregion

We could put that parse function in a region of its own, but that doesn't make a whole lot of sense either. Hmmm.

It'd be neat if we could write this:

#region parsing functions
  #desc entry point
public void parse() ...
  #region string parsing
public void parseString() ...
public void parseEscapedString() ...
public void parseHeredoc() ...
  #endregion

  #region number parsing
public void parseNumber() ...
public void parseHexadecimal() ...
public void parseImaginary() ...
  #endregion
#endregion

Then, this made-up #desc would fold the parse function like so:

#region parsing functions
  [+ entry point]
  [+ string parsing]
  [+ number parsing]
#endregion

And while we're at it, let's go a step further. Let's add #desc's to all the functions and allow a folding mode that looks like this:

[+ parsing functions]
  [+ entry point]
  [+ string parsing]
    [+ strings w/ escape chars]
    [+ heredocs]
  [+ number parsing]
    [+ hexadecimals]
    [+ imaginary]

That would look a lot cleaner. It basically looks like a table of contents. Maybe I'll do something like that for my toy parser.

Wednesday, July 29, 2009

Some thoughts on password input visualization

I've been seeing a few of these things floating around. Supposedly, they make it easier to figure out if you typed your password correctly just by glancing at a hashed graphic representation of the password.

My first thought is of the eating-your-own-dogfood type: how do you type your password? Do you actually look at the screen as you're typing? Do you click the button or press enter to submit? If the latter, do you pause before pressing enter? Can you easily override your muscle memory and not press enter if, say, you feel you see one less * than what you think you should see? Well, maybe you're a geeky freak. Ask your friends the same questions.

Another thing that I'm wondering is whether the whole thing is redundant. Why do you need to visualize your password? Did you make a mistake? Were you not aware that you may have made a mistake?

And one last thing. What was the last ad you saw about? Chances are you didn't even see it. What makes a graphic feedback icon any different? It's very easy to miss things that you aren't expecting. For example, I often miss a "check user ID availability" button when signing up for a free game simply because it's just a bit off of where I'd expect an interactive piece to be next.

I don't know about anyone else, but I don't really care about hash strength and all that crap people throw around to make themselves look smart in HN or whatever. If people really wanted to get your password, they would. There are so many non-cryptographic ways to do it, it's not even funny.

What matters for an UI experiment is that it plays well with users' behaviours: I type my passwords looking at the keyboard and press enter by muscle memory. I subconsciously dismiss things as visual noise when they are not absolutely required to the task at hand.

So far, the password visualization experiments I've seen don't address any of those behaviours.

Friday, July 17, 2009

Bullying

What the hell was wrong that school? o_o

Since everyone is talking about their experiences now, here's mine too: Sometime in the first month of high school, I bit the guy's finger (I was actually trying to rip it off). Then life was nice and quiet.

Tuesday, July 14, 2009

Why give software away?

Zed Shaw on his choice of licenses.

I still don't get why people would want to give stuff out for free. It's one thing to collaborate with random programmers who are interested in the same technology as you, it's quite another to be Mother Teresa.

Friday, July 10, 2009

What is a browser?

I should do that sometime.

Digg and IE6

Now we can point to this whenever someone makes yet another one of those obnoxious upgrade warnings.

Wednesday, July 8, 2009

Tuesday, July 7, 2009

Surfing with the aliens

So, I was playing with my old radio and by some strange stroke of fate, I stumbled across some sort of alien communication channel. Apparently they look like what we know as unicorns: four legs and a horn on their heads.

By tweaking the frequency knob just a bit, I was somehow able to access and understand their fantastic intergalactic Extertube(tm) network, where apparently millions of these aliens can share information at the speed of thought.

I listened avidly. Some of things I learned about them is that their numbering system counts the number of legs plus the horn, kinda like how we humans count the 10 fingers in our hands. Counting for them goes like this: 0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, and so on.

I came across a particularly lively discussion involving their strange numbering system. The question: Is 0.444... == 1?

So basically, is a zero followed by infinite fours the same as one? Well, not in my planet.

But wait, if their 10 is equal to our 5, their 11 is equal to our 6, their 12 is equal to 7, and so on, what the hell is their 0.444... equal to anyways?

I scribble some math in my trusty notepad. Is 3 / 2 equal to 0.444...?

 3 | 2  I can fit one 2 in a 3
    1

 3 | 2  but I still have a remainder of 1
-2  1   let's put a dot and add a zero
 1      to the remainder like my 1st grade teacher taught

 3 | 2  There.
-2  1.
 10

 3 | 2  Ok, so 5 now, right?
-2  1.5 Wait. They don't have a 5.
 10     Their 10 is worth 5.
        Argh. I'm getting confused.

 3 | 2  I can fit two 2's in a 4.
-2  1.2 Two 3's would only fit in 11.
 10     So 2 it is. I get 10 - 4 = 1. Right?
- 4     But 1.2 is definitely not 0.444...
  1     This can't be right.

I scratch that and try a new fraction.

Is 1 / 3 equal to 0.444...? Scribble, scribble. No. Is 23 / 34 equal to 0.444...? Scribble, scribble. No. Is 34110 / 21300 equal to 0.444...? Scribble, scribble. No. After a bit of fumbling, I tried this:

 1 | 4  I can fit zero 4's in a one 
    0

 10 | 4  so I put a dot and add a 0
     0.

 10 | 4  now I can fit two 4's.
     0.1  Oh wait, no, I can't, because their
          one-followed-by-a-zero is actually
          only worth 5. So I can only fit one
          4 in a 10 and I get 1 left.

 10 | 4  so I have 0.1 and 1 left. Right?
- 4 0.1
  1

 10 | 4  repeat...
- 4 0.11
  10
 - 4
   1

 10 | 4  repeat...
- 4 0.111
  10
 - 4
   10
  - 4
    1

Ok, great, if I keep calculating this forever I will have 0.111... (with infinite ones). So 1/4 = 0.111... for our alien friends.

Awesome, since I know 0.111... will be an infinite number of ones (and no other number), I think I can do this then:

 0.1  0.11  0.111  0.1111...
 0.1  0.11  0.111  0.1111...
 0.1  0.11  0.111  0.1111...
+0.1 +0.11 +0.111 +0.1111...
 0.4  0.44  0.444  0.4444...

Alright! I figured out that 1 divided by 4, times 4 is 0.444...

Wait.

Anything divided by 4, times 4 is itself. Right? I try it with my super powerful Windows calculator to make sure I'm not getting confused by their weird number system.

1 / 4 = 0.25
0.25 * 4 = 1

Yeah. I'm not crazy.

Their 0.111... is the same as our 0.25
Their 0.222... is the same as our 0.50
Their 0.333... is the same as our 0.75
Their 0.444... is the same as our 1

And our 1 is the same as their 1.

Excited, I decide to share my discovery with the aliens. I tune my old walkie-talkie in the same frequency and start spelling out my calculation. 0.444... is equal to 1!

I disconnect my radio, feeling accomplished that I helped extraterrestrial beings in a intergalactic discussion. I grab some juice and decide to surf the 'net a bit to relax.

Hey, what is this? A new forum post. Apparently it's also a math question. Hah. I'm good at those. I just helped some aliens!

I rub my hands anxiously, pick my pencil and paper and start reading the question: is 0.999... == 1?

Lisp Toronto Meetup

Snap, it's starting right now!

Tuesday, June 30, 2009

Cryptool

Cryptography e-learning tool.

Ropes

I was thinking about performance for text editors the other day. This looks useful to solving the problem of responsiveness when dealing with gigantic text files.

SFML - Alternative to SDL

Supposedly it's nicer than SDL.

Monday, June 29, 2009

Friday, June 26, 2009

MIT course on multicore (with videos)

Here.

Stop password masking

Says Jakob Nielsen.

I think what he really meant to say was: "give me the option to see my password when I type it".

Thursday, June 25, 2009

Tuesday, June 9, 2009

Hackjob in production

I just noticed this snippet from the Yahoo SEM code:

<SCRIPT language="JavaScript" type="text/javascript">
<!-- Yahoo! Inc.
window.ysm_customData = new Object();
window.ysm_customData.conversion = "transId=,currency=,amount=";
var ysm_accountid  = "ABCDEF123456";
document.write("<SCR" + "IPT language='JavaScript' type='text/javascript' " 
+ "SRC=//" + "srv1.wa.marketingsolutions.yahoo.com" + "/script/ScriptServlet" + "?aid=" + ysm_accountid 
+ "></SCR" + "IPT>");
// -->
</SCRIPT>

This code is given to webmasters for both secure and non-secure URLs. Compare it to the Google analytics loading snippet:

<script type="text/javascript">
 var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
 document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>

Yes, Yahoo provides code that requests a URL with no protocol (src=//srv1.wa.marketingsolutions.yahoo.com). Talk about funky code.

Wednesday, June 3, 2009

Haibane Renmei

I watched Haibane Renmei a few days ago. I can't really tell yet if this is going to be the case, since my gut feel has a natural bias towards things I've seen more recently, but it may well become of my favorite animes.

I think there are a lot of fresh concepts and I find the slice-of-life feel of the series very immersive. There are many unanswered questions left for interpretation: the characters' origins, the geography, the rules, all contribute to provide a rich culture to the series' world. Exploring the mysteries unravels interesting theories that can add depth to the world on their own.

It's all very fascinating and stimulating. It's not very often that a series makes me pick up creative writing again. :)

Thursday, May 28, 2009

VisualVM

I just got a toy to play with tonight :)

Does it matter if immutable data is slow?

Note: this post is specifically about Java.

One thing I noticed about the benchmarks in the blog post I linked to on my last post is that the Java tests weren't wrapped in synchronized blocks (which would be a given in any concurrent program).

So I decided to modify it a bit and see how things went. Here's the code:

public final class Bench {
 public static Object mutex = new Object();
 public static Object getMutex() {
  return mutex;
 }
 //immutable
 private static final class Person0 {
  public final String name;
  public final int age;
  public final double balance;
  
  public Person0(final String name, final int age, final double balance) {
   this.name = name;
   this.age = age;
   this.balance = balance;
  }
 }
 
 //idiomatic mutable
 private static final class Person1 {
  private String name;
  private int age;
  private double balance;
  
  public Person1(final String name, final int age, final double balance) {
   this.name = name;
   this.age = age;
   this.balance = balance;
  }
  
  public void setName(final String n) {
   this.name = n;
  }
  
  public void setAge(final int n) {
   this.age = n;
  }
  
  public int getAge() {
   return this.age;
  }
  
  public void deposit(final double n) {
   this.balance += n;
  }
 }
 
 //mutable w/ public fields
 private static final class Person2 {
  public String name;
  public int age;
  private double balance;
  
  public Person2(final String name, final int age, final double balance) {
   this.name = name;
   this.age = age;
   this.balance = balance;
  }
  
  public void deposit(final double n) {
   this.balance += n;
  } 
 }
 
 private interface Test {
  double test(int iters);
 }

 private static final Test TEST0 = new Test() {
  public double test(int iters) {
   Person0 person = new Person0("John Doe", 19, 100.0);
   for (int i = 0; i != iters; i++) {
    synchronized (mutex) {
     person = new Person0(person.name, person.age + i, person.balance + 1.0);
    }
   }
   return person.balance;
  }
 };
 
 private static final Test TEST1 = new Test() {
  public double test(int iters) {
   Person0 person = new Person0("John Doe", 19, 100.0);
   Person0 p;
   for (int i = 0; i != iters; i++) {
    p = new Person0(person.name, person.age + i, person.balance + 1.0);
    synchronized (mutex) {
     person = p;
    }
   }
   return person.balance;
  }
 };
 
 private static final Test TEST2 = new Test() {
  public double test(int iters) {
   Person1 person = new Person1("John Doe", 19, 100.0);
   for (int i = 0; i != iters; i++) {
    synchronized (getMutex()) {
     person.setName("John Doe");
     person.setAge(person.getAge() + i);
     person.deposit(1.0);
    }
   }
   return person.balance;
  }
 };
 
 private static final Test TEST3 = new Test() {
  public double test(int iters) {
   Person1 person = new Person1("John Doe", 19, 100.0);
   for (int i = 0; i != iters; i++) {
    synchronized (mutex) {
     person.name = "John Doe";
     person.age += i;
     person.deposit(1.0);
    }
   }
   return person.balance;
  }
 };
 
 private static final Test TEST4 = new Test() {
  public double test(int iters) {
   Person0 person = new Person0("John Doe", 19, 100.0);
   for (int i = 0; i != iters; i++) {
    person = new Person0(person.name, person.age + i, person.balance + 1.0);
   }
   return person.balance;
  }
 };
 
 private static final Test TEST5 = new Test() {
  public double test(int iters) {
   Person1 person = new Person1("John Doe", 19, 100.0);
   for (int i = 0; i != iters; i++) {
    person.name = "John Doe";
    person.age += i;
    person.deposit(1.0);
   }
   return person.balance;
  }
 };
 
 private static double test(int times, Test test, int iters) {
  long best = Long.MAX_VALUE;
  double balance;
  for (int i = 0; i != times; i++) {
   long now = System.currentTimeMillis();
   balance = test.test(iters);
   now = System.currentTimeMillis() - now;
   if (best > now) best = now;
  }
  return (double) iters / ((double) best / 1000.0);
 }

 public static void main(String[] args) {
  final int iters = 10000000;
  System.out.printf("Immutable sync all: %f updates/s\n", test(5, TEST0, iters));
  System.out.printf("Immutable sync =: %f updates/s\n", test(5, TEST1, iters));
  System.out.printf("Mutable idiomatic: %f updates/s\n", test(5, TEST2, iters));
  System.out.printf("Mutable fields:  %f updates/s\n", test(5, TEST3, iters));
  System.out.printf("Unsafe immutable: %f updates/s\n", test(5, TEST4, iters));
  System.out.printf("Unsafe mutable:  %f updates/s\n", test(5, TEST5, iters));
 }
}

And the results:

Immutable syncing constructor14,903,129 updates/s
Immutable syncing assignment14,880,952 updates/s
Mutable with idiomatic Java18,832,391 updates/s
Mutable accessing fields directly18,832,391 updates/s
Non-synced immutable70,921,985 updates/s
Non-synced mutable322,580,645 updates/s

Interesting points to note:

  • Immutables turn out to be slightly faster than mutables when synchronization is involved.
  • Using idiomatic set/get methods directly seems to be about as fast as accessing fields directly (albeit more verbose).
  • Non-thread-safe code runs about an order of magnitude faster than the synchronized counterparts. Does that mean I need 20+ CPUs to match the speed of a single-threaded program (due to synchronization overhead)?

So is concurrency really overhyped or did I just do something dumb with the code?

Monday, May 25, 2009

JNA

Looks pretty interesting. Access to C libs from Java, without using JNI.

Friday, May 22, 2009

Dunning-Kruger and Cobra

I saw Cobra the other day and was curious about what people had to say about it. I noticed that some people are rather quick in pronouncing it "retard", "stupid", and some other not-so-flattering adjectives.

It's pretty disappointing that these people are so quick to take a scornful position when a new language comes along and it happens to be, you know, different. Or, (gasp) similar to stuff that already exists.

I guess I'll have to wait a bit more before I get to see comments from people who have actually used the language.

Wednesday, May 13, 2009

Nimrod

Looks interesting. I wonder how it interops with C.

Tuesday, May 12, 2009

DDo$

Hilarious and scary at the same time: the Pirate Bay founders are encouraging people to make small payments that incur more fees than the payment is worth to the law firm that represented the music companies in the trial.

The bank account to which the payments are directed has only 1000 free transfers, after which any transfers have a surcharge of 2 SEK for the account holder. Any internet-fee payments made after the first 1000, which includes the law firm’s ordinary transfers, will instead of giving 1 SEK, cost 1 SEK to the law firm.

Saturday, May 9, 2009

Where does the line come from?

I'm like staring at this graph and trying to figure out where that line came from. Are they hiding the other countries or did they just pull a convenient line out their asses?

Thursday, April 30, 2009

Clojure

I've been seeing quite a few jabs at clojure lately. Sometimes I wonder if people actually tried to use the things they claim to hate.

On a related note, there's a book about it in beta now. I hear it's geared more towards Java programmers than CL ones - which is a plus imho since CL users are apparently (at least from the attitudes I've seen) the best thing since sliced bread :)

Maybe I should go buy the book.

How bad is the Swine flu so far?

Swine flu - 9 deaths so far.

Heart disease - 34 deaths in the last second.

Hmmm.

SHA-1 collisions down to 2^52

Heh.

Overreacting

They might as well kill everybody to prevent regular flu, car accidents and alcohol related deaths...

Tuesday, April 28, 2009

Rails drama

So there was this presentation in a conference that was sorta inappropriate and some people that got offended, and a then things sorta derailed a bit (no pun intended).

On the comments of a rant post, the presenter rethorically asked what is it that makes IT less friendly to women. He says:

"Try asking young teenage girls why they don’t want to become software developers. Again I’d be surprised if they say, because of the macho environment."

Well, so would I. We can't just ask people to explain out what they feel is a cultural issues. On the off chance that they are actually able to explain out in words what the root of the phenomenon is, there's still the chance that people involved in that culture won't agree with the conclusion that there is a problem to begin with.

On a somewhat related topic, I never really understood why is it that some people feel compelled to associate software with this idea of "end of a journey": being a rock star, being a ninja, whatever. You don't see rock stars calling themselves "ninjas". Does being a real life programmer suck so much that we need to pretend to be something else? Where's the focus? Where's the pride?

Miracles and rationality

Old blog post, but interesting nonetheless.

The definition of miracle seems rather fuzzy, imho.

On the one end, people say splitting a sea in two is a miracle. On the other, gravity and tides are known natural phenomena and it is theoretically possible to split a sea in two, given that a bunch of highly unlikely events happen simultaneously and someone is paying attention.

Often, an event is called a miracle because it's very personal, e.g. a loved one surviving cancer or a gruesome accident. I'd say the explanation for these cases just happen to be beyond comprehension, but not they're certainly not necessarily beyond the forces of nature.

There are those who say that miracles are things that can never happen because there are very specific scenario constraints, e.g. walking off the top of a building and expecting not to turn into a flattened pancake. But hey, it can be done. Voluntarily, at that.

I tend to be pragmatic and go more by the street usage of the term miracle (i.e. that it can happen), so I figure that since miracles only escape our understanding but not necessarily laws of nature, yes, we can be rational and believe in miracles.

As the saying goes, I only know that I know nothing.

Friday, April 24, 2009

Watching TV

nod nod.

Fake stuff

So someone set out to show that you can get away with spreading misinformation quite easily in Twitter.

There was a rather famous similar experiment in Youtube, and of course, fake people in social networking sites are nothing new.

Having a shred of a scientific mind (i.e. automatically calling bs on everything) seems to be becoming more and more useful in this age of information overload.

Wednesday, April 22, 2009

QuelSolaar

Looks like a neat 3D modeling tool for games.

Something is missing

Looking at my RSS aggregrator, I came to a realization, it looks an awful like what a newspaper or magazine would: lots of catchy headlines for topics that interest me. The difference is, of course, I choose where the headlines come from, whereas news go through editors. So, there's an certain inherent bias to what is presented to me via RSS, and there's a different bias to what news make the final cut on a newspaper or magazine.

What is common about both is that this bias converges into a culture of sorts. There's a certain level of expectations from things that appear on News.YC, and there's a certain level of expectations from things on the New York Times. The great thing about the Internet is that there's enough choices out there to make a pretty varied selection; the sucky thing is that we're stuck with them once we make them. (Well, not really, but let me explain what I mean).

As Malcolm Gladwell says in his TED talk, you can't really ask people what they want. We don't know what we want, we only know if we like what we have or not. Out of sight, out of mind.

The thing about content (at least for me), is that "how-much-I-like-content-from-any-given-outlet" is a bell curve: there are some great things and a lot of useless junk. The catch is that this applies to stuff outside of my preferred cultures as well. Meme sites usually irk the hell out of me and I'd not want one in my RSS aggregator, but I can't deny that they do have some pretty nice content every once in a while (considering what the intentions of meme sites are, anyways).

Do you see where I'm going? We are stuck with the choices we make in our readers because we're asking the wrong question: what is the perfect culture for me? There is no perfect culture. Only many noisy ones with some perfect content (and there may or may not be a correlation between the culture's voting patterns and what would actually please me). My netvibes page wouldn't know that though. All it can do is map one culture to one portion of the screen.

One could say that content aggregators would solve the problem, since they grab the best of all worlds, but, again, look at News.YC. It obviously has a very strong culture. You'd never see a clever lolcat picture with a great geek culture reference in News.YC. Similarly, you'd never get a paper about JVM internals on StumbleUpon. It seems every site develops a culture by virtue of its own history of posts, even when they encourage randomness.

How does one develop a fitness function that takes Internet content as an input and that evolves into a filter that gives me what I like (as opposed to giving me stuff that is roughly in the direction I expect from a given culture)? Is that even possible?

Sometimes I wish my aggregator had a magic "Surprise me with something nice" button. But I have no idea if the fitness function to power it can even be done. I must be missing something.

Tuesday, April 21, 2009

Small world

I stumbled upon this talk again. Funny thing, a co-worker just recommended Gladwell's book when we had a casual conversation about my MSN message. Small world.

Variable interpolation in javascript strings

I came across this fairly old attempt at making variable interpolation work in javascript.

The conclusion was that it could only be made to work with object properties or global variables.

But as it turns out, we can make interpolation of local variables work:

var expand = function(string) {
 return '"' + string.replace(/"/g, '\\"').replace(/\{/g, '"+').replace(/\}/g, '+"') + '"';
}
new function() {
 var hello = "hello world";
 alert(eval(expand('say "{hello}"')))

 var quote = '"';
 alert(eval(expand("a quote looks like this: {quote}")))
}

I'm not checking for escape sequences for curly braces, but adding support for that shouldn't be too hard.

Monday, April 20, 2009

WYSIWYG Strings

You may have noticed that lately my posts have been related a lot to programming language syntax. That's because I'm playing with a parser right now.

I've been thinking about WYSIWYG strings and heredoc strings.

There are at least a dozen different ways of denoting a string, each with it own limitations: The common quote delimited strings with escape sequences become unreadable when there are too many escape characters, heredocs can't be written in a single line, strings with exotic delimiters (like D's backquoted strings) are vulnerable to delimiter collision.

I like heredocs because their flexibility makes it possible to avoid demiliter collisions in just about every possible scenario (except random infinite strings), and multiple quoting, which looks like a compact variation of heredocs (except that we can't make a string with one of every possible character).

<<HEREDOC
some text
HEREDOC

qq^some text^

I also like Ruby's "<<-" heredoc, which allows the end token to be indented, as well as YAML, which lets the body of text itself to be indented.

  <<-HEREDOC
some text
  HEREDOC

  - text: |
      some text

How can we mix all of these together? Something like this (note the indentation)?

//Multiline:
//standard idiom
  @@
  some text
  @

//handling edge cases
  @HEREDOC
  email@email.com
  HEREDOC

  @@@
  email@email.com
  @@

  @#
  email@email.com
  #

//Single line:
//standard idiom
  @@:some text@

//handling edge cases
  @HEREDOC:email@email.comHEREDOC
  @@@:email@email.com@@
  @#:email@email.com#

So basically, an "@" followed by a heredoc token followed by either a colon or a line feed, depending on whether you want single line or multiline. Indentation characters up to the level of the closing token are discarded from the actual string's byte array.

Do those examples look readable? Would they play well with common indentation patterns in actual code? Would you be able to guess what the syntax is if you didn't know it?

Another random idea

How about we interpolate this heredoc notation into a regular string via an escape sequence?

"here's an example: \@@:"""some python doc comment about the backslash ("\")"""@"

"here's another: \@@@
"""this is about the at sign ("@")"""
@@"

I think making it available only as an escape sequence, rather than as a stand-alone token, would make the syntax more discoverable. The down side is, of course, that we need at least 7 characters to make a stand-alone heredoc string (compared to 4 with a stand-alone token).

"\@@:hello world@"

That in itself is not really a problem, just a minor annoyance. The bigger problem with my mix-of-everything idea is the whole thing about tabs and spaces. Unless we force an arbitrary rule for indentation (like YAML does), there's no good way of making indented heredocs work nicely when different people press tab on different text editors.

Also, what happens when the text is indented less than the closing token? What should happen there? How do we describe trailing whitespace at the end of a heredoc string?

Maybe we should forget the YAML-like text indentation.

What if whitespaces are acceptable token characters?

Then this is valid

  var bla = @
---
my heredoc
---

And so is this

  var bla = @
  """
another heredoc here
  """

Here the heredoc tokens are "\n---" and '\n\u0020\u0020"""' respectively and there are no indentation problems. Cosmetically, in the second example, the non-whitespace tokens align with the rest of the code, since they are merely indented. The only caveat is that the actual heredoc string is outdented back to zero - perhaps that's better; after all, indenting it manually is what would break it.

I like how the second style looks. Indentation good practices are directly in line with what a parser would expect as correct syntax and the position of the non-whitespace part of the tokens give enough information about the string's indentation level in relationship to the rest of the code. Meanwhile, the body of the string remain intact (which is good, since it can often be a whitespace-sensitive copy-and-paste from somewhere else - e.g. a Python script). Another benefit of keeping the string intact is that it can be diffed in source control systems.

Agree? No? Maybe?

Sunday, April 19, 2009

Monkeypatching and eggs

So monkeypatching - or more generically, multiple versions of code and multiple dependencies - can break stuff. It kinda reminds me of the GPL's virality: once you "pollute" a scope, everyone after you will likely have to rewrite code to fix some edge case you haven't thought of.

Mac botnet

I wouldn't be surprised at all if it wasn't the only one.

Saturday, April 18, 2009

I just had one of those silly realizations

I just realized something silly:

//C
 add(1, 2, 3);
;;lisp
(add 1  2  3)

Friday, April 17, 2009

On tabs vs spaces

If I understand the debate correctly, the problem of tabs vs spaces arise only when there are both in the same file:

1 if (a_condition &&
2     another_condition)
3 {
4     do_something(variable1,
5                  variable2,
6                  variable3)
7 }

The indentation doesn't really matter. It works either way. But the alignment would break in spectacular fashion if we aligned lines 2, 5 and 6 with tabs.

So always tabbing won't work.

People like to be unique, and everyone has their own favorite tabstop settings. I've seen different co-workers use 2, 4 and 8, for example. Tabs make the files automatically look nicely indented to you in your favorite editor(tm). Spaces make it look nice only to some people (doesn't that remind you of the three bears fairy tale?). Also, having a key insert not only a different character than it states, but also several of them, is weird. So pure spaces don't quite work either.

No editor I'm familiar with can smartly figure out what portion of the leading space is supposed to be tabs and what is supposed to be spaces AND do the conversion automatically when you press tab and/or spam the spacebar. And we're assuming we can't rely on the programmer to remember to check (a fair assumption imho).

So tabs for indentation and spaces for alignment doesn't work either.

Solution?

Well, if there was one, we'd all be using it. What if we just avoid aligning things altogether?

//with alignment
doSomething(var1
            var2
            var3)

//indented
doSomething(
  var1,
  var2,
  var3
)

//with alignment
if (foo == true &&
    bar == true &&
    baz == false)
{
  //bla
}

//refactored
var isNameValid = foo == true
var isEmailValid = bar == true
var isDateValid = baz == false
if (isNameValid && isEmailValid && isDateValid) {
  //bla
}

Then again, that's javascript. Probably doesn't work so well for C or lisp.

But the question is: why do people align stuff, rather than indent it? I can see that it'd look ugly in the case of the if statement, but time and time again I've seen huge parameters lists for some OpenGL call being aligned to some random column for no particular reason when they could just break the line after the opening parens and indent the parameters (and they'd even fit in the screen!).

For things like huge if statements, I find that the refactored pattern above is nice especially when the code is dense (e.g. when expressions are queries to data structures, like in LINQ or Python comprehensions), since the variable name describes what information is being pulled out of the data structure.

Back to the topic

Anyways, coding patterns aside, I still don't know what's a good way to tie spatial code organization more closely to the abstract syntax tree (and in the case of alignment, to the metagroups of data) that provides a consistent coding style convention that works everywhere and for everyone.

Is bickering about which ASCII character is better the best we can do?

Thursday, April 16, 2009

Lisp without parentheses

So apparently, every lisp newcomer and their dogs has had the fabulous idea of making a version of Lisp that uses indentation instead of the derided parentheses.

The most common proposal I've seen is to make each line with a deeper level of indentation be a new form.

(0 (1 2))
becomes
0
  1 2

Simple enough. The problem is that the idea breaks when we have a form that looks like (0 1 (2 3) 4 5 (6 7)) or (if condition some-long-form another-long-form). The first breaks because once you indent, there's no syntax to close the current form and return to the parent, since outdenting requires moving to a new line, which closes both forms.

The second form is more subtle: in Algol-like languages, you'd normally some-long-form on a new line and indented. We can't do that with the lisp-without-parens proposal unless we add another symbol to escape line feeds or something like that.

if (foo bar) \
  do-something \
  do-something-else

That just looks plain stupid. Let's scratch that.

Another idea would be to make outdenting return to the parent form, i.e. a line feed does not close a form.

(0 1 (2 3) 4 5 (6 7))

0 1
  2 3
4 5
  6 7

(if condition some-long-form another-long-form)

if condition
some-long-form
another-long-form

Bla. Looks dumb and we now need something to denote when a form closes and a new one opens.

(if condition (+ 1 2) (+ 2 3))

if condition
  + 1 2
  =====
  + 2 3

Or something equally bizarre. Scratch.

Ok, let's stop with the toying around a bit

In case you haven't noticed the pattern, the problem here is that even though regular lisp has two pieces of syntax (open-parens and close-parens), and python-like syntax has three (line feed, indent and outdent), indent and outdent can't always be written out (e.g. in the last example they cancel out and thus we need a fourth symbol to go around that edge case).

So can Lisp without parentheses work without bolting on weird characters to make edge cases work? I don't see how.

Piracy

Is it just me or is everyone obsessed with pirates these days?

Thursday, April 9, 2009

Java is so not dead

So since Java is now supported on Google App Engine, a gazillion languages become supported too. We can now play with Javascript, Ruby, Lisp and even Lua in GAE. Talk about bang for a buck.

Tuesday, April 7, 2009

The most dangerous person in the world

Pretty sure I've seen the numbers before. I just like to read about this topic for some reason. Putting things in perspective I guess.

Nukes

Scary, the US radius is so large it doesn't even fit in the map.

Friday, April 3, 2009

The User

I was working on an internal app today and caught myself saying "when the user does x". Dude. I *AM* the user.

Wednesday, April 1, 2009

Ignore teh Intahtubez day

Habits question: do we really need a spammy day to ignore the Internet? I've been noticing that I've been spending a bit more time than I probably should online. Interestingly, that realization only really clicked because of the wacky nature of April's Fools. Hmm.

Competence

Jeff's question: Should competent programmers be mathematically inclined?

My question: what does one have to do with the other? Does writing a 3D engine automatically make you a competent programmer? Does working almost exclusively with databases make you not competent? Mental exercise: Let's swap these two hypothetical programmers for a day and see how it goes.

Tuesday, March 31, 2009

Languages

Atwood was talking about how English is a lingua franca of sorts in the programming world, and now there's this rebuttal making rounds.

I remember seeing a fairly similar discussion in Orkut once. Orkut is a social networking site that is popular mostly in Brazil, and the discussion was about whether people should make an effort to speak in English anyways, since it's been (arguably) the lingua franca of the Internet.

It sorta boiled down to this: lazy people would stay in their comfort zone. Smart people could recognize the value of using english.

I'm not saying all Brazilians are lazy, just that there are a significant number of Brazilians who are not that comfortable with English and are not as willing to make an effort to learn it.

What's a bit funny is that, with Jeff's example, things are a bit reversed from mine: in Orkut, you're more likely to get unexpectedly different perspectives when talking in English with an Indian or Japanese or Russian person, than talking to someone from the same city you were born in. The programming example speaks in a scale that is an order of magnitude larger: In the real world, you are more likely to see unexpectedly different perspectives when you get out of the English speaking bubble that is the Internet.

And with all these talks of recessions and the need for entrepreneurship, and (if you follow Seth Godin anyways) the idea that focusing on tribes is the road to success, maybe we should be considering the possibility that we've spent way too much time shielding ourselves from the scary, weird world, and that we've been losing out on a lot of opportunities.

Monday, March 30, 2009

I know, I'll use a library! Now you have two problems

I just helped a co-worker from another dept debug one of those fun bugs that make absolutely no sense when you first see it (syntax error in IE6, no line number, if you're wondering). The codebase is for an internal app and it's fairly old and not very well written. It uses an older version of prototype and uses Adobe's js library to get around that Eolas thing.

So, just like the adobe code docs suggested, we had code like this:

<script type="text/javascript">
<!--
var bla = "some config for flash player version"
-->
</script>

Yeah, we know inline javascript is not a great idea, but people working with 3rd party flash graph components (especially when these people are full-time back-enders) are not particularly keen on iterating over little javascript boilerplates that are just there to get the flash up and running.

Anyways, the code above looks fairly harmless. It's just a variable assignment.

Or is it? Turns out that if we ajax that code with older versions of prototype, the Ajax.Updater call will internally parse all the script tags and eval() their innerHTMLs via the String.evalScripts function. The catch: it doesn't filter out the HTML comments out!

So, since IE6 doesn't have support for E4X, you'll get a big fat syntax error popup on your face.

Yes, I admit, our internal code is fairly ugly and could be improved a lot, but that's another rant. The issue here, though, is that, by themselves, both Prototype and the Adobe library worked just fine - it's only when the two appeared in the same codebase that hell broke loose.

Now that I've described the problem, it may even seem fairly silly and easy to identify, but tell that to the guy that was pulling his hair out a few hours ago. In all honesty, we only managed to find out that was the issue because:

  1. I've played a lot with writing libraries on my spare time and I know about many browser limitations and quirks that you can only know if you actually do a ton of cross-browser debugging (rather than just staying inside the comfort zone of a tested js library)
  2. I read a whole lot more open source code than a lot of my co-workers and, as such, I'm fairly well versed with Prototype's finicky hacks.
  3. We had already tried a bunch of other things and I suggested to try something unintuitive, because I was stumped and the old school HTML comment in the script tag was about the only thing left that looked even remotely unusual.

Not understanding enough about what's hidden by a library's layer of abstraction can be dangerous. It makes it hard to troubleshoot a problem, even when you can see the faulty code right in front of your eyes.

So do yourself a favor and read the code for the libraries you use. You'll likely learn a bunch of stuff you didn't know before, and sooner or later, instead of burning yourself out over some inexplicable bug, you'll have a moment of enlightenment and say "hey, I know what's the problem here!".

At least for me, whenever it did happen, the second option has been great.

Games, bias and statistics

Otaku Cedric posted this in his blog: Do you want to play a game?

People are apparently fascinated by these mathematical mind games. Count the comments here if you don't believe me.

What's common about these puzzles is there's usually one answer that is more attractive than the others. Reaching the attractive conclusion often requires a bit of logical reasoning, but that's not always the rule.

Considering that mind games (especially the statistical varieties) would not be very interesting if the correct answer was the obvious one, would it be safe to read their intentions and always assume that the attractive answer is wrong?

If you are a Bayesian filter only looking for the numeric/boolean solution, probably yes. People, on the other hand, work differently: the naive gamers will take the bait of the attractive answer and lose the game; the keen gamer will still be drawn into each individual game's rule set, rather than considering that a generic probabilistic approach based on the question's bias will win most of these games, regardless of their rule sets.

The devil is, of course, in the details. Even though these types of games never explicitly ask for the reasoning behind answers, merely knowing the correct answer is not as desirable as knowing why that is so (for us humans, anyways).

Friday, March 27, 2009

Email standards

Email standards. HTML emails usually don't get a whole lot of love from developers. I wonder why.

Wednesday, March 25, 2009

Fast Polling w/ C, Memcached, Libevent and Nginx

The author claims 2400 requests per second. That seems to a whole lot more than Jetty's 1000 rps. To be fair, Jetty's results are 2 years old.

Note to self: I should try and hammer my architecture with messages one of these days to see how well it does.

Tuesday, March 24, 2009

Monday, March 23, 2009

What trap?

This seems to making a splash on most techie news aggregation sites today. I don't get the fixation with javascript though. It doesn't make a whole lot of sense to talk about non-trivial web applications if we disregard server-side code.

Can anyone actually point me to some javascript code that is GPL'ed and has no unobfuscated source code available?

On x86

Saw it on Reddit, looks interesting, I'll read when I get some time.

Saturday, March 21, 2009

Thursday, March 12, 2009

Fossil SCM

Fossil sounds nice: version control with integrated wiki and bug tracking. I'll give it a whirl when I get some time.

Apples are the end of oranges

Sometimes it feels like some people don't actually know the APIs they are talking about. Case in point: webcams and sockets.

Monday, March 9, 2009

Mortgages

I think I'm starting to understand why economists were saying that now it's a good time to be a house buyer. I like reading about people's experiences when the subject is economy, it makes things much easier to grasp than articles about macro economics published by large new outlets.

Friday, March 6, 2009

PPK on mobile browsers

This is why I love PPK: he does all the heavy lifting for us.

Wednesday, March 4, 2009

Saturday, February 28, 2009

a little neat thing about git gui

I just learned about this neat feature in git GUI.

When you click on filenames, you can see the diffs on the right side on the window. Nothing new here.

The neat thing is that instead of clicking on the icon beside a file to stage all the changes in it, we can click on the file to see its diff, and then right-click on a particular diff line and choose "stage hunk for commit". There's also one for single lines of changes. What that feature does is it lets you commit only parts of the file, which is great for .NET Web.config files and for those times when you only want to commit the one character fix and not the 100 lines where you merely changed indentation.

Conversely, you can stage the whole file; then, right-clicking on a change on the diff panel will show "unstake hunk from commit", which means that change won't be committed.

For the keyboard people, the command line version of that is git add -p.

"Ajax calls don't render in IE"

Yesterday, one of my co-workers ran into an issue where ajax calls would simply refuse to render in IE. You could see the call returning a 200 from Fiddler, but it just wouldn't render any HTML (we were using Prototype's Ajax.Updater, btw).

It's a really puzzling bug but as it turns out, that exact same bug had happened to a different co-worker a few months ago. The ugly thing about this bug is that it only shows up when a project is rather complex (this particular one has a few dozen branches, hundreds of thousands LOCs and maybe 10 people working on it at any given time). What's worse is that as far as I know there's no one tool that will tell you what's wrong.

So I'm here to share an idea that may spare you from quite a bit of grief.

The problem turns out to happen because there are lots of reusable modules and things that include things that include things (yes, as in PHP include() or require_once()). Because of the complexity, a view with a form ended up being inadvertedly ajaxed into another form. That is obviously not valid markup, but it will still render in Firefox. The problem is that IE won't render it, and it won't throw any errors either. The W3C validator won't help much either, unless it happens to occur to you to copy and paste the full generated source from Firebug into the validator (does anyone ever do that?).

tl; dr: un-nest your forms.

A neat pattern

This neat javascript pattern just came to my mind. Consider this class constructor:

var Base = function(o) {
  for (var i in o) this[i] = o[i];
}

Pretty basic constructor, right? This class can have a prototype and we can subclass it like so:

Base.prototype = {a : 1};
var Sub = new Base({b : 2});
var sub = new Sub();
sub.a == 1; //true
sub.b == 2; //true

It just occurred to me that since a constructor is a function, it can also be call()'ed, like so:

var A = function() {};
A.prototype = {a : 1};

var B = function() {};
B.prototype = {b : 2};

Base.call(B.prototype, A.prototype); //class B extends class A

var a = new A();
var b = new B();

Base.call(b, a); //instance b extends instance A
Base.call(b, A.prototype); //instance b extends class A
Base.call(B, A); //static B extends static A

I've seen the extend() pattern pretty much everywhere but I haven't come across anything that uses this same Base function as a class constructor as well as an general purpose "extend()" / "clone()". I wonder if anyone uses it like this.

Friday, February 27, 2009

Ripple - a simple js REPL tool

I wrote a quick tool last night to help me teach people about javascript's prototype-based OOP. It's up on github (MIT licensed). Suggestions welcome.

Demo here

Wednesday, February 25, 2009

LLVM-Lua

I should take a peek the source code when I get some time.

Eye of God

Looks really cool. For some reason, there are people selling that same image.

One shot from Hubble.

Redis

A key-value database.

Funny, I was actually thinking about implementing some of the architectural features (namely, the async io) for my pet project.

Object relationship oriented programming

Lately, functional programming seems to be getting a lot of attention (so much so that OOP no longer looks like the cool kid on the block). But, at least for me, OOP is still very much alive and is useful to organize code.

What I have noticed about my code as I read more about FP and play with languages like clojure is that I now try to make objects represent not objects, but generic concepts that encapsulate relationships between objects.

The main difference between thinking in terms of relationship containers and how I used to think about OOP is that methods that deal with more than one thing don't live within one of the objects that it applies to; it lives in a separate object where the interaction happens.

For example, instead of

person.feed(dog);
I'd now call a feed function from an object where both person and dog are part of. The hard part is figuring out what this object should be. It depends on the application. Maybe I could have written it this way:

class CountrySideLife extends Lifestyle {
  public void feed(Person person, Animal pet) {}
}

Maybe that's overkill and I can get away with "class Main", since this is a throw-away example.

The point, though, is to not think so much in terms of object x does y, but function y happens in x.

The downside of thinking about relationships is that you don't always have a clear cut idea of what they are (especially if your business requirements change a lot), so designing the relationship classes prematurely could mean shooting yourself in the face.

The upside is that code written like this looks top-down and is easy to read and understand.

Of course, the old paradigm of object x does y still has its place. Sometimes a self-contained class just makes sense. But for higher level code paths that deal with a lot of objects and relationships, the paradigm of function y happens in x helps me organize code when I'm not sure which object should encapsulate what function.

Monday, February 23, 2009

Intro to compilers (Python)

Looks like a nice resource.

"Why" doesn't help me

Lately, I've been running across a gazillion blog posts with a title that starts with "why".

The funny thing about these types of articles is that if you search enough you can find a bunch of them that say roughly the same things, give or take a bullet point. But when you search for how someone fixed a particularly nasty bug in some particular API, you're lucky if you find one obscure blog post (usually 2+ years old). And in news aggregation places? Forget about it.

Why don't people blog about implementation woes more? Are they too busy coding, or not coding enough? I wonder.

Friday, February 20, 2009

Microfinances

Interesting article. This disparity between what rich and poor think promotes equality is some nice food for thought.

More on broken windows

An A/B study measured a 20% improvement.

Thursday, February 19, 2009

Friday, February 13, 2009

Productivity

Reg Braithwraite wrote a bit of food for thought on productivity.

I think when people talk about productivity, they often set "high productivity" as goal to be achieved, when really, we can only measure the state of completion of individual tasks. Wrote a test unit. Check. Implemented form validation logic. Check. Designed wireframe. Check. Achieved high productivity. Huh? What does that even mean?

Notice how, despite being very measurable and sometimes even paramount to get a project out of the door, none of the tasks I mentioned can really be measurements of productivity:

  • Write a test unit. Pretty important in TDD. Not what you should be working on when you're putting up a prototype demo that will be used in a sales presentation that you've just been informed will start in 2 hours.
  • Implemented form validation. Anyone knows it's important, but rolling your own when the framework has a built-in function to handle the exact same case is sometimes a waste of time. The opposite can be true too: you might find that using a framework built-in helper to save 2 minutes wasn't worth the 2 hours you end up spending on it when the qa phase comes along and a bunch of cases are broken.

Etc. Etc.

If I don't know what your goals are, and you don't know mine and we have no idea what each other's teams can and can't do (because of knowledge levels, corporate constraints, programming languages, frameworks, workflows, whatever), how can we intelligently discuss productivity improvements? It strikes me as odd that people would go as far as preach a methodology or even a coding practice as "the one", when I think about it from this angle.

Besides, hasn't there been enough articles around the tubes saying how rewarding programmers based on their individual "performance" is a bad idea?

Why do we even talk about productivity?

Doomed

Doomed. Doomed. Doomed.

What's up with people and this obsession with doom?

Thursday, February 12, 2009

How not to sort by ratings

Informative. Goes to show how good knowing statistics can be.

Wednesday, February 11, 2009

When can I use...

A list of upcoming standards and drafts and their level of implementation in various versions of major browsers.

My conclusion: use flash :)

Why you should be a good citizen online

Nice article talking about legal standards myths and how police can disrupt your life in case you get accused of doing something illegal online.

Look ma, I'm a prophet

I've been seeing a lot of jabs at how the newspaper industry should restructure now that they're reportedly not doing so great.

I keep wondering if these people actually run businesses on the models they are proposing or if they're just prophets full of themselves.

Monday, February 9, 2009

Cognitive bias on wikipedia

Cognitive bias. via. I know I'll forget the term Dunning-Kruger, so here it is for future reference.

Wednesday, February 4, 2009

Carakan

Opera really does not sleep on the job. I wish it'd get more traction, I think it's a great browser.

Users don't always know what they want

Speed is more important than quantity, despite users' reasoning that more results are better, according to Marissa Meyer from Google.

Tuesday, February 3, 2009

Why debating CSS vs Tables is pointless

So some were recently saying CSS *should not* be used for layouts and others were saying CSS *should* be used for layout.

On one end, there are people who really have better things to do than spending the day typing up angled brackets and curly braces. Great for them. Whip up a quick layout in 10 minutes and you're on your way. Requirements? What requirements?

On the other end, there are people who need to maintain sites and people who have technically challenging requirements (you know, the print versions of the pages must look a certain way, layouts look and feel are to be revised and approved by the client, etc). Great, CSS to the rescue. Money pays the bills, life is nice. Brownie points if you improved yourself by learning something new about CSS on your journey to "front-end expertise".

Most people are usually somewhere in between the two extremes and their whereabouts in the gray area also depends on things like whether it's a job or a hobby project, or whether it's monday or friday-when-omg-we-need-to-get-this-thing-out-of-the-door-now. Or whether their boss is a technical evangelist or a sales person. Or whether they're lazy. Or stressed out. Or whatever. Whether kittens are blue.

The obvious but often forgotten thing about the teh intahblagz is that we don't know who's at the other end of the wire, let alone what their environment, priorities and workflow look like. So we read all of these "advices" about why this is the bomb and why that is THE way to do whatever, and in the end, we just do whatever happens to look like the best idea at the moment. Mind fap. </acid>

Friday, January 30, 2009

Robot rights

"The point isn't whether it's an issue for the creature. It's what does it do to us."

Yes, but regulating one particular type of action that affects the perception of torture doesn't necessarily make the world less violent. Especially when you can't enforce it.

Tuesday, January 27, 2009

Mona Lisa

Nice. I definitely agree about the lack of sample code out there for clojure.

Friday, January 23, 2009

Internet population by country

This gives a good idea of what languages are nice to learn (assuming you do web development): chinese, japanese, german, french, russian, portuguese, korean, spanish and dutch.

Interesting that there are more europeans online than north americans.

Paros security scanner

This looks really helpful.

Thursday, January 22, 2009

My first impressions of Clojure

I was playing with Clojure last night, it looks like a pretty interesting platform, since it has tight integration with the JVM, and seems to have solid native collections.

My first negative impression about the whole lisp thing was that it seems that pretty much everyone that does it recommends emacs or vi or an maybe eclipse plugin and that other editors get no love. I installed emacs only to find out that that the shortcut for undo is bizarre (ctrl+x, then u, or alternatively, ctrl+shift+-). I'm not sure how similar vi is to vim, but I find vim hard to use as well. Eclipse was something a friend of mine suggested, but that turned out to be too slow for my taste. So I'm trying it with good ol' notepad++. Is fighting with editor shortcuts and/or indentation supposed to make me more productive? Bla.

My second negative impression was Clojure's documentation. Almost nothing in the docs has usage examples. The stuff that does is not very easy to understand either. What's a #^{}? What's "k v & more"? What's a valid attr-map for defmacro? Double bla.

Thursday, January 15, 2009

Crayon Physics

A co-worker just showed this. I've gotta say it looks really cool.

Wednesday, January 14, 2009

Online child safety

Looks like a very extensive and down-to-earth report. At the moment, I'm more inclined to think critics are driven by fear rather than by facts.

Tuesday, January 13, 2009

CMS in PHP tutorial

This sort of shit scares the hell out of me. And the Digg comments.

Grass

This guy makes a mention of Buddhism at the beginning of the post. I took a cursory look at the comments just to verify one suspicion I had: that there wouldn't be criticism towards Buddhism the way you'd see snarky remarks about "religion" when Christianity is mentioned.

Maybe I'm stupid and Buddhism is not really a religion, like I'd normally think.

Or maybe it's just that the grass is greener on the other side of the fence.

Friday, January 9, 2009

Laws

<rant>What's with everything being a "law" nowadays? In science, "theories" are usually only considered worthy when there's hard data and standard deviations, so "opinion" or "anecdote" sounds like a more proper term when people want to say how they think the world works in a catchy way.</rant>

zappos

This is a very clever way of recruiting.

Thursday, January 8, 2009

Twitter password

Pretty much everyone is talking about the twitter breach that happened this week and how twitter could've prevented it. One thing that I noticed about the whole ordeal was how the username wasn't secret (in fact they can even be farmed with a bot).

It's a well known fact that hackers use dictionary attacks to find passwords, so shouldn't we be making usernames secret too? I mean, a hacker doesn't necessarily care who they hacked, if it was a celebrity, that's just brownie points.

I don't see what's the big deal with having an extra column on the db (one for username and one for display name), since having the two separated also gives us the benefit of being able to use our favorite display name, even if someone we'll never talk to has the same display name.

Friday, January 2, 2009

Probabilities

More than statistics, people discussing statistics amuse me.