I was amused by this:

  "Arguably it's the nicest programming environment I've ever used,
even though I go back and forth about whether J itself is brilliant or
insane."

http://prog21.dadgum.com/28.html

In an unrelated conversation, someone I know complained about APL
syntax, and I pointed out that the case he was talking about had no
unusual syntax -- it was bog-standard expression syntax, just like any
other language's expression syntax.  It was just the symbols and their
definitions being different.

And, he said "yes" -- that when he said "syntax" he really meant the semantics.

Meanwhile, in a completely different context, I was building some
"flip" code for javascript.  There are numerous jquery plugins that
deal with "flipping" content -- giving an effect like rotating it on a
3d plane.  But I wanted to be able to flip on an arbitrary axis.
After a bit of investigation, I decided to use the css3 2d matrix
operations -- that gave me compatibility with IE9, chrome, firefox and
a few others (but not IE8, so users of windows XP would have to use
something other than IE to get this effect).

After struggling with various implementations, I finally fell back on
how I would do it in J.  Leaving out the jQuery animate stuff, the
code looks like this:

        function do_rotate(target, axis, angle, X, Y) {
                var m= inner_product(
                        translate(X, Y),
                        inner_product(
                                rotxy(axis),
                                inner_product(
                                        rotyz(angle),
                                        inner_product(
                                                rotxy(-axis),
                                                translate(-X, -Y)))));
                var matM= cssmatrix(m, 1);
                var matG= cssmatrix(m, 0);
                target.css({
                        'transform': matG,
                        '-moz-transform': matM,
                        '-ms-transform': matG,
                        '-o-transform': matG,
                        '-webkit-transform': matG
                });
        };
        function op(f, m1, m2) {
                var r= [];
                if ('object' != typeof m1)
                        if ('object' != typeof m2)
                                r= f(m1, m2);
                        else
                                for (var j= 0; j < m2.length; j++)
                                        r[j]= op(f, m1, m2[j]);
                else
                        if ('object' != typeof m2)
                                for (var j= 0; j < m1.length; j++)
                                        r[j]= op(f, m1[j], m2);
                        else
                                for (var j= 0; j < m2.length; j++)
                                        r[j]= op(f, m1[j], m2[j]);
                return r;
        }
        function add(m1, m2) {
                return op(function(x, y) {return x+y}, m1, m2);
        }
        function mul(m1, m2) {
                return op(function(x, y) {return x*y}, m1, m2);
        }
        function sum(m) {
                var r= 0;
                for (var j= 0; j < m.length; j++)
                        r= add(r, m[j]);
                return r;
        }
        function inner_product(m1, m2) {
                var r= [];
                for (var j= 0; j < m1.length; j++)
                        r[j]= sum(mul(m1[j], m2));
                return r;
        }
        function translate(x, y) {
                return [[1, 0, 0, x], [0, 1, 0, y], [0, 0, 0, 1], [0, 0, 0, 1]];
        }
        function rotxy(angle) {
                var c= Math.cos(angle);
                var s= Math.sin(angle);
                return [[c, -s, 0, 0], [s, c, 0, 0], [0, 0, 0, 1], [0, 0, 0, 
1]];
        }
        function rotyz(angle) {
                var c= Math.cos(angle);
                var s= Math.sin(angle);
                return [[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 
1]];
        }
        function cssmatrix(m, moz) {
                moz= moz ?'px' :0;
                return 'matrix('+[m[0][0], m[1][0], m[0][1], m[1][1], 
m[0][2]+moz,
m[1][2]+moz].join(',')+')';
        }

And that was enough for me to get where I wanted to be.

Here, function op() gives me the ability to have javascript functions
which behave like J rank 0 dyadic verbs.  And, inner_product is J's +/
.* as long as the left argument has a rank no greater than 2.  (In
real life, J's implementation is not so recursive -- I think that the
recursion in op() has more to do with javascript's array data
structures than with J.)

Anyways, I think my point here is that everything J does is simple --
dead simple.

It's difficult, though, sometimes, conveying just how simple this stuff is.

-- 
Raul
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to