Hi again all,

On Sat, Dec 13, 2008 at 14:34, Arnar Birgisson <[email protected]> wrote:
> As for permuting arguments, I have some ideas.. let me think about them a bit.

Here is an implementation of partial that does out-of-order arguments,
both via unnumbered placeholders and numbered ones (see the function
test() for examples):

// I'm also attaching an html file that you can load in your browser
to see it in action.

function p() {
   var args = Array.prototype.slice.call(arguments);
   appendChildNodes('logpane', DIV(null, args.join(', ')));
}

function _(n) {
    return {'__argument_index': n};
}

var invalidNumberOfArgs = new Error("Number of given arguments does
not match number of unknown arguments.");
var mixingNumberedWithUnnumbered = new Error("Cannot mix numbered
argument placeholders with numbered ones.");
var invalidNumberedPlaceholders = new Error("Numbered placeholders
must be sequential (i.e. no gaps) starting from 0 or 1.");

function partial() {
   var args = Array.prototype.slice.call(arguments);
   var f = args.shift();

   var unnumbered = filter(MochiKit.Base.partial(operator.seq, _), args).length;
   var indexes = map(itemgetter('__argument_index'), filter(function (a) {
       return typeof a == 'object' && '__argument_index' in a;
   }, args));

   if (unnumbered > 0 && indexes.length > 0) {
       throw mixingNumberedWithUnnumbered;
   }

   if (indexes.length == 0) {
       return function() {
           if (arguments.length != unnumbered) {
               throw invalidNumberOfArgs;
           }
           var passed = Array.prototype.slice.call(arguments);
           var filled = map(function (a) {
               if (a === _) {
                   return passed.shift();
               } else {
                   return a;
               }
           }, args);
           return f.apply(this, filled);
       }
   } else {
       // some sanity checks
       var sorted = indexes.slice(0);
       sorted.sort();
       if (sorted[0] == 1) {
           indexes = map(function (x) {return x-1;}, indexes);
           sorted  = map(function (x) {return x-1;}, sorted);
       } else if (sorted[0] != 0) {
           throw invalidNumberedPlaceholders; // must start with 0 or 1
       }
       // make sure there are no gaps
       if (!every(izip(count(), sorted), function (pair) { return
pair[0] == pair[1]})) {
           throw invalidNumberedPlaceholders; // can't have gaps
       }
       return function() {
           if (arguments.length != indexes.length) {
               throw invalidNumberOfArgs;
           }
           var passed = Array.prototype.slice.call(arguments);
           var i = 0;
           var filled = map(function (a) {
               if (typeof a == 'object' && '__argument_index' in a) {
                   return passed[indexes.shift()];
               } else {
                   return a;
               }
           }, args);
           return f.apply(this, filled);
       }
   }
}

function test() {
   p('start');

   var x = partial(p, "one", _, "three");
   x('two');

   x = partial(p, _, _, "three", _);
   x('one', 'two', 'four');

   x = partial(p, _);
   x('one');

   x = partial(p, 'one');
   x();

   x = partial(p, _(2), _(1));
   x('two', 'one');

   // for convenience:
   function flip(f) { return partial(f, _(2), _(1)); }
   x = flip(p);
   x('two', 'one');

   // can also be zero based
   x = partial(p, _(1), _(0));
   x('two', 'one');

   x = partial(p, 'one', _(3), 'three', _(1), 'five', _(2));
   x('four', 'six', 'two');

   p('done');
}

addLoadEvent(test);


cheers,
Arnar

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"MochiKit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---

Title: untitled

Reply via email to