On 28/03/2020 21:37, Jakob Givoni wrote:
I really believe that COPA can help thousands of PHP developers
without introducing any new complexities to the language and my hope
is that perfect won't be the enemy of good this time around :-)
Any last words unsaid before the final lap commences?
Hi Jakob,
It occurred to me thinking about alternative syntaxes that COPA could be
seen as a limited form of the "with" statement found in some languages,
e.g. JS [1], VisualBasic [2], Delphi [3], Groovy [4] (note that with
blocks in Python are something different).
[1]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with
[2]
https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/with-end-with-statement
[3] http://www.delphibasics.co.uk/RTL.asp?Name=With
[4]
https://docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/Object.html#with(boolean,%20groovy.lang.Closure)
The Groovy version is particularly relevant, since it can be used as an
expression, not just a statement block, so this example from your RFC:
doTheFoo((new Foo)->[
a = 1,
b = 2,
c = 3,
]);
would I think look something like this in Groovy:
doTheFoo(new Foo().with(true) {
a = 1
b = 2
c = 3
})
The notable differences between COPA and with blocks are:
- with statements generally allow methods as well as properties to be
referenced on the given object
- with blocks contain a series of full statements in some form (either a
syntactical block, or some form of closure); COPA instead contains a
special list of key-value pairs
- with blocks generally fall back to other scopes if a property or
method is not found, and are often criticised for the resulting ambiguity
COPA trades the scope ambiguity for reduced flexibility: the left-hand
side of each assignment is always a property name, and the
right-hand-side is a normal expression, so doesn't benefit from the syntax.
This example from the RFC:
$myObj->[
foo = 10,
bar = $myObj->foo + 20,
];
Wouldn't need the extra reference to $myObj in Groovy:
myObj.with {
foo = 10
bar = foo + 20
}
Similarly, the nesting example in Future Scope:
$foo->[
a = 1,
b = $foo->b->[
c = 2,
],
];
Could be written something like this:
foo.with {
a = 1
b = b.tap {
c = 2
}
}
If we used a different sigil instead of $ for "property and method of
with'd object", we could avoid the ambiguity of most with blocks, but
get most of the power; something like this:
$foo = new Foo with {
->a = 1;
->b = ->1 + 10;
->c = new Bar with {
->d = 'Hello';
};
->start();
}
I'm not sure whether I like this idea or not, but I thought I'd share
it, because I think COPA as currently proposed is too narrow a use case
to deserve a special syntax.
Regards,
--
Rowan Tommins (né Collins)
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php