Gaussian Blur for jQuery

I did a quick search and didn’t find any existing plugins to do this, so I wrote one. Nothing fancy, just element cloning and opacity adjustment.

Test page here.

If your browser is in Spanish…

… your CSS might not work properly. I just ran into an interesting issue with Chromium in Spanish. If you use jQuery (or pure DOM) to set the CSS opacity of an element to a floating-point value and then read that value, e.g.:

$('some-element').css ('opacity', 0.5);
$('some-element').css ('opacity') // What will this be?

you may get a string value like this: “0,5″. The only problem with this value is that it can’t be converted to a number without doing a replace() call, and you’ll get NaN values popping up from what should be purely numeric expressions.

I’ve filed a bug on the Chromium project, but in the meantime I guess I’ll have to switch over to English.

Scary Code

After losing some perspective doing solo projects, I recently was reminded of some of my worse habits when coding. There’s this gem from the Rebase project:

syntax: '@parent = $0, @op = $1, @xs = $2 || [], $_'.ctor ({
                           is_value: '@xs.length >= $0.arity_of(@op)'.fn(r),
                                map: 'new $0.syntax(null, @op, @xs.map($1).map({|t, x| x.parent = t, x |}.fn($_)))'.fn(r),
                               find: '(@op == $0 || @xs.grep({|t, x| t == x |}.fn($0)).length ? [$_] : []).concat (@xs.flat_map({|t, v| v && v.xs && v.find(t) || [] |}.fn($0)))'.fn(),
                            replace: '@xs[$0] = $1, $1 && ($1.parent = $_), $_'.fn(),
                         push_value: '! @is_value() ? (@xs.push($0), $0) : ("The token " + $0 + " is one too many for the tree " + $_ + " in the context " + $_.top() + ".").fail()'.fn(),
                          with_node: '$0 && ($0.parent = $_), @push_value($0), $_'.fn(),
                            push_op: '$0.precedence[$1] - !! ($0.right[$1] || $0.syntactic[$1]) < $0.precedence[@op] ? @graft($1) : @hand_to_parent($1)'.fn(r),
                              graft: '@push_value(@is_value() ? new $0.syntax($_, $1).with_node(@xs.pop()) : new $0.syntax($_, $1))'.fn(r),
                     hand_to_parent: '@parent ? @parent.push_op($0) : ("Syntax trees should have a minimal-precedence container when parsing " + $0 + " at " + $_).fail()'.fn(),
                                top: '@parent ? @parent.top() : $_'.fn(),
                           toString:  function () {var left_in = function (x, ops) {return x.xs && x.xs[0] && (ops[x.xs[0].op] && x.xs[0].op ||
                                                                                                               x.xs[0].xs && x.xs[0].xs[1] && ops[x.xs[0].xs[1].op] && x.xs[0].xs[1].op)},
                                                      right_in = function (x, ops) {return x.xs && x.xs[1] && ops[x.xs[1].op] && x.xs[1].op},
                                                            $_ = '';
                                                   return '([{'.indexOf(this.op) > -1 ? this.op + s(this.xs[0]) + r.openers[this.op] :
                                                                      this.op ==  '?' ? s(this.xs[0]) + ' ? ' + s(this.xs[1].xs[0]) + ' : ' + s(this.xs[2]) :
                                                   this.op == '(!' || this.op == '[!' ? s(this.xs[0]) + s(this.xs[1]) :
                                                       r.implicit_assignment[this.op] ? '(' + (this.op.charAt(0) === 'u' ? this.op.substring(1) + s(this.xs[0]) : s(this.xs[0]) + this.op) + ')' :
                                             this.xs[1] && r.connected[this.xs[1].op] ? (($_ = s(this.xs[0])).charAt($_.length - 1) === '}' ? $_ + ' ' : $_ + ';') + s(this.xs[1]) :
                                                                     r.unary[this.op] ? (r.translations[this.op] || this.op) + ' ' + s(this.xs[0]) :
                                                             r.prefix_binary[this.op] ? this.op + ' ' + s(this.xs[0]) + ' ' + s(this.xs[1]) :
                                                                 r.no_spaces[this.op] ? s(this.xs[0]) + this.op + s(this.xs[1]) :
                                                                                        s(this.xs[0]) + ' ' + this.op + ' ' + s(this.xs[1])}})

that gets coupled with this parser:

                  parse: function (s) {var mark = 0, s = s.toString(), i = 0, $_ = '', l = s.length, token = '', expect_re = true, escaped = false, t = new r.syntax(null, '('),
                                                      c = s.charAt.bind (s), openers = [],
                                             precedence = r.precedence, ident = r.ident, punct = r.punct, digit = r.digit,
                                            line_breaks = [0].concat (s.split('\n').map('.length')), lb = 1,
                                          located_token = function () {var jump = lb << 1, l = 0, r = new String (token);
                                                                       while (jump >>= 1) mark >= line_breaks[l + jump] && (l += jump);
                                                                       return r.line = l + 1, r.character = mark - line_breaks[l], r};
                          while ((lb <<= 1) < line_breaks.length);
                          for (var j = 0, lj = line_breaks.length, total = -1; j < lj; ++j) line_breaks[j] = total += line_breaks[j] + 1;

                          while ((mark = i) < l && ($_ = c(i))) {
          escaped = token = '';

               if                                (' \n\r\t'.indexOf ($_) > -1)                                                             {++i; continue}
          else if                               ('([{?:}])'.indexOf ($_) > -1)                                                              expect_re = '([{:?'.indexOf ($_) > -1, ++i;
          else if                 ($_ === '/' && c(i + 1) === '*' && (i += 2)) {while       (c(++i) !== '/' || c(i - 1) !== '*' || ! ++i);  continue}
          else if                             ($_ === '/' && c(i + 1) === '/') {while             (($_ = c(++i)) !== '\n' && $_ !== '\r');  continue}
          else if ($_ === '/' && expect_re && ! (expect_re = ! (token = '/'))) {while                  (($_ = c(++i)) !== '/' || escaped)   escaped = ! escaped && $_ === '\\';
                                                                                while                                     (ident[c(++i)]);}
          else if              ($_ === '"' && ! (expect_re = ! (token = '"')))  while         (($_ = c(++i)) !== '"' || escaped || ! ++i)   escaped = ! escaped && $_ === '\\';
          else if              ($_ === "'" && ! (expect_re = ! (token = "'")))  while         (($_ = c(++i)) !== "'" || escaped || ! ++i)   escaped = ! escaped && $_ === '\\';
          else if                    (expect_re && punct[$_] && (token = 'u'))  while        (punct[$_ = c(i)] && precedence[token + $_])   token += $_, ++i;
          else if                            (punct[$_] && (expect_re = true))  while        (punct[$_ = c(i)] && precedence[token + $_])   token += $_, ++i;
          else                                                                 {while (ident[$_ = c(++i)] || digit[c(mark)] && digit[$_]);  expect_re = precedence.hasOwnProperty (token = s.substring (mark, i))}

          expect_re && token.charAt(0) === 'u' || (token = s.substring (mark, i));
          token in {} && (token = '@' + token);

               if         (t.is_value() && '[('.indexOf (token) > -1)  openers.push (t = t.push_op (token + '!').graft (located_token()));
          else if (($_ = r.closers[token]) && last(openers).op == $_)  t = openers.pop().parent, token === '}' && t.is_value() && r.statement[t.op] && (t = t.push_op(';'));
          else if                                     (token === '?')  openers.push (t = t.push_op (located_token()).graft ('?:'));
          else if                                  (r.openers[token])  openers.push (t = t.graft (located_token()));
          else if                                 (precedence[token])  t = t.push_op (located_token());
          else                                                         t.push_value (located_token());
                          }
                          return t.top()}

Seriously gnarly code. Anyone else have examples of scary code (written by you or by someone else)?

LuaJIT is Really Fast!

I was surfing around on the benchmarks game yesterday looking for a fast language to use for Gnarly. (I’ve since decided on C/C++.) On the x86-32 scale, LuaJIT is the sixth most performant language, behind ATS, C++, C, Java, and Scala. On the 64-bit scale it’s the 7th; C, C++, ATS, Ada, Java, and Haskell are faster.

