Hi all,

I have been pondering for a while how to improve the anonymous class syntax to allow "capturing" of values from the outer scope, and came up with the idea of a special variable marker for "lexically captured variable" - instead of $foo, you would write $!foo or $^foo (I quite like the "upwardness" of $^).

To give a simple example, values can only pass into the anonymous class via its constructor, like this:

function foo(int $outer) {
    return new class($outer) {
        public function __construct(
            private int $myProp
        ) {}
        public function getIt() {
            return $this->myProp;
        }
    };
}

The idea is that you would instead be able to reference an outer variable directly anywhere in the declaration, removing a lot of boilerplate:

function foo(int $outer) {
    return new class {
        public function getIt() {
            return $^outer;
        }
    };
}

The outer variable would be captured by value, and carried around with the instance, like existing closures.

I suggest it is also treated as readonly, and visible strictly in the lexical definition, not generally in private scope (it couldn't be referenced from an applied trait, for instance).

Using it to initialise a property or local variable would allow you to give it an explicit scope, while still avoiding the constructor:

function foo(int $outer) {
    private $inner = $!outer;
    return new class {
        public function getIt() {
            $this->inner++;
            return $this->inner;
        }
    };
}


It then occurred to me that the same syntax could be used in multi-statement anonymous functions instead of an explicit use() statement. This strikes a different balance between conciseness and explicitness than full automatic capture:

$before = function($x) use ($y, $z) {
    $a = $x * $y;
    return do_something($a, $z);
}
$after = function($x) {
    $a = $x * $^y;
    return do_something($a, $^z);
}


To keep this message short, I've put some more examples and thoughts into a GitHub Gist here: https://gist.github.com/IMSoP/4157af05c79b3df4c4853f5a58766341

I'd be interested to hear anyone's thoughts - is this a promising idea to explore, or have I gone completely off the rails?

Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to