Hi,
PHP is a weak-typed language which casts in the background as required - at
least most of the time. I recently found an exception which bugged me:
$a = false;
$a++;
Here $a isn't casted to int or "incremented" to true but the incrementing has
no effect. By checking zend_operators.c I saw that booleans had no explicit
incrementing rule but uses just the default in the relevant switch.
Looking a bit deeper it got quite interesting: NULL++ gives as result the
integer one. This is fine for incrementing undefined variables but imho
inconsistent with the behavior of false. NULL-- evaluates to NULL
similar to
false but different from NULL++.
All this makes using PHP harder than needed. At least I spent quite some time
finding that my variable was set to false instead of 0 (or NULL).
I wrote the attached patch which allows in-/decrementing of simple types by
casting bools and NULL
to long. Yes, it would be a BC break but I don't think
someone relies on false++ being false and it would make life simpler.
Comments?
johannes
P.S. If the patch doesn't come through: It's available via web, too:
http://www.schlueters.de/zend_incdec_with_bool.diff
Johannes Schlüter Mayflower GmbH / ThinkPHP
http://thinkphp.de http://blog.thinkphp.de
Hi,
PHP is a weak-typed language which casts in the background as required - at
least most of the time. I recently found an exception which bugged me:$a = false;
$a++;Here $a isn't casted to int or "incremented" to true but the incrementing has
no effect. By checking zend_operators.c I saw that booleans had no explicit
incrementing rule but uses just the default in the relevant switch.Looking a bit deeper it got quite interesting: NULL++ gives as result the
integer one. This is fine for incrementing undefined variables but imho
inconsistent with the behavior of false. NULL-- evaluates toNULL
similar to
false but different from NULL++.All this makes using PHP harder than needed. At least I spent quite some time
finding that my variable was set to false instead of 0 (or NULL).I wrote the attached patch which allows in-/decrementing of simple types by
casting bools andNULL
to long. Yes, it would be a BC break but I don't think
someone relies on false++ being false and it would make life simpler.Comments?
I did this a year or so ago, and after discussing with Andi we decided
not to promote types in this case.
Derick
--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
Hello Derick,
Sunday, June 5, 2005, 10:27:51 PM, you wrote:
Hi,
PHP is a weak-typed language which casts in the background as required - at
least most of the time. I recently found an exception which bugged me:$a = false;
$a++;Here $a isn't casted to int or "incremented" to true but the incrementing has
no effect. By checking zend_operators.c I saw that booleans had no explicit
incrementing rule but uses just the default in the relevant switch.Looking a bit deeper it got quite interesting: NULL++ gives as result the
integer one. This is fine for incrementing undefined variables but imho
inconsistent with the behavior of false. NULL-- evaluates toNULL
similar to
false but different from NULL++.All this makes using PHP harder than needed. At least I spent quite some time
finding that my variable was set to false instead of 0 (or NULL).I wrote the attached patch which allows in-/decrementing of simple types by
casting bools andNULL
to long. Yes, it would be a BC break but I don't think
someone relies on false++ being false and it would make life simpler.Comments?
I did this a year or so ago, and after discussing with Andi we decided
not to promote types in this case.
Not promoting types would mean adding false++, and true-- doesn't it?
And again not doing this complicaates php needlessly. For example the two
snippets below are different, tell me why:
- if (($p=strpos(...)+1) > 0) ...
- $p = strpos(...);
$p++;
if ($p > 0) ...
Sidenote: Why is the following a parser error:
if (($p=strpos(...))++ > 0) ...
Best regards,
Marcus mailto:mail@marcus-boerger.de
At 2005-06-06 08:37, Marcus Boerger wrote:
Sunday, June 5, 2005, 10:27:51 PM, you wrote:
PHP is a weak-typed language which casts in the background as required - at
least most of the time.
Yes, but I think it doesn't always do it in an
intuitive way and I would rather have errors
or warnings instead.
I recently found an exception which bugged me:
$a = false;
$a++;Here $a isn't casted to int or "incremented" to true but the incrementing has
no effect. By checking zend_operators.c I saw that booleans had no explicit
incrementing rule but uses just the default in the relevant switch.
Yes, that is strange. I would like to plead for
a real boolean type. The argument of an if or
while statement for example has to be boolean
(or convertable to boolean).
In your case '$a=false;' should give $a the type
and I don't think that integer arithmetic should
be allowed on booleans, because it's confusing and
unnecessary. Give an error or warning instead.
Looking a bit deeper it got quite interesting: NULL++ gives as result the
integer one. This is fine for incrementing undefined variables but imho
inconsistent with the behavior of false. NULL-- evaluates toNULL
similar to
false but different from NULL++.
NULL
comes from C I think and stands for an uninitialized
pointer. There is no other way to empty a pointer except
by using 'pointer=(*char)0;', using NULL
is more clear.
Instead of filling a variable with a null pointer one
can unset() a variable in PHP.
I have no problems with integers and strings being
promoted to booleans, except for example that an
empty string is considered to be false and even
(in some versions?) a string containing '0' or even
'false' or even 'NULL'?
I like to write:
while (fgets($hf)) {
}
But this fails when an empty string is considered to be
false. BTW. the behaviour also depends on the fact if
"\r\n" is considered to be empty or not.
I don't remember if it also happens in the case
above or only in bigger expressions.
All this makes using PHP harder than needed. At least I spent quite some time
finding that my variable was set to false instead of 0 (or NULL).
My point too. Scripts in overly permissive and
'intelligent' languages like PHP tend to be hard
to debug.
C and Javascript were also made much more strict
later.
BTW. Wouldn't it be a good idea to split this
mailing list in a list about the definition
of the PHP language and the implementation and
versions etc.?
I wrote the attached patch which allows in-/decrementing of simple types by
casting bools andNULL
to long. Yes, it would be a BC break but I don't think
someone relies on false++ being false and it would make life simpler.Comments?
I did this a year or so ago, and after discussing with Andi we decided
not to promote types in this case.
As I said above I agree with not auto-promoting
booleans to other types. People should write
'$i=(int)$b;' because this conversion is very
unusual.
Not promoting types would mean adding false++, and true-- doesn't it?
false is a constant and can't be increment.
When you are in favor of incrementing booleans
you should also be able to increment a veriable
with the value true, but should it become false,
0 or 2 or stay the same?
Of course it's possible to think of the boolean
space as a one bit integer, so true+1 is false
again, but I'd much rather see an error or
warning.
And again not doing this complicaates php needlessly. For example the two
snippets below are different, tell me why:
- if (($p=strpos(...)+1) > 0) ...
- $p = strpos(...);
$p++;
if ($p > 0) ...
It should be the same indeed.
Sidenote: Why is the following a parser error:
if (($p=strpos(...))++ > 0) ...
You can't increment ($p=strpos()), because it's
not a left-value (=assignable variable). This
already wasn't the case in C. The result of an
assignment is the contents of the left-value
and not it's location.
Please also note that in C, the $p++ can lead to
very strange results, because it's not very well
defined when the incrementing is actually done.
For example:
*p++=i++;
shouldn't become:
++i;
*p=i;
++p;
but:
*p=i;
++p;
++i;
or:
*p=i;
++i;
++p;
A C compiler can postpone all of the
auto incrementing until after evaluating the
actual expression, to avoid problems with
expressions like:
*p++=*p++ + *p++;
(which is very dubious otherwise.
Please also consider that in your case:
($p=strpos())++
would have as a result the value of $p after
the assignment from strpos()
and not of that
plus on because $p would be increment after
being read. I tend use ++p and ++i wherever
appropriate in C and always in PHP. ++p
always stands for (p+=1) but p++ is much
more dubious.
Greetings,
Jaap
Hello Jaap,
Friday, June 10, 2005, 10:01:10 AM, you wrote:
NULL
comes from C I think and stands for an uninitialized
pointer. There is no other way to empty a pointer except
by using 'pointer=(*char)0;', usingNULL
is more clear.
you shall never cast 0 to anything since 0 matches any pointer.
Casting it would result in a typecast error or an unneccessary
casting. Thus #define NULL
0 is the only way. But that apart :-)
Instead of filling a variable with a null pointer one
can unset() a variable in PHP.
I have no problems with integers and strings being
promoted to booleans, except for example that an
empty string is considered to be false and even
(in some versions?) a string containing '0' or even
'false' or even 'NULL'?
I like to write:
while (fgets($hf)) {
}
But this fails when an empty string is considered to be
false. BTW. the behaviour also depends on the fact if
"\r\n" is considered to be empty or not.
Yes you definitively come from C.
(...)
BTW. Wouldn't it be a good idea to split this
mailing list in a list about the definition
of the PHP language and the implementation and
versions etc.?
We had that before and theoretically there are more lists which nobody
uses anymore. And then i think it is a very good idea that the developers
get feedback. There is a lot of noise but still a fair amount of really
good mails here that help direct the way PHP evolves.
Not promoting types would mean adding false++, and true-- doesn't it?
false is a constant and can't be increment.
It was a shortcut for $a=false; $a++; $b=true; $b--; of course. However
the shortcut is much easier to get.
When you are in favor of incrementing booleans
you should also be able to increment a veriable
with the value true, but should it become false,
0 or 2 or stay the same?
Since PHP conversion magic: true+1 => 2; false+1 => 1; 1+1 = >2
(...)
BTW, Nice commenting on the: ($p=strpos())++
Best regards,
Marcus mailto:mail@marcus-boerger.de
At 2005-06-10 22:37, Marcus Boerger wrote:
Friday, June 10, 2005, 10:01:10 AM, you wrote:
NULL
comes from C I think and stands for an uninitialized
pointer. There is no other way to empty a pointer except
by using 'pointer=(*char)0;', usingNULL
is more clear.you shall never cast 0 to anything since 0 matches any pointer.
0 is an integer and not a pointer and therefore I think
it should be cast. The idea behind NULL
seems to be that
it's not an integer but stands for a pointer containing
zero. I think that both ideas shouldn't be mixed.
I think there is no sense of writing (in C):
int i=NULL;
instead of:
int i=0;
Casting it would result in a typecast error
It shouldn't be an error to cast a value of a
certain type into that same type and in most
languages it isn't, so:
int i;
i=(int)i;
should never be a problem and certainly not in a
language like PHP where it's not always clear
of what type the source is.
or an unneccessary casting.
Casting in PHP is more meant to make sure that
the result is of a certain type, as far as I
understood it.
Thus #define
NULL
0 is the only way. But that apart :-)
I plead for NULL
being something else than 0.
And the macro mechanism of using things like
'#define' is so outdated!
Instead of filling a variable with a null pointer one
can unset() a variable in PHP.I have no problems with integers and strings being
promoted to booleans, except for example that an
empty string is considered to be false and even
(in some versions?) a string containing '0' or even
'false' or even 'NULL'?I like to write:
while (fgets($hf)) {
}But this fails when an empty string is considered to be
false. BTW. the behaviour also depends on the fact if
"\r\n" is considered to be empty or not.Yes you definitively come from C.
(...)
PHP is also based on C, so what is your point?
I think that all modern C-like languages should
as much as possible be alike, because a lot of
programmers will want to or even have to be able
to write in several languages.
It's not easy to remember all of these details and
especially slight differences about languages like
C, C++, Javascript, Java and PHP.
However, things progress and since PHP is now in
the forefront of developments, I think, it should
try to use the best solution to these problems or
at least openly discuss them.
I mis that a lot on this mailing list. Crucial
decisions seem to be made by a few implementers
and solutions are borrowed from other languages
seemingly at random.
Example, who ever came up with:
foreach ($A as $d)
instead of:
foreach ($d in $A)
(or why not allow both?)
BTW. Wouldn't it be a good idea to split this
mailing list in a list about the definition
of the PHP language and the implementation and
versions etc.?We had that before
The fact that it was discussed before doesn't
make the idea less valid.
I am and was on this and other PHP mailing lists
and never noticed a different mailing list to
discuss the design of PHP itself, but I'd
very much like to be on such a list, because
I could have prevented a lot of folly, like
just adding file_getcontents() and not
file_putcontents() (or whatever the exact
name of the function is).
I don't expect that all ideas are actually
implemented and I don't believe in
committee languages (like Algol and Ada) and
don't mind when say Rasmus keeps the final say
in matters (so the language stays consistent
and small), but I think we should freely
discuss ideas and not in this environment of
implementers and users. Design is very different
from implementing and use. Of course everyone
is welcome to join the design mailing list,
but on this list, about 95% is about
implementation and version issues and that
is more of a hindrence for design issues.
Thinking about design issues should look ahead
5 years or so and implementers just think about
what can be done and not what should be done
and a lot of people (users and implementers)
can only think in terms of what is and that
it should be preserved as is.
And yes, as a programmer and designer I know
that one has to consider compatibility issues
in a project like PHP, but since PHP is still
growing fast, it's much better to implement
changes sooner than later.
BTW. I also had some significant ideas for
improving C and (pre-RISC) assemblers. I posted
some of them on the 6811 mailing list but when
the 6812 came out, they clearly hadn't read them...
(I'll gladly repeat them here and once you have
read them you'll forever wonder why the old
designs were so flawed.)
As regards suggestions for C: I did have contact
with someone on the C design committee back in
the early ninetees and that was before these
things could be done via mailing lists. I'll
gladly explain my ideas, based on porting
applications between all kinds of architectures
among which porting them to a 64 bits architecture
(from Xenix on a 486 to a DEC's Alpha) and back
again to a Duron running Linux.
and theoretically there are more lists which nobody
uses anymore.
I think that is not a theoretical but a practical
problem. ;-)
And yes, I know a lot about the dynamics of
mailing lists and therefore also about dead lists
and that is why I proposed a split, which means that
an existing list like this is being split into two
lists which both have the same subscribers and
whereby people are encouraged to post on the right
list and unsubscribe from one of the lists when they
are not longer interested. I'd unsubscribe from the
implementation and version part of list. Personally
I always wait until there is a stable new PHP version
and compile that and my system (when my latest
upgrade of Mandrake didn't unstall a new enough
PHP version).
And then i think it is a very good idea that the developers
get feedback.
Of course, but I don't think that the developers (read
implementers) should also be the designers, or should
decide about the design issues. Of course they can
involve themselves in the design issues if they like,
but there is a much lower than 100% overlap in skills.
I have been a for-pay programmer and although I have
studied industrial design for a few years before
graduating in computer science, I had no problem with
the fact that someone else designed a product and I
only had to write the code (although I usually had
to fill in a lot of design details... ;-)
There is a lot of noise but still a fair amount of really
good mails here that help direct the way PHP evolves.
As far as I can tell, more than about 95% is noise as
regards to pure design of PHP and I can't read it all
to see if there is anything relevant to the direction
of PHP.
In fact I got involved with this discussion when I
was considering unsubscribing from this mailing list.
Not promoting types would mean adding false++, and true-- doesn't it?
false is a constant and can't be increment.
It was a shortcut for $a=false; $a++; $b=true; $b--; of course. However
the shortcut is much easier to get.
Sorry, but I am used to write for computers and they
wouldn't understand such an abstraction... ;-)
When you are in favor of incrementing booleans
you should also be able to increment a veriable
with the value true, but should it become false,
0 or 2 or stay the same?Since PHP conversion magic: true+1 => 2; false+1 => 1; 1+1 = >2
Yes, but that is when you consider current PHP laws
to be god-given, but I was discussing how it should
be (and I thought you were too).
And I think that programming languages shouldn't
have this and similar magic, but be more strict
so that programming errors are spotted earlier.
BTW, Nice commenting on the: ($p=strpos())++
Well I used to write my own C compilers, so I know
a lot about the details of C. The second K&R book
(the ANSI version) answers all questions that a
compiler writer has. C was so well defined,
unlike Pascal for example and it was so easy to
translate C source code into fast machine code.
C was clearly a great revolution in computer
languages.
But we are now witnessing another revolution in
the form of script languages and PHP is in my
view at the very forefront (and yes, I have
studied Perl, Python and Ruby) and would very
much like to help iron out problems with PHP
before they are implemented and reverse earlier
mistakes (can we ever get rid of that damned '$'? ;-)
BTW. In university (here in the Netherlands) I
followed an optional course by professor Lambert
Meertens about the language ABC that later
inspired Guido van Rossum to design Python...
Greetings,
Jaap