It is easily the fastest interpreted, dynamically-typed language that was ranked. It’s very impressive to see this kind of performance without offline compilation and without a static type system.

And, if you haven’t checked out Lua’s semantics, those are very cool too. It’s basically JavaScript without the design mistakes. (I’ll probably be blogging more about Lua as a I learn it.)

SDoc on Github

If you’ve ever felt like existing source code documentation was cumbersome (not all are POD-quality, after all), then you might like SDoc. It’s designed to be very simple and transparent, making documentation easier to write and maintain. As far as I know it’s the only solution that infers comments, though I may be wrong about that.

I hope to have a CTags-based HTML generator up soon. If done correctly, that would provide cross-referencing of code symbols via an Exuberant CTags file.

Can CFG Parsers be Optimized?

Obviously there are more and less clever ways to write parsers for context-free grammars. But since context-free grammars aren’t subject to the halting problem (nor the incompleteness theorem), is there an algorithm to transform a context-free grammar into a maximally-efficient program to parse that grammar?

Infix as Huffman Encoding

I’ll be honest: I don’t like infix notation in programming languages. Ever since finding Lisp, I’ve found it to be superfluous (from a linguistic sense, anyway), and something to be lived with, rather than enjoyed, in otherwise great languages like Perl and JavaScript.

But infix syntax came about for a good reason. More often than not, expressions written infix are terser than those in prefix notation (edit: they are never less terse if you’re coding in variadic prefix notation, such as Lisp). If I had to guess, these conventions arose because of common usage; the precedence of various operators was chosen to minimize the need for parentheses (and line up with mathematical tradition, but I’m assuming mathematicians were doing the same thing).

So infix syntax is more than a syntax, since it carries assumptions about structure. Adding takes lower precedence than multiplying because of the algebraic structure of the data type.

And defining operator precedence makes an enormous amount of sense as long as that algebraic structure is present. But given that most programs aren’t mathematical in nature, is it time for a new set of implied rules about what happens first? (Especially considering the verbosity of chained or nested method calls.) Further, given this shift in programming in general, is it time to delegate these conventions to libraries of a language rather than to a language itself?

Types in the Untyped Lambda Calculus

The untyped lambda calculus by definition doesn’t support the idea of types. However, this isn’t to say that types become inapplicable. At the very least, one could assign each value its own unique type and claim to have a Turing-complete type system.

As it turns out, though, there is (well, might be) some performance advantage to giving each value a type. In particular, if the program is first CPS-converted, then the type of each value is the call stack that produced it. (Following the idea that types represent decisions — so the limit of dynamic typing is what we generally code these days, and the limit of static typing is a fully decided program.) Obviously some unification can be done; for example, if we know ahead of time that a particular function projects its inputs into a consistent space, then we can remove all preceding frames from the call stack.

I’m not sure whether this is useful yet. What might be interesting, though, is to remove the automatic unifications from existing type systems and rely on lazy unification instead. That way the type system can be Turing-complete and transparent, but it won’t put the compiler into an infinite loop or give up if something can’t be proven. (Luke Palmer has some very interesting thoughts about ideas like this.)

New Design!

Over the past week Joyce has been going through and redesigning my website/blog. I’m sure I’ve still got some broken links, but it is awesome to be able to support comments again, and to have a blog that I’ll be updating on hopefully a more regular basis.

New Projects

I’ve been working on some new stuff lately, most of it on my Github profile. In particular, I’ve been really diving into JavaScript and trying to push the limits. Here are the new projects:

  • Divergence JavaScript library: functional JavaScript library
  • JavaScript in Ten Minutes: a quick but thorough guide to serious functional JavaScript programming. This is a work in progress, but would probably make a good read for anyone interested in writing some heavy client-side code or getting into something like node.js.
  • Gnarly: a very slow Lisp derivative written in self-modifying Perl. Gnarly takes the concept of Lisp macros to a new level by making them properly first-class, but the downside to this is that programs are nearly impossible to optimize.

As usual, feedback is welcome.

Update: There are now even more projects! Check it out: