Showing posts with label firefox. Show all posts
Showing posts with label firefox. Show all posts

24 January 2013

Browser/OS stats for this blog

I was looking through the blog’s stats, and the browser and OS stats seemed kind of interesting.

  • 63% Firefox
  • 15% Chrome
  • 10% Safari
  • 8% Internet Explorer
  • 40% Macintosh
  • 37% Windows
  • 16% Linux
  • 2% iPad
  • 2% iPhone
  • < 1% Android
  • < 1% Other Unix

Based on what I’ve been seeing from more generic reports, that seems atypical. I’m surprised that Chrome isn’t closer to or a bigger percentage than Firefox. I’d expect Safari and IE to be reversed, but they are pretty close. It seems that fewer of my visitors who use Macs use Safari than I would’ve thought.

For this blog, that’s pretty much just trivia. If you are someone who has to make decisions based off this kind of data, though, I can’t emphasize enough how important it is to collect your own data rather than relying on what others report. e.g. When I was in the shrink-wrapped software business, Macs made up a lot more of my company’s market than the general marketshare they held at the time.

12 November 2009

The problem with Javascript’s map

This is about Javascript programming. If you’re not interested in Javascript programming, bail now.

Say you have a Javascript array of strings that you want to convert to numbers.

['1', '2', '3'].map(parseInt) ⇒ [1, NaN, NaN]

Hmm. Why didn’t that work? Because parseInt takes an optional parameter (the radix)...

parseInt('ff', 16) ⇒ 255
parseInt('2', 1) ⇒ NaN // Because a radix of 1 always returns NaN
parseInt('3', 2) ⇒ NaN // Because 3 isn’t a valid binary digit

...and map passes an optional second parameter (the index).

[1, 2, 3].map(function(n, i) [n, i]) ⇒ [[1, 0], [2, 1], [3, 2]]

Occasionally it is very handy to have map give you that index. Often, however, I want to give map a function—like parseInt—that wasn’t explicitly designed to be used with map.

Here’s how to fix it.

['1', '2', '3'].map(function(_){return parseInt(_);});

Yuck. Not only is that verbose, it looks downright silly since the closure looks pointless.

Expression closures can address the verbosity...

array.map(function(_) parseInt(_));

..., but (currently) only Firefox versions 3.0 and later support that. Plus, it still obscures why you’re doing it.

In Scheme, I’d use cute from SRFI 26. It allows you to specify some parameters of a function. The “<>” is used for parameters that you don’t want to specify.

(map (cute string->number <> 10) '("1" "2" "3"))

Of course, while string->number takes an optional radix parameter like parseInt, Scheme’s map doesn’t pass the index, so this isn’t necessary.

Back to Javascript. A “unaryize” function looks nicer than an explicit closure and makes what you’re doing clearer.

function unaryize(f) {
return function(_) {
return f(_);
}
}

['1', '2', '3'].map(unaryize(parseInt)) ⇒ [1, 2, 3]

We could generalize unaryize to naryize.

function naryize(f, n) {
return function() {
return f.apply(null,
Array.prototype.slice.call(arguments, 0, n));
}
}

['1', '2', '3'].map(naryize(parseInt, 1)) ⇒ [1, 2, 3]

In practice, I’ve run into uses of unaryize several times, but I haven’t yet run into a need for naryize. Also, naryize is less efficient than unaryize.

What if we want to specify a radix? We could create a Javascript version of cute. I’ll use undefined instead of “<>” for the slot specifier.

function cute() {
var cutargs = Array.slice(arguments);
var f = cutargs.shift();
return function() {
var args = Array.slice(arguments);
var fargs = [];
var i;
for(i = 0; i < cutargs.length; ++i) {
if(undefined === cutargs[i]) {
fargs.push(args.shift());
} else {
fargs.push(cutargs[i]);
}
}
return f.apply(null, fargs);
};
}

['a', 'b', 'c'].map(cute(parseInt, undefined, 16)) ⇒ [10, 11, 12]

Again, I haven’t yet run into many cases where I’d want to use cute that unaryize doesn’t suffice. In this specific case, I think I’m happy with the explicit closure.

['a', 'b', 'c'].map(function(_){return parseInt(_, 16);});

Additional notes:

Array.map can be implemented in Javascript and added without any changes to the interpreter. I’m using Prototype’s.

Expression closures can’t be added without changes to the interpreter, but they can be faked with strings. See Functional Javascript

While cute can be implemented as a function, SRFI-26’s cut has to be a macro. Likewise, a cute macro is more efficient than the procedure implementation.

06 July 2009

HTML 5 <video>

There’s some brouhaha over the decision that the HTML 5 standard (a work in progress) will not require browsers to support any specific codec(s) for the <video> tag. So...my 2¢...

Submarine patents: Really? You’re paying the licensing fees to implement the heavily patent encumbered H.264 codec, but you absolutely refuse to implement (or just take advantage of the open source code for) Ogg Theora because you’re afraid it may be discovered to infringe a patent? Despite the known patents covering H.264, isn’t it just as likely to be a victim of an as-yet-unknown submarine patent? It doesn’t look like the licensing future of H.264 is all that clear either. It’s hard for me to believe that Ogg Theora is any bigger a risk than anyone who has implemented H.264 has already assumed. I think Apple can weather any submarine patents better than Mozilla.

Quality: What does it matter whether Ogg Theora isn’t as good as H.264? Implementing Ogg Theora doesn’t prevent you from also providing H.264 as well. This is not an argument for opposing Ogg Theora being required by the standard or for refusing to implement it. Does iTunes refuse to play mp3 files because AAC are higher quality? Does Safari refuse to play mp3 files?

I don’t buy that HTML 5 should only codify what the browsers do. (Would there even be a <video> element to be debated if that were really the case?) A standard—backed by pressure from actual customers and implemented by competitors always looking for another bullet point—can and has convinced implementors to do things they wouldn’t otherwise.

That being said, I fully respect Ian Hickman’s decision as editor. It was a good decision, whether I might nitpick it or not.

And really, I haven’t been following HTML 5 as closely as I probably should be. Not to mention that, as interested (although that word seems entirely inappropriate) as I am in intellectual property law, I’m far from an expert on it. And my knowledge of video codecs is only having implemented some old codecs. (^_^)

18 June 2008

Firefox 3

It’s strange. I can’t really work up any enthusiasm for Firefox 3. I guess I’ve fully switched to Safari now.