Last active
November 4, 2016 15:04
-
-
Save nicolas-grekas/b23b27d9fd12796f89d15191f3cc9829 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// A proposal for a future PHP version: builtin lazy variables | |
class foo | |
{ | |
function __construct(PDO $db) { | |
$this->db = $db; | |
} | |
function doJob() | |
{ | |
$sql = '...'; | |
$this->db->query($sql); | |
} | |
} | |
$host = 'localhost'; | |
// Here is the new construct: a variable whose value | |
// can be computed later thanks to a closure, | |
// with a type that is known at compile time (PDO): | |
$db = var(PDO) use ($host) { | |
return new PDO($host); | |
}; | |
$foo = new foo($db); // works, no db connection is made until really needed | |
/* | |
* - when only type information is needed, the provided var type should be used to resolve the need; | |
* - when the value is needed, the value should be computed and memoized so that the closure is never | |
evaluated again and can be freed; | |
* - any Exception or Error thrown by the closure should be propagated as usual; | |
* - returned values must match defined return type in `var (PDO)` or throw a TypeError | |
* - by nature, this construct is not reflectable and must be totally undifferentiable from its return value; | |
* - when a circular dependency is found while resolving the lazy-chain cascade (if any), an Error should be raised (exact type to be defined). | |
* | |
* To play nice with existing PHP extensions, this eval-n-replace should happen by default when any internal | |
* function/method is called (same hook as __toString?) Some internal functions that use only type information | |
* should be able to opt into not-triggering the lazy-evaluation (e.g. gettype, get_class). | |
*/ | |
gettype($db) === 'object'; // true, does NOT trigger lazy-eval | |
get_class($db) === 'PDO'; // true, does NOT trigger lazy-eval | |
$db instanceof PDO; // true, does NOT trigger lazy-eval | |
var_dump($db); // exact same output as var_dump(new PDO(...)), DOES trigger lazy-eval | |
$db === $bar; // DOES trigger lazy-eval | |
$r = new ReflectionClass($db); // DOES trigger lazy-eval | |
$r->name === 'PDO'; // true | |
$foo->doJob(); // DOES trigger lazy-eval |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment