I have a simple question about the callability of language constructs and
whether or not that's something that might change in the future. Consider:
var_dump(is_callable('echo')); // bool(false)
var_dump(call_user_func('echo', 'foo')); // E_WARNING
echo('foo'); // foo
var_dump(is_callable('isset')); // bool(false)
var_dump(isset(1)); // E_ERROR
Obviously this behavior arises because tokens like echo
and isset
are
language constructs and not functions. I can see some potential benefits
for working around this. For example, say I want to filter only the NULL
elements from an array but keep the other "falsy" values. Recognizing
isset
as callable would allow me to do this:
var_dump(array_filter([0, FALSE, NULL], 'isset')); // [0, FALSE]
Of course, this limitation is trivial to work around with a userland
callback to check for the explicit NULL
equivalency, but it would be nice
to avoid the hassle. So my question is ...
How deeply ingrained into the engine is this behavior? Is there any chance
of language constructs ever passing the tests for callability or is that
just a pipe dream that's not worth the implementation effort?
I have a simple question about the callability of language constructs and
whether or not that's something that might change in the future. Consider:var_dump(is_callable('echo')); // bool(false)
var_dump(call_user_func('echo', 'foo')); //E_WARNING
echo('foo'); // foovar_dump(is_callable('isset')); // bool(false)
var_dump(isset(1)); //E_ERROR
Obviously this behavior arises because tokens like
echo
andisset
are
language constructs and not functions. I can see some potential benefits
for working around this. For example, say I want to filter only theNULL
elements from an array but keep the other "falsy" values. Recognizing
isset
as callable would allow me to do this:var_dump(array_filter([0, FALSE, NULL], 'isset')); // [0, FALSE]
array_filter([…], 'is_null');
Of course, this limitation is trivial to work around with a userland
callback to check for the explicitNULL
equivalency, but it would be nice
to avoid the hassle. So my question is ...How deeply ingrained into the engine is this behavior? Is there any chance
of language constructs ever passing the tests for callability or is that
just a pipe dream that's not worth the implementation effort?
2013/7/19 Peter Cowburn petercowburn@gmail.com
I have a simple question about the callability of language constructs and
whether or not that's something that might change in the future.
Consider:var_dump(is_callable('echo')); // bool(false)
var_dump(call_user_func('echo', 'foo')); //E_WARNING
echo('foo'); // foovar_dump(is_callable('isset')); // bool(false)
var_dump(isset(1)); //E_ERROR
Obviously this behavior arises because tokens like
echo
andisset
are
language constructs and not functions. I can see some potential benefits
for working around this. For example, say I want to filter only theNULL
elements from an array but keep the other "falsy" values. Recognizing
isset
as callable would allow me to do this:var_dump(array_filter([0, FALSE, NULL], 'isset')); // [0, FALSE]
array_filter([…], 'is_null');
That would do the opposite of what you want.
Of course, this limitation is trivial to work around with a userland
callback to check for the explicitNULL
equivalency, but it would be nice
to avoid the hassle. So my question is ...How deeply ingrained into the engine is this behavior? Is there any
chance
of language constructs ever passing the tests for callability or is that
just a pipe dream that's not worth the implementation effort?
2013/7/19 Peter Cowburn petercowburn@gmail.com
I have a simple question about the callability of language constructs
and
whether or not that's something that might change in the future.
Consider:var_dump(is_callable('echo')); // bool(false)
var_dump(call_user_func('echo', 'foo')); //E_WARNING
echo('foo'); // foovar_dump(is_callable('isset')); // bool(false)
var_dump(isset(1)); //E_ERROR
Obviously this behavior arises because tokens like
echo
andisset
are
language constructs and not functions. I can see some potential benefits
for working around this. For example, say I want to filter only theNULL
elements from an array but keep the other "falsy" values. Recognizing
isset
as callable would allow me to do this:var_dump(array_filter([0, FALSE, NULL], 'isset')); // [0, FALSE]
array_filter([…], 'is_null');
That would do the opposite of what you want.
Absolutely (I blame Friday). Still, this is only being suggested because
"isset" just happens to do what is needed in this case? Where to other
language constructs fit into it?
Of course, this limitation is trivial to work around with a userland
callback to check for the explicitNULL
equivalency, but it would be
nice
to avoid the hassle. So my question is ...How deeply ingrained into the engine is this behavior? Is there any
chance
of language constructs ever passing the tests for callability or is that
just a pipe dream that's not worth the implementation effort?
Oh yeah, I see your point about is_null but not why it makes any more
sense to allow language constructs there.
Yeah I don't know if it even does. I'm not even really sure if there's a
good example use case for it besides the array_filter/isset combo. My
question was really only exploratory in nature.
On Fri, Jul 19, 2013 at 1:12 PM, Peter Cowburn petercowburn@gmail.com
wrote:
Oh yeah, I see your point about is_null but not why it makes any more
sense to allow language constructs there.
On Fri, Jul 19, 2013 at 1:11 PM, Jelle Zijlstra jelle.zijlstra@gmail.comwrote:
2013/7/19 Peter Cowburn petercowburn@gmail.com
I have a simple question about the callability of language constructs
and
whether or not that's something that might change in the future.
Consider:var_dump(is_callable('echo')); // bool(false)
var_dump(call_user_func('echo', 'foo')); //E_WARNING
echo('foo'); // foovar_dump(is_callable('isset')); // bool(false)
var_dump(isset(1)); //E_ERROR
Obviously this behavior arises because tokens like
echo
andisset
are
language constructs and not functions. I can see some potential benefits
for working around this. For example, say I want to filter only theNULL
elements from an array but keep the other "falsy" values. Recognizing
isset
as callable would allow me to do this:var_dump(array_filter([0, FALSE, NULL], 'isset')); // [0, FALSE]
array_filter([…], 'is_null');
That would do the opposite of what you want.
Of course, this limitation is trivial to work around with a userland
callback to check for the explicitNULL
equivalency, but it would be
nice
to avoid the hassle. So my question is ...How deeply ingrained into the engine is this behavior? Is there any
chance
of language constructs ever passing the tests for callability or is that
just a pipe dream that's not worth the implementation effort?
array_filter([…], 'is_null');
Doesn't work -- is_null
would return TRUE
leaving a result of [NULL]
after the array_filter operation. That's the diametric opposite of what my
example code looks to do.
On Fri, Jul 19, 2013 at 1:07 PM, Peter Cowburn petercowburn@gmail.comwrote:
I have a simple question about the callability of language constructs and
whether or not that's something that might change in the future. Consider:var_dump(is_callable('echo')); // bool(false)
var_dump(call_user_func('echo', 'foo')); //E_WARNING
echo('foo'); // foovar_dump(is_callable('isset')); // bool(false)
var_dump(isset(1)); //E_ERROR
Obviously this behavior arises because tokens like
echo
andisset
are
language constructs and not functions. I can see some potential benefits
for working around this. For example, say I want to filter only theNULL
elements from an array but keep the other "falsy" values. Recognizing
isset
as callable would allow me to do this:var_dump(array_filter([0, FALSE, NULL], 'isset')); // [0, FALSE]
array_filter([…], 'is_null');
Of course, this limitation is trivial to work around with a userland
callback to check for the explicitNULL
equivalency, but it would be nice
to avoid the hassle. So my question is ...How deeply ingrained into the engine is this behavior? Is there any chance
of language constructs ever passing the tests for callability or is that
just a pipe dream that's not worth the implementation effort?
How deeply ingrained into the engine is this behavior? Is there any chance
of language constructs ever passing the tests for callability or is that
just a pipe dream that's not worth the implementation effort?
It's actually pretty trivial to provide functions for echo and print (just
did a 5 minute POC), but I'm not convinced it's very useful. I don't think
isset would be possible other than making it equivalent to an is_not_null.
If the aim is some sort of consistency, what would you do with constructs
like define()
or include()?
Arpad
It would more than likely create some semantic nightmares. I can envision
people doing numpty things like:
array_map('include', $dependencyFilesArr);
While it works, it somewhat obscures what you're trying to accomplish in
the code. The maintainability nightmare alone may be enough to
counterbalance any benefits. Then again, who needs
readability/maintainability when you can write hopelessly impenetrable
code? :)
How deeply ingrained into the engine is this behavior? Is there any chance
of language constructs ever passing the tests for callability or is that
just a pipe dream that's not worth the implementation effort?It's actually pretty trivial to provide functions for echo and print (just
did a 5 minute POC), but I'm not convinced it's very useful. I don't think
isset would be possible other than making it equivalent to an is_not_null.If the aim is some sort of consistency, what would you do with constructs
likedefine()
or include()?Arpad
While it works, it somewhat obscures what you're trying to accomplish in
the code. The maintainability nightmare alone may be enough to
counterbalance any benefits. Then again, who needs
readability/maintainability when you can write hopelessly impenetrable
code? :)
Yes, quite, let's just pretend this thread never happened ;)
Arpad
While it works, it somewhat obscures what you're trying to accomplish in
the code. The maintainability nightmare alone may be enough to
counterbalance any benefits. Then again, who needs
readability/maintainability when you can write hopelessly impenetrable
code? :)Yes, quite, let's just pretend this thread never happened ;)
Let's also pretend I didn't suggest to add a third argument to
array_filter()
;
array_filter($arr, 'is_null', PHP_FILTER_INVERT);
;-)
Arpad
--
Tjerk
I think the idea comes from a good place, but the actual, practical
usefulness of it is so low that the availability of workaround negates even
the very small amount of effort it would take to create (and maintain!)
shadow functions for the language constructs.
array_filter($arr, function($val) { echo $val; }); <--- done. No
gymnastics needed.
On Fri, Jul 19, 2013 at 8:53 PM, Tjerk Anne Meesters datibbaw@php.netwrote:
On Fri, Jul 19, 2013 at 6:28 PM, Daniel Lowrey rdlowrey@gmail.com
wrote:While it works, it somewhat obscures what you're trying to accomplish
in
the code. The maintainability nightmare alone may be enough to
counterbalance any benefits. Then again, who needs
readability/maintainability when you can write hopelessly impenetrable
code? :)Yes, quite, let's just pretend this thread never happened ;)
Let's also pretend I didn't suggest to add a third argument to
array_filter()
;array_filter($arr, 'is_null', PHP_FILTER_INVERT);
;-)
Arpad
--
Tjerk
Hi,
I have a simple question about the callability of language constructs and
whether or not that's something that might change in the future. Consider:var_dump(is_callable('echo')); // bool(false)
var_dump(call_user_func('echo', 'foo')); //E_WARNING
echo('foo'); // foovar_dump(is_callable('isset')); // bool(false)
var_dump(isset(1)); //E_ERROR
By itself the idea looks good and useful - but There is an issue: Those
language constructs have different semantics from functions. On the one
side there a simple difference which can more or less be ignored - like
the fact that "echo" has no return value and might be called without
parentheses.
But also more complex ones:
var_dump(array_filter([0, FALSE, NULL], 'isset')); // [0, FALSE]
The argument for isset is not sent via the regular parameter stack but
directly as operands to the opcode. This is a key part to the trick on
how it works for not producing a notice about undeclared variables and
not creating it as userland emulations would.
So let's assume we allow this then we must allow this simple code:
$c = 'isset';
$c($foo);
Now the opcode generated by the compiler here won't know what $c is in
the second line (yes, yes, in this case an optimizer could figure it
out) and will produce opcode which tries to fetch $foo on the argument
stack. Now we could fix this in the executor by doing a string
comparison on the function name and - oh wait - we'll already have
messed with a variable which shouldn't be there ...
So, unfortunately no, language constructs have different semantics which
we can't emulate inside function semantics (well ok, it is software, so
it is thinkable .. but nobody,yet, came up with a robust patch which
doesn't cause maintenance and performance penalty)
johannes
Johannes Schlüter wrote:
So, unfortunately no, language constructs have different semantics which
we can't emulate inside function semantics (well ok, it is software, so
it is thinkable .. but nobody,yet, came up with a robust patch which
doesn't cause maintenance and performance penalty)
Is there a reason that echo/print couldn't be implemented as functions
with some sort of backwards compatibility layer? isset/etc make sense to
be language constructs, but I can't think of any reason echo/print need
to be.
--
Ryan McCue
<http://ryanmccue.info/
Lack of parenthesis and the fact that EVERY project out there takes
advantage of this affordance. So BC nightmare.
Johannes Schlüter wrote:
So, unfortunately no, language constructs have different semantics which
we can't emulate inside function semantics (well ok, it is software, so
it is thinkable .. but nobody,yet, came up with a robust patch which
doesn't cause maintenance and performance penalty)Is there a reason that echo/print couldn't be implemented as functions
with some sort of backwards compatibility layer? isset/etc make sense to
be language constructs, but I can't think of any reason echo/print need
to be.--
Ryan McCue
<http://ryanmccue.info/
Well, now... to be fair... You could make them functions and use the same
parser trick the backtick operator uses. to map the non-parenthesized
versions.... feels messy though. I'd just hate to get stuck with a hacky
workaround like that for the long term.
Lack of parenthesis and the fact that EVERY project out there takes
advantage of this affordance. So BC nightmare.Johannes Schlüter wrote:
So, unfortunately no, language constructs have different semantics which
we can't emulate inside function semantics (well ok, it is software, so
it is thinkable .. but nobody,yet, came up with a robust patch which
doesn't cause maintenance and performance penalty)Is there a reason that echo/print couldn't be implemented as functions
with some sort of backwards compatibility layer? isset/etc make sense to
be language constructs, but I can't think of any reason echo/print need
to be.--
Ryan McCue
<http://ryanmccue.info/
Sara Golemon wrote:
Well, now... to be fair... You could make them functions and use the same
parser trick the backtick operator uses. to map the non-parenthesized
versions.... feels messy though. I'd just hate to get stuck with a hacky
workaround like that for the long term.
That's what I meant by the "backwards compatibility layer". Not saying
we have to deprecate the use as a construct, but why can't we enable the
use as a function (and hence, callback, etc)? It feels less cleaner from
my point of view (userland).
--
Ryan McCue
<http://ryanmccue.info/
The danger I see there is the fact that we'd have two different
implementations of the same functionality (leading to potential code-rot),
and worse, it wouldn't be obvious from userspace when one implementation
would be used over the other. (We'd know, but I mean for the average PHP
user, leading to weird unreproducible bug reports).
-Sara
Sara Golemon wrote:
Well, now... to be fair... You could make them functions and use the same
parser trick the backtick operator uses. to map the non-parenthesized
versions.... feels messy though. I'd just hate to get stuck with a hacky
workaround like that for the long term.That's what I meant by the "backwards compatibility layer". Not saying
we have to deprecate the use as a construct, but why can't we enable the
use as a function (and hence, callback, etc)? It feels less cleaner from
my point of view (userland).--
Ryan McCue
<http://ryanmccue.info/
Sara Golemon wrote:
Well, now... to be fair... You could make them functions and use the same
parser trick the backtick operator uses. to map the non-parenthesized
versions.... feels messy though. I'd just hate to get stuck with a hacky
workaround like that for the long term.That's what I meant by the "backwards compatibility layer". Not saying
we have to deprecate the use as a construct, but why can't we enable the
use as a function (and hence, callback, etc)? It feels less cleaner from
my point of view (userland).
There again is a thing we can't emulate using functions: The operator
precedence when using () with echo is "special":
php > echo(0) || print(1);
11
alright, that's weird isn't it? Anyways let's try to emulate using a
function:
php > function echo_func($foo) {
php { echo $foo;
php { }
php > echo_func(0) || print(1);
01
damn different result, ah, echo-func returns NULL
maybe when we return
true?
php function echo_func1($foo) {
php { echo $foo;
php { return true;
php { }
php > echo_func1(0) || print(1);
0
still not. Reason is that currently in
echo(0) || print(1);
the expression (0) || print(1) is evaluated first and then the result is
passed to echo.
Maybe one might have designed it differently but more than 15 years into
the game it's hard.
johannes
Hi!
Is there a reason that echo/print couldn't be implemented as functions
with some sort of backwards compatibility layer? isset/etc make sense to
Yes, the reason is not fixing what isn't broken :)
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Stas Malyshev wrote:
Is there a reason that echo/print couldn't be implemented as functions
with some sort of backwards compatibility layer? isset/etc make sense to
Yes, the reason is not fixing what isn't broken:)
And perhaps introducing 'black holes' like the one created when <?= suddenly
stopped working, then had to be repaired. If we were writing and supporting
'flat' code where we know how everything works, things would be a lot easier,
but many of us are using third party libraries and frameworks which tend to
follow 'new practices' while some of us still stubbornly stick to old ones ;)
The discussion on picking up a know version of a library is very relevant here,
and would at least help to maintain consistency. Can one ensure that backwards
compatibility does not become undefined in some circumstances and just adds to
the workload ... and creates further havoc in user land?
There has to be a substantial reason to implementing change?
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
Stas Malyshev wrote:
Is there a reason that echo/print couldn't be implemented as functions
with some sort of backwards compatibility layer? isset/etc make sense to
Yes, the reason is not fixing what isn't broken:)
And perhaps introducing 'black holes' like the one created when <?=
suddenly stopped working, then had to be repaired. If we were writing and
supporting 'flat' code where we know how everything works, things would be
a lot easier, but many of us are using third party libraries and frameworks
which tend to follow 'new practices' while some of us still stubbornly
stick to old ones ;) The discussion on picking up a know version of a
library is very relevant here, and would at least help to maintain
consistency. Can one ensure that backwards compatibility does not become
undefined in some circumstances and just adds to the workload ... and
creates further havoc in user land?There has to be a substantial reason to implementing change?
I agree this is a largely pointless can of worms, but here's my POC from
yesterday in case anyone wants to play with it:
https://gist.github.com/arraypad/6044439
Arpad
I agree this is a largely pointless can of worms, but here's my POC from
yesterday in case anyone wants to play with it:
https://gist.github.com/arraypad/6044439
If we want to provide a simple function for easy printing for
callbacks and such it should not use the echo/print names. This messes
with debugging etc. (mind: function names listed in xdebug's output, gdb
breakpoint on zif_echo, our dtrace hooks will be misleading, ...)
johannes