docs: function _is_same(a, b){
  	//bark('typeof(a, b): ' + typeof(a) + ',' + typeof(b));
  
  	var ret = false;
  	if( a == b ){ // atoms, incl. null and 'string'
  	    //bark('true on equal atoms: ' + a + '<>' + b);
  	    ret = true;
  	}else{ // is list or obj (ignore func)
  	    if( typeof(a) === 'object' && typeof(b) === 'object' ){
  		//bark('...are objects');
  		
  		// Null is an object, but not like the others.
  		if( a == null || b == null ){
  		    ret = false;
  		}else if( Array.isArray(a) && Array.isArray(b) ){ // array equiv
  		    //bark('...are arrays');
  		    
  		    // Recursively check array equiv.
  		    if( a.length == b.length ){
  			if( a.length == 0 ){
  			    //bark('true on 0 length array');
  			    ret = true;
  			}else{
  			    ret = true; // assume true until false here
  			    for( var i = 0; i < a.length; i++ ){
  				if( ! _is_same(a[i], b[i]) ){
  				    //bark('false on diff @ index: ' + i);
  				    ret = false;
  				    break;
  				}
  			    }
  			}
  		    }
  
  		}else{ // object equiv.
  
  		    // Get unique set of keys.
  		    var a_keys = Object.keys(a);
  		    var b_keys = Object.keys(b);
  		    var keys = a_keys.concat(b_keys.filter(function(it){
  			return a_keys.indexOf(it) < 0;
  		    }));
  		    
  		    // Assume true until false.
  		    ret = true;
  		    for( var j = 0; j < keys.length; j++ ){ // no forEach - break
  			var k = keys[j];
  			if( ! _is_same(a[k], b[k]) ){
  			    //bark('false on key: ' + k);
  			    ret = false;
  			    break;
  			}
  		    }
  		}
  	    }else{
  		//bark('false by default');
  	    }
  	}
  	
  	return ret;
      }