docs: function (getter_fn, options) {
  		options = extend({
  			hash: memoize_default_hash,
  			equals: memoize_default_equals,
  			context: root,
  			literal_values: true
  		}, options);
  
  		// Map from args to value
  		options.args_map = new MapConstraint({
  			hash: options.hash,
  			equals: options.equals,
  			literal_values: options.literal_values
  		});
  
  		// When getting a value either create a constraint or return the existing value
  		var rv = function () {
  			var args = slice.call(arguments),
  				constraint = options.args_map.getOrPut(args, function() {
  					return new Constraint(function () {
  						return getter_fn.apply(options.context, args);
  					});
  				});
  			return constraint.get();
  		};
  
  		// Clean up memory after self
  		rv.destroy = function (silent) {
  			options.args_map.forEach(function (constraint) {
  				constraint.destroy(silent);
  			});
  			options.args_map.destroy(silent);
  		};
  
  		// Run through every argument and call fn on it
  		rv.each = function (fn) {
  			options.args_map.forEach(fn);
  		};
  		rv.options = options;
  		return rv;
  	}