Skip to content

Instantly share code, notes, and snippets.

@taufik-nurrohman
Forked from bitlyfied/curry.php
Created April 9, 2014 10:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save taufik-nurrohman/10251127 to your computer and use it in GitHub Desktop.
Save taufik-nurrohman/10251127 to your computer and use it in GitHub Desktop.
<?php
function curry() {
$curryArgs = func_get_args();
return function() use ($curryArgs){
$function = array_shift($curryArgs);
$mergedArgs = array_merge($curryArgs, func_get_args());
return call_user_func_array($function, $mergedArgs);
};
}
$multiply = function($x, $y) {
return $x * $y;
};
$multiplyBy4 = curry($multiply, 4);
echo $multiplyBy4(2); // Echo: 8
<?php
class DynamicClosure {
public static function execute(Closure $closure) {
return call_user_func($closure);
}
}
echo '<br/>Standard factorial<br/>';
function factorial($n) {
echo 'call <br/>';
if ($n == 0) {
return 1;
} else {
return $n * factorial($n - 1);
}
}
echo factorial(10) . '<br/>'; // called 11 times
echo factorial(11) . '<br/>'; // called 12 times
echo factorial(8) . '<br/>'; // called 8 times
echo '<br/>Memoized factorial<br/>';
$memoizedFactorial = DynamicClosure::execute(function(){
// results are cached in an array
$results = array();
// the function is passing itself as a bound variable
return $factorial = function($n) use(&$results, &$factorial) {
echo 'call <br/>';
if (!isset($results[$n])) {
if ($n == 0) {
$results[$n] = 1;
} else {
$results[$n] = $n * $factorial($n - 1);
}
}
return $results[$n];
};
});
echo $memoizedFactorial(10) . '<br/>'; // called 11 times
echo $memoizedFactorial(11) . '<br/>'; // called only 2 times!
echo $memoizedFactorial(8) . '<br/>'; // called only 1 times!
<?php
class DynamicObject {
/**
* @var DynamicObject
*/
public $prototype;
public function __construct(array $attributes = array()) {
foreach ($attributes as $name => $value) {
$this->$name = $value;
}
}
public function __get($varName) {
if (!isset($this->$varName)) {
return $this->prototype->$varName;
}
}
public function __call($methodName, $params) {
array_unshift($params, $this);
if (isset($this->$methodName)) {
return call_user_func_array($this->$methodName, $params);
} else {
return call_user_func_array($this->prototype->$methodName, $params);
}
}
public static function extend(DynamicObject $prototype, $attributes = array()) {
$child = new self($attributes);
$child->prototype = $prototype;
return $child;
}
public static function execute(Closure $closure) {
return call_user_func($closure);
}
}
$dialogsModule = DynamicObject::execute(function() {
// private stuff
$self = new DynamicObject(array(
'privateName' => 'Piggy',
'addNewLine' => function($me) {
echo '<br/>';
}
));
// public stuff
return new DynamicObject(array(
'publicName' => 'Mickey Mouse',
'sayHello' => function($me) use(&$self) {
echo 'hi';
$self->addNewLine();
echo 'hello';
$self->addNewLine();
},
'sayName' => function($me) use(&$self) {
echo 'My public name is:' . $me->publicName;
$self->addNewLine();
echo 'My private name is:' . $self->privateName;
$self->addNewLine();
}
));
});
echo $dialogsModule->publicName . '<br/>'; // Echo: Mickey Mouse
$dialogsModule->sayHello(); // Echo: hi<br/>hello
$dialogsModule->sayName(); // Echo: My public name is: Micket Mouse <br/> My private name is: Piggy
<?php
class DynamicObject {
/**
* @var DynamicObject
*/
public $prototype;
public function __construct(array $attributes = array()) {
foreach ($attributes as $name => $value) {
$this->$name = $value;
}
}
public function __get($varName) {
if (!isset($this->$varName)) {
return $this->prototype->$varName;
}
}
public function __call($methodName, $params) {
array_unshift($params, $this);
if (isset($this->$methodName)) {
return call_user_func_array($this->$methodName, $params);
} else {
return call_user_func_array($this->prototype->$methodName, $params);
}
}
public static function extend(DynamicObject $prototype, $attributes = array()) {
$child = new self($attributes);
$child->prototype = $prototype;
return $child;
}
}
$animal = new DynamicObject(array(
'age' => 0,
'name' => 'El Barto',
'breathe' => function($me) {
echo $me->name . " is breathing<br/>";
}
));
$animal->breathe(); // Echo: El Barto is breathing
///////////////////////////////////////////////////////////////////////////////
// Prototypal inheritance: an object extend another object
//
$cat = DynamicObject::extend($animal, array(
'breathe' => function($me) {
echo $me->name . " is purring<br/>";
}
));
$cat->breathe(); // Echo: El Barto is purring
// Modifyng the prototype dynamically change the child too
$animal->eat = function($me){
echo 'Gnam!<br/>';
};
$cat->eat(); // Echo: Gnam
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment