//
// Function.memo
//
;
( function ( _host_ ) {
var
t = !0,
f = !t,
pn = String( this ),
mmfn = function ( fn, mem_read_callback, mem_write_callback ) {
return ( function( input, output, mrcb, mwcb, k, v ) {
// capture original fns
var
origFn = this,
// define 'memo' fn
mmfn = function ( /*...params*/ ) {
// capture passed arguments
var inputArgs = slc( arguments );
// reset the flag,
// -1 indicates that passed arguments haven't been proccessed yet.
k = -1;
// see if args have been already processed
// scan inputs[]
each( input, function ( input_args, pos ) {
// update k to point to memoized args
return ( is_same_arrays( inputArgs, input_args ) ) ? ( k = pos, f ) : t;
} );
// if k is -1 passed args are processe for the 1st time
// execute original fn,
// store result in output[],
// store arguments[] in inputs[],
// call provided ( optional ) 'mem_write_callback',
// return result
// else
// call provided ( optional )'mem_read_callback',
// return memoized result
return ( k == -1 ) ?
(
v = origFn.apply( this, inputArgs ),
input.push( inputArgs ),
output.push( v ),
( isfn( mwcb ) && mwcb.call( this, inputArgs, v ) ),
v
):
( isfn( mrcb ) && mrcb.call( this, inputArgs, output[k] ), output[k] );
};
// optionaly provide access to cache
mmfn.cache = {
inputs : input,
outputs : output
};
mmfn.mclear = function () {
input.splice( 0, input.length );
output.splice( 0, output.length );
};
// return memoizer
return mmfn;
} ).call( fn, [], [], mem_read_callback, mem_write_callback );
};
// #helpers
function is_same_arrays( a1, a2 ) {
var flg = t;
return ( each( a1, function ( v, k ) { return ( v === a2[k] ) ? t: ( flg = f ) ; } ), flg );
}
function each( arr, fn ) {
for ( var l = arr.length, i = 0; i < l; i++ )
if ( ( fn.call( arr, arr[i], i ) ) === f ) break;
return arr;
}
function slc( args, i, j ) {
return Array.prototype.slice.call( args, i, j );
}
function isfn( fn ) {
return typeof fn === 'function';
}
// attach 'memo' fn to host obj
_host_[pn] = mmfn;
} ).call( new String('memo'), ( typeof context === 'undefined' ? Function : context ) );
var
f1 = Function.memo(
function ( v ) { return v*v; },
function ( inpArr, res ) { console.log('cache read: ', inpArr.join(''),', ', res); },
function ( inpArr, res ) { console.log('cache write: ', inpArr.join(''),', ', res); }
);
f1(1);
f1(2);
f1(1);
f1(2);
f1(1);
f1(3);
//
// logs
//
// cache write, 1 , 1
// cache write, 2 , 4
// cache read, 1 , 1
// cache read, 2 , 4
// cache read, 1 , 1
// cache write, 3 , 9
//