FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » Imported messages » comp.lang.php » switch with case 0
Show: Today's Messages :: Polls :: Message Navigator
Switch to threaded view of this topic Create a new topic Submit Reply
switch with case 0 [message #182589] Sat, 17 August 2013 04:55 Go to next message
Fiver is currently offline  Fiver
Messages: 35
Registered: July 2013
Karma: 0
Member
This example

switch ("foo") {
case 0:
echo "'foo' is 0\n";
break;
default:
echo "'foo' is not 0\n";
}

will print: 'foo' is 0.

I know how to avoid the problem, I'm just wondering what kind of
comparison is used that makes "foo" equal to 0? The manual mentions
"loose comparison", but this is even looser than usual.

By the way, the original code was meant to validate SORT_* arguments.
It's a little harder to spot here:

switch ($mode) {
case SORT_ASC:
case SORT_DESC:
case SORT_REGULAR:
case SORT_NUMERIC:
case SORT_STRING:
case SORT_LOCALE_STRING:
case SORT_NATURAL:
case SORT_FLAG_CASE:
break;
default:
throw new \InvalidArgumentException("invalid sort mode: $mode");
}

SORT_REGULAR is 0, so if the input is a string, this will break (literally).


regards,
5er
Re: switch with case 0 [message #182590 is a reply to message #182589] Sat, 17 August 2013 06:35 Go to previous messageGo to next message
J.O. Aho is currently offline  J.O. Aho
Messages: 194
Registered: September 2010
Karma: 0
Senior Member
On 17/08/13 06:55, Fiver wrote:
> This example
>
> switch ("foo") {
> case 0:
> echo "'foo' is 0\n";
> break;
> default:
> echo "'foo' is not 0\n";
> }
>
> will print: 'foo' is 0.

The switch you are doing is equal to a

if("foo" == 0) {}

PHP will make a type casting and try to make the "foo" to a integer, as
it's not a string only of numeric characters and those it will be cast
to a 0 which makes your statement true.


You can try this one:

switch("123") {
case 0:
echo "it's 0\n";
break;

case 123:
echo "it's 123\n";
break;

default:
echo "it's NOT 0 nor 123\n";
}


> I know how to avoid the problem, I'm just wondering what kind of
> comparison is used that makes "foo" equal to 0? The manual mentions
> "loose comparison", but this is even looser than usual.

No it's not looser than normally, PHP don't care so much about data
types so it internally casts it just to make it easy for those who ain't
so good at programming.


> By the way, the original code was meant to validate SORT_* arguments.
> It's a little harder to spot here:
>
> switch ($mode) {
> case SORT_ASC:
> case SORT_DESC:
> case SORT_REGULAR:
> case SORT_NUMERIC:
> case SORT_STRING:
> case SORT_LOCALE_STRING:
> case SORT_NATURAL:
> case SORT_FLAG_CASE:
> break;
> default:
> throw new \InvalidArgumentException("invalid sort mode: $mode");
> }
>
> SORT_REGULAR is 0, so if the input is a string, this will break (literally).

Sounds like you are trusting user input, always validate the user input
to be a valid value of the type you are requiring. In this case
is_numeric() could save you from trouble.

--

//Aho
Re: switch with case 0 [message #182591 is a reply to message #182590] Sat, 17 August 2013 07:29 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
On 17/08/13 07:35, J.O. Aho wrote:
> On 17/08/13 06:55, Fiver wrote:
>
>
>> I know how to avoid the problem, I'm just wondering what kind of
>> comparison is used that makes "foo" equal to 0? The manual mentions
>> "loose comparison", but this is even looser than usual.
>
> No it's not looser than normally, PHP don't care so much about data
> types so it internally casts it just to make it easy for those who
> ain't so good at programming.
>
>

and bloody nigh impossible for those who are..



--
Ineptocracy

(in-ep-toc’-ra-cy) – a system of government where the least capable to lead are elected by the least capable of producing, and where the members of society least likely to sustain themselves or succeed, are rewarded with goods and services paid for by the confiscated wealth of a diminishing number of producers.
Re: switch with case 0 [message #182592 is a reply to message #182590] Sat, 17 August 2013 07:51 Go to previous messageGo to next message
Luuk is currently offline  Luuk
Messages: 329
Registered: September 2010
Karma: 0
Senior Member
On 17-08-2013 08:35, J.O. Aho wrote:
> You can try this one:
>
> switch("123") {
> case 0:
> echo "it's 0\n";
> break;
>
> case 123:
> echo "it's 123\n";
> break;
>
> default:
> echo "it's NOT 0 nor 123\n";
> }

or:

You can try this one:

switch("1e3") {
case 0:
echo "it's 0\n";
break;

case 1000:
echo "it's 1000\n";
break;

default:
echo "it's NOT 0 nor 1000\n";
}
Re: switch with case 0 [message #182593 is a reply to message #182590] Sat, 17 August 2013 11:16 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
J.O. Aho schrieb:

> PHP will make a type casting and try to make the "foo" to a integer

And that's precisely what PHP shouldn't do. Cast an integer to a string?
Yes, no problem, since this can be done without loss of information. But
the other way round, especially if the string is obviously not
representing a numeric value? That's just plain stupid.

PHP should never, never, never try to parse out anything from a string
*unless* explicitly told to do so. And throw an error or return `null`
in situations like `(int) "foo"`.

> PHP don't care so much about data
> types so it internally casts it just to make it easy for those who ain't
> so good at programming.

Easy?!? No it doesn't. On the contrary. A "noob" programmer could write
a piece of code like the OPs first example (switch ("foo") ... case 0
....) and rightfully assume it "to work", because in what strange
parallel universe "foo" could possibly equal 0? Even disregarding the
fact that they are of different types. "foo" == 0? WTF?!?

>> switch ($mode) {
>> case SORT_ASC:
>> case SORT_DESC:
>> case SORT_REGULAR:
>> case SORT_NUMERIC:
>> case SORT_STRING:
>> case SORT_LOCALE_STRING:
>> case SORT_NATURAL:
>> case SORT_FLAG_CASE:
>> break;
>> default:
>> throw new \InvalidArgumentException("invalid sort mode: $mode");
>> }

> Sounds like you are trusting user input

No he isn't, as the above code clearly shows. It would work perfectly
well in any normal programming language (although, personally, I would
have used in_array() instead of switch).

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: switch with case 0 [message #182594 is a reply to message #182589] Sat, 17 August 2013 14:15 Go to previous messageGo to next message
Fiver is currently offline  Fiver
Messages: 35
Registered: July 2013
Karma: 0
Member
On 2013-08-17 06:55, Fiver wrote:
> I know how to avoid the problem, I'm just wondering what kind of
> comparison is used that makes "foo" equal to 0? The manual mentions
> "loose comparison", but this is even looser than usual.

Ah, please disregard. This is exactly how loose typing in PHP is
supposed to work (for some reason). "foo" == 0 indeed evaluates to true.
I work with a lot of different languages, often at the same time, so I
sometimes get confused by the different type coercion rules in weakly
typed languages. FWIW, in JavaScript, Python, Ruby, Bash and others this
comparison would evaluate to false; Perl issues a warning; strongly
typed languages like Java won't even compile it.

For the record, I had changed the problematic switch() to in_array()
with strict type checking before even posting the question.

thanks,
5er
Re: switch with case 0 [message #182598 is a reply to message #182593] Sat, 17 August 2013 15:56 Go to previous messageGo to next message
Peter H. Coffin is currently offline  Peter H. Coffin
Messages: 245
Registered: September 2010
Karma: 0
Senior Member
On Sat, 17 Aug 2013 13:16:32 +0200, Thomas Mlynarczyk wrote:
> J.O. Aho schrieb:
>
>> PHP will make a type casting and try to make the "foo" to a integer
>
> And that's precisely what PHP shouldn't do. Cast an integer to a string?
> Yes, no problem, since this can be done without loss of information. But
> the other way round, especially if the string is obviously not
> representing a numeric value? That's just plain stupid.
>
> PHP should never, never, never try to parse out anything from a string
> *unless* explicitly told to do so. And throw an error or return `null`
> in situations like `(int) "foo"`.

But the only way to do that that's consistent is to drop "loosely typed"
entirely, and then numeric-to-string goes away as well. And it's NOT "no
problem" either because you need to know how to represent that number.
Is it "0"? "0.0"? "0.00000"? Are big numbers like
"873425783240914325987643256732459087423598876234785624358" or
"8.73425e57"? Are we going with "-4" or "(4)"? And that's before we even
TOUCH on locale issues like whether to use thousands separators, are
they commas, dots, or spaces, and what do decimal places look like? Are
they thousands-sparated as well? Might as well throw out the one-way
implicit conversion as problematic as well, and just go with a
stronger typing.

Strong-typing introduces its own complications: Are we going to cast
implicitly between numeric types? It's easy to say "Sure, that's okay"
but we're IMMEDIATELY up against float rounding and questions of "Do we
want an explicity DECIMAL type?" and how to compare them. Is "004.50000"
comparable to "4.5000002" and are they equal or not? They're both DECIMAL
types, and differ only precision, and could have been even assigned the
same value in the same statement immediately before like

def a : decimal(8,5);
def b : decimal(8,7);

let a = b = 4.5000002; # are we even going to allow this to work, or
# should it also fail because we're trying to
# assign a value of a different scope to a
# variable. But we kind of have to allow math
# with un-predetermined outcomes to be assigned
# to variables, unless we want to explicitly type
# every single term we're going to use...
if (a == b); then
print "equal\n";
else
print "inequal\n";
fi

And then you've got to DOCUMENT all that.

Even just thinking about it makes me 100% behind "We're a loosely-typed
language and it works how it works. If you want to know HOW it's going
to work in a particular case, don't guess, test or look at the source.
Which we make available."

--
17. When I employ people as advisors, I will occasionally listen to
their advice.
--Peter Anspach's list of things to do as an Evil Overlord
Re: switch with case 0 [message #182599 is a reply to message #182598] Sat, 17 August 2013 16:45 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
On 17/08/13 16:56, Peter H. Coffin wrote:
> Strong-typing introduces its own complications: Are we going to cast
> implicitly between numeric types?

No.
> it makes me 100% behind "We're a loosely-typed language and it works
> how it works. If you want to know HOW it's going to work in a
> particular case, don't guess, test or look at the source. Which we
> make available."
That is the problem in a nutshell. With a strongly typed language I
don't HAVE to look at the source code. Ther are no implicit rules.There
are only explicit rules and if I say:

float c;

I don't mean char c, char * c; cha** c, char c[]. int c, double c or int
*float(c) ; or anything else.
and I HOPE the compiler will tell me I am being sloppy when I return a
zero from a function that should return a pointer.

and furthermore if I say case 0: , it doesn't mean case '0' or case "0"
or case 0.0 but it can surely mean (because its defined that way) case
FALSE, and may mean case NULL. but with a few errors thrown up abut
implicit casts.





--
Ineptocracy

(in-ep-toc’-ra-cy) – a system of government where the least capable to lead are elected by the least capable of producing, and where the members of society least likely to sustain themselves or succeed, are rewarded with goods and services paid for by the confiscated wealth of a diminishing number of producers.
Re: switch with case 0 [message #182602 is a reply to message #182589] Sat, 17 August 2013 17:28 Go to previous messageGo to next message
Norman Peelman is currently offline  Norman Peelman
Messages: 126
Registered: September 2010
Karma: 0
Senior Member
On 08/17/2013 12:55 AM, Fiver wrote:
> This example
>
> switch ("foo") {
> case 0:
> echo "'foo' is 0\n";
> break;
> default:
> echo "'foo' is not 0\n";
> }
>
> will print: 'foo' is 0.
>
> I know how to avoid the problem, I'm just wondering what kind of
> comparison is used that makes "foo" equal to 0? The manual mentions
> "loose comparison", but this is even looser than usual.
>

Type juggling is done at every CASE statement, consider the following:

switch ("foo") {
case "foo":
echo "'foo' is 'foo'!\n";
//break;
case 0:
echo "'foo' is 0\n";
break;
default:
echo "'foo' is not 0\n";
}

switch ("2bar") {
case "bar":
echo "'bar' is 'bar'!\n";
//break;
case 0:
echo "'bar' is 0\n";
break;
default:
echo "'bar' is not 0\n";
}


> By the way, the original code was meant to validate SORT_* arguments.
> It's a little harder to spot here:
>
> switch ($mode) {
> case SORT_ASC:
> case SORT_DESC:
> case SORT_REGULAR:
> case SORT_NUMERIC:
> case SORT_STRING:
> case SORT_LOCALE_STRING:
> case SORT_NATURAL:
> case SORT_FLAG_CASE:
> break;
> default:
> throw new \InvalidArgumentException("invalid sort mode: $mode");
> }
>
> SORT_REGULAR is 0, so if the input is a string, this will break (literally).
>
>

No, it will just default to SORT_REGULAR if the string type juggling
results in 0.


--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: switch with case 0 [message #182606 is a reply to message #182593] Sat, 17 August 2013 17:56 Go to previous messageGo to next message
Norman Peelman is currently offline  Norman Peelman
Messages: 126
Registered: September 2010
Karma: 0
Senior Member
On 08/17/2013 07:16 AM, Thomas Mlynarczyk wrote:
> J.O. Aho schrieb:
>
>> PHP will make a type casting and try to make the "foo" to a integer
>
> And that's precisely what PHP shouldn't do. Cast an integer to a string?
> Yes, no problem, since this can be done without loss of information. But
> the other way round, especially if the string is obviously not
> representing a numeric value? That's just plain stupid.
>

That's why it says "foo" = 0. Now is "foo" really 0, no - but it sure
isn't greater than 0. PHP looks at the string in question one character
at a time and builds a number until a non-numeric character is reached
(in a nutshell):

"foo" = 0
"foo2you" = 0
"2fooyou" = 2
"250fooyou" = 250
"250.0fooyou" = 250.0

The (basic) premise is a string can only result in a number if it
starts with a number, otherwise not. If you want to know why "foo" = 0
then, it's the same as doing math with NULL. NULL <> 0 but acts like it
in computations:

2 * "2fooyou" = 4

> PHP should never, never, never try to parse out anything from a string
> *unless* explicitly told to do so. And throw an error or return `null`
> in situations like `(int) "foo"`.

An empty string "" = 0, "foo" does not lead with any *numbers* so
therefor is = 0. Saying (int) "foo" = NULL is like saying "foo" isn't there.

>
>> PHP don't care so much about data types so it internally casts it just
>> to make it easy for those who ain't so good at programming.
>
> Easy?!? No it doesn't. On the contrary. A "noob" programmer could write
> a piece of code like the OPs first example (switch ("foo") ... case 0
> ....) and rightfully assume it "to work", because in what strange
> parallel universe "foo" could possibly equal 0? Even disregarding the
> fact that they are of different types. "foo" == 0? WTF?!?
>
>>> switch ($mode) {
>>> case SORT_ASC:
>>> case SORT_DESC:
>>> case SORT_REGULAR:
>>> case SORT_NUMERIC:
>>> case SORT_STRING:
>>> case SORT_LOCALE_STRING:
>>> case SORT_NATURAL:
>>> case SORT_FLAG_CASE:
>>> break;
>>> default:
>>> throw new \InvalidArgumentException("invalid sort mode: $mode");
>>> }
>
>> Sounds like you are trusting user input
>
> No he isn't, as the above code clearly shows. It would work perfectly
> well in any normal programming language (although, personally, I would
> have used in_array() instead of switch).
>

You are assuming $mode is never a string for one. For two, type
juggling is done at the CASE statement, not the SWITCH statement.


--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: switch with case 0 [message #182607 is a reply to message #182599] Sat, 17 August 2013 17:58 Go to previous messageGo to next message
Tim Streater is currently offline  Tim Streater
Messages: 328
Registered: September 2010
Karma: 0
Senior Member
In article <kuo9bl$4h9$1(at)news(dot)albasani(dot)net>,
The Natural Philosopher <tnp(at)invalid(dot)invalid> wrote:

> On 17/08/13 16:56, Peter H. Coffin wrote:
>> Strong-typing introduces its own complications: Are we going to cast
>> implicitly between numeric types?
>
> No.
>> it makes me 100% behind "We're a loosely-typed language and it works
>> how it works. If you want to know HOW it's going to work in a
>> particular case, don't guess, test or look at the source. Which we
>> make available."
> That is the problem in a nutshell. With a strongly typed language I
> don't HAVE to look at the source code. Ther are no implicit rules.There
> are only explicit rules and if I say:
>
> float c;
>
> I don't mean char c, char * c; cha** c, char c[]. int c, double c or int
> *float(c) ; or anything else.
> and I HOPE the compiler will tell me I am being sloppy when I return a
> zero from a function that should return a pointer.
>
> and furthermore if I say case 0: , it doesn't mean case '0' or case "0"
> or case 0.0 but it can surely mean (because its defined that way) case
> FALSE, and may mean case NULL. but with a few errors thrown up abut
> implicit casts.

I'd rather not have to bother. And I like to be able to do:


$num = (some calculation here);

if ($num==0) $num = "no";

echo "There were " . $num . " widgets\n";


for example.

--
Tim

"That excessive bail ought not to be required, nor excessive fines imposed,
nor cruel and unusual punishments inflicted" -- Bill of Rights 1689
Re: switch with case 0 [message #182609 is a reply to message #182607] Sat, 17 August 2013 18:39 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
On 17/08/13 18:58, Tim Streater wrote:
> In article <kuo9bl$4h9$1(at)news(dot)albasani(dot)net>,
> The Natural Philosopher <tnp(at)invalid(dot)invalid> wrote:
>
>> On 17/08/13 16:56, Peter H. Coffin wrote:
>>> Strong-typing introduces its own complications: Are we going to cast
>>> implicitly between numeric types?
>>
>> No.
>>> it makes me 100% behind "We're a loosely-typed language and it works
>>> how it works. If you want to know HOW it's going to work in a
>>> particular case, don't guess, test or look at the source. Which we
>>> make available." That is the problem in a nutshell. With a strongly
>> typed language I
>> don't HAVE to look at the source code. Ther are no implicit rules.There
>> are only explicit rules and if I say:
>>
>> float c;
>>
>> I don't mean char c, char * c; cha** c, char c[]. int c, double c or int
>> *float(c) ; or anything else.
>> and I HOPE the compiler will tell me I am being sloppy when I return
>> a zero from a function that should return a pointer.
>>
>> and furthermore if I say case 0: , it doesn't mean case '0' or case "0"
>> or case 0.0 but it can surely mean (because its defined that way) case
>> FALSE, and may mean case NULL. but with a few errors thrown up abut
>> implicit casts.
>
> I'd rather not have to bother. And I like to be able to do:
>
>
> $num = (some calculation here);
>
> if ($num==0) $num = "no";
> echo "There were " . $num . " widgets\n";
well all you have to do is

char temp[256]; int num;
num = (some calculation here);
printf("There were %s widgets! " num? itoa(num, temp,10): "no");

Shorter than your example.




--
Ineptocracy

(in-ep-toc’-ra-cy) – a system of government where the least capable to lead are elected by the least capable of producing, and where the members of society least likely to sustain themselves or succeed, are rewarded with goods and services paid for by the confiscated wealth of a diminishing number of producers.
Re: switch with case 0 [message #182611 is a reply to message #182609] Sat, 17 August 2013 19:36 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
The Natural Philosopher schrieb:

>> $num = (some calculation here);
>>
>> if ($num==0) $num = "no";
>> echo "There were " . $num . " widgets\n";
> well all you have to do is
>
> char temp[256]; int num;
> num = (some calculation here);
> printf("There were %s widgets! " num? itoa(num, temp,10): "no");
>
> Shorter than your example.

echo "There were " . ( $num ?: "no" ) . " widgets\n";

But the real problem with this example is: if $num == 1 it should print
"was" and "widget" instead of "were" and "widgets".

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: switch with case 0 [message #182612 is a reply to message #182606] Sat, 17 August 2013 19:55 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Norman Peelman schrieb:

> That's why it says "foo" = 0. Now is "foo" really 0, no - but it sure
> isn't greater than 0.

In order to compare "foo" and 0 one would need either to convert the
number 0 to a string ("0" would be the most reasonable result) or
convert "foo" to a number (not reasonably possible). PHP, unfortunately,
chooses the unreasonable alternative.

> PHP looks at the string in question one character
> at a time and builds a number until a non-numeric character is reached

I am aware of all that. It was decided to make PHP work that way. I was
merely pointing out that I consider it a very unfortunate decision to
cast strings to numbers instead of the other way round.

>>>> switch ($mode) {
>>>> case SORT_ASC:
>>>> case SORT_DESC:
>>>> case SORT_REGULAR:
>>>> case SORT_NUMERIC:
>>>> case SORT_STRING:
>>>> case SORT_LOCALE_STRING:
>>>> case SORT_NATURAL:
>>>> case SORT_FLAG_CASE:
>>>> break;
>>>> default:
>>>> throw new \InvalidArgumentException("invalid sort mode: $mode");
>>>> }
>>
>>> Sounds like you are trusting user input
>>
>> No he isn't, as the above code clearly shows. It would work perfectly
>> well in any normal programming language (although, personally, I would
>> have used in_array() instead of switch).
>>
>
> You are assuming $mode is never a string for one.

No I'm not assuming that. If all the SORT_* constants are integers, then
only the default branch should match in that case. It doesn't in PHP,
because PHP is made to implicitly convert strings to integers.

> For two, type
> juggling is done at the CASE statement, not the SWITCH statement.

I am aware of the fact that PHP will try to convert the string into a
number (even when this would not possibly make any sense). I'm just
saying that PHP should not have been designed that way.

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: switch with case 0 [message #182613 is a reply to message #182612] Sat, 17 August 2013 20:04 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
On 17/08/13 20:55, Thomas Mlynarczyk wrote:


> I'm just saying that PHP should not have been designed that way.
>

sheesh how much time have you GOT???

was PHP ever 'designed' ? It looks to me like a guy in a basement
decided to write an interpreter for active pages, and very time there
was a choice he either did what he felt was most useful, or tossed a coin.

Nobody is forcing you to use it...

...that the way it is...
> Greetings,
> Thomas
>
>


--
Ineptocracy

(in-ep-toc’-ra-cy) – a system of government where the least capable to lead are elected by the least capable of producing, and where the members of society least likely to sustain themselves or succeed, are rewarded with goods and services paid for by the confiscated wealth of a diminishing number of producers.
Re: switch with case 0 [message #182614 is a reply to message #182598] Sat, 17 August 2013 20:14 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Peter H. Coffin schrieb:

[PHP should never implicitly parse out anything from a string]

> But the only way to do that that's consistent is to drop "loosely typed"
> entirely,

No. Why? Other (loosely typed) languages work just fine. Because instead
of implicitly casting a string to an integer, they rather cast the
integer to a string. And there's a most natural way to do that: just use
the syntax for the respective number literal in that language (if
several different ones are possible, use the shortest representation).
Thus there are no "locale issues". (For locale specific number
formatting, there are dedicated functions.)

> Strong-typing introduces its own complications: Are we going to cast
> implicitly between numeric types? It's easy to say "Sure, that's okay"
> but we're IMMEDIATELY up against float rounding and questions of "Do we
> want an explicity DECIMAL type?" and how to compare them.

If the target type is "larger" (wider range of values) and/or "more
precise" (more decimals) than the source type, there should be no
problem. The other way round, a (lossless) type conversion may not be
possible. In that case the language could either throw an exception or
still perform the conversion with some information loss if reasonably
acceptable. E.g. if you convert a float(3.14) to int, it's clear that
the decimals will have to be dropped and the result will be int(3).
Converting a float larger than PHP_INT_MAX to int could only result in
PHP_INT_MAX (what else? `null` possibly?). Both are acceptable when done
*explicitly*. But the language should not perform such lossy conversions
*implicitly*.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: switch with case 0 [message #182615 is a reply to message #182613] Sat, 17 August 2013 20:32 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
The Natural Philosopher schrieb:

> was PHP ever 'designed' ?

Indeed, it was not. It was not intended to be what it is now.

> It looks to me like a guy in a basement
> decided to write an interpreter for active pages, and very time there
> was a choice he either did what he felt was most useful, or tossed a coin.

I'm sure it was well-meant, but then, well-meant is the opposite of well
done... (or whatever the expression is).

> Nobody is forcing you to use it...

Nobody is forcing you to earn a living ;-) ... But (despite my ranting)
I actually do enjoy using PHP -- a perfect language might be too boring.

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: switch with case 0 [message #182616 is a reply to message #182613] Sat, 17 August 2013 20:37 Go to previous messageGo to next message
Fiver is currently offline  Fiver
Messages: 35
Registered: July 2013
Karma: 0
Member
On 2013-08-17 22:04, The Natural Philosopher wrote:
> On 17/08/13 20:55, Thomas Mlynarczyk wrote:
>
>> I'm just saying that PHP should not have been designed that way.
>
> sheesh how much time have you GOT???
>
> was PHP ever 'designed' ? It looks to me like a guy in a basement
> decided to write an interpreter for active pages, and very time there
> was a choice he either did what he felt was most useful, or tossed a coin.
>
> Nobody is forcing you to use it...
>
> ..that the way it is...

You're right: PHP wasn't designed, it more or less "happened". But just
because we're using an imperfect language doesn't mean we have to shut
up about its weaknesses. Converting strings to integers instead of the
other way around was an unfortunate choice. It's one of the pitfalls
that regularly get people who are more used to other loosely typed
languages (like me in this case).

If you really want to see somebody with "too much time" to complain
about PHP's idiosyncrasies, take a look at http://phpsadness.com/ .
Quite an interesting collection, too, even if not everything on the list
is new or surprising or even wrong.

regards,
5er
Re: switch with case 0 [message #182617 is a reply to message #182615] Sat, 17 August 2013 22:20 Go to previous messageGo to next message
Richard Yates is currently offline  Richard Yates
Messages: 86
Registered: September 2013
Karma: 0
Member
On Sat, 17 Aug 2013 22:32:51 +0200, Thomas Mlynarczyk
<thomas(at)mlynarczyk-webdesign(dot)de> wrote:

> The Natural Philosopher schrieb:
>
>> was PHP ever 'designed' ?
>
> Indeed, it was not. It was not intended to be what it is now.
>
>> It looks to me like a guy in a basement
>> decided to write an interpreter for active pages, and very time there
>> was a choice he either did what he felt was most useful, or tossed a coin.
>
> I'm sure it was well-meant, but then, well-meant is the opposite of well
> done... (or whatever the expression is).
>
>> Nobody is forcing you to use it...
>
> Nobody is forcing you to earn a living ;-) ... But (despite my ranting)
> I actually do enjoy using PHP -- a perfect language might be too boring.

I am reminded of the current thread in alt.usage.english about
slippage in the use of the word 'literally'. At least php doesn't
change as you move from one state or year to another.
Re: switch with case 0 [message #182618 is a reply to message #182616] Sat, 17 August 2013 23:26 Go to previous messageGo to next message
Norman Peelman is currently offline  Norman Peelman
Messages: 126
Registered: September 2010
Karma: 0
Senior Member
On 08/17/2013 04:37 PM, Fiver wrote:
> On 2013-08-17 22:04, The Natural Philosopher wrote:
>> On 17/08/13 20:55, Thomas Mlynarczyk wrote:
>>
>>> I'm just saying that PHP should not have been designed that way.
>>
>> sheesh how much time have you GOT???
>>
>> was PHP ever 'designed' ? It looks to me like a guy in a basement
>> decided to write an interpreter for active pages, and very time there
>> was a choice he either did what he felt was most useful, or tossed a coin.
>>
>> Nobody is forcing you to use it...
>>
>> ..that the way it is...
>
> You're right: PHP wasn't designed, it more or less "happened". But just
> because we're using an imperfect language doesn't mean we have to shut
> up about its weaknesses. Converting strings to integers instead of the
> other way around was an unfortunate choice. It's one of the pitfalls
> that regularly get people who are more used to other loosely typed
> languages (like me in this case).
>

The reason it has evolved this way is because you never get integers
from POST/GET data, you get strings.

> If you really want to see somebody with "too much time" to complain
> about PHP's idiosyncrasies, take a look at http://phpsadness.com/ .
> Quite an interesting collection, too, even if not everything on the list
> is new or surprising or even wrong.
>
> regards,
> 5er
>


--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: switch with case 0 [message #182619 is a reply to message #182612] Sun, 18 August 2013 00:23 Go to previous messageGo to next message
Norman Peelman is currently offline  Norman Peelman
Messages: 126
Registered: September 2010
Karma: 0
Senior Member
On 08/17/2013 03:55 PM, Thomas Mlynarczyk wrote:
> Norman Peelman schrieb:
>
>> That's why it says "foo" = 0. Now is "foo" really 0, no - but it
>> sure isn't greater than 0.
>
> In order to compare "foo" and 0 one would need either to convert the
> number 0 to a string ("0" would be the most reasonable result) or
> convert "foo" to a number (not reasonably possible). PHP, unfortunately,
> chooses the unreasonable alternative.
>

Why is it unreasonable? After all, FORM data is all strings to begin
with. PHP will type juggle "12345" to 12345 just fine. The whole idea
behind this after all is not about having strings like "2foo".

>> PHP looks at the string in question one character
>> at a time and builds a number until a non-numeric character is reached
>
> I am aware of all that. It was decided to make PHP work that way. I was
> merely pointing out that I consider it a very unfortunate decision to
> cast strings to numbers instead of the other way round.
>

FORM data, GET/POST data, all strings...

>>>> > switch ($mode) {
>>>> > case SORT_ASC:
>>>> > case SORT_DESC:
>>>> > case SORT_REGULAR:
>>>> > case SORT_NUMERIC:
>>>> > case SORT_STRING:
>>>> > case SORT_LOCALE_STRING:
>>>> > case SORT_NATURAL:
>>>> > case SORT_FLAG_CASE:
>>>> > break;
>>>> > default:
>>>> > throw new \InvalidArgumentException("invalid sort mode:
>>>> > $mode");
>>>> > }
>>>
>>>> Sounds like you are trusting user input
>>>
>>> No he isn't, as the above code clearly shows. It would work perfectly
>>> well in any normal programming language (although, personally, I would
>>> have used in_array() instead of switch).
>>>
>>
>> You are assuming $mode is never a string for one.
>
> No I'm not assuming that. If all the SORT_* constants are integers, then
> only the default branch should match in that case. It doesn't in PHP,
> because PHP is made to implicitly convert strings to integers.
>

No, the only time the default is reached is when $mode is outside 0-7
(I say that because i only have 6 of the 8, I haven't updated yet.) If
$mode = E_ERROR it still validates. This code does nothing to ensure
$mode is what it is supposed to be.

What about:
-- code --
$mode = setSortMode("SORT_NUMERIC");
echo $mode."\n";

function setSortMode($mode)
{
switch ($mode)
{
case "SORT_ASC":
case "SORT_DESC":
case "SORT_REGULAR":
case "SORT_NUMERIC":
case "SORT_STRING":
case "SORT_LOCALE_STRING":
case "SORT_NATURAL":
case "SORT_FLAG_CASE":
return constant($mode);
break;
default:
return SORT_REGULAR;
}
}
-- code --

Technically speaking, the user should not be able to *choose* an
invalid mode but if they somehow did, I believe it should default to
some normal behavior (even if the result isn't what they wanted.) In
other words, default to SORT_REGULAR (pick your poison) until another
*valid* option is chosen.

>> For two, type juggling is done at the CASE statement, not the SWITCH
>> statement.
>
> I am aware of the fact that PHP will try to convert the string into a
> number (even when this would not possibly make any sense).

How do you know when it wouldn't make sense?

> I'm just saying that PHP should not have been designed that way.
>

FORMS, GET/POST data = strings...

> Greetings,
> Thomas
>
>


--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: switch with case 0 [message #182620 is a reply to message #182616] Sun, 18 August 2013 11:54 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
On 17/08/13 21:37, Fiver wrote:
> On 2013-08-17 22:04, The Natural Philosopher wrote:
>> On 17/08/13 20:55, Thomas Mlynarczyk wrote:
>>
>>> I'm just saying that PHP should not have been designed that way.
>> sheesh how much time have you GOT???
>>
>> was PHP ever 'designed' ? It looks to me like a guy in a basement
>> decided to write an interpreter for active pages, and very time there
>> was a choice he either did what he felt was most useful, or tossed a coin.
>>
>> Nobody is forcing you to use it...
>>
>> ..that the way it is...
> You're right: PHP wasn't designed, it more or less "happened". But just
> because we're using an imperfect language doesn't mean we have to shut
> up about its weaknesses.

OTOH fixing those weaknesses would probably break every single legacy
app out there.

Look at the utter and total MESS that HTML got into with style sheets,
and completely different models in IE versus rest of the world.

you would probably have to do similar..so
<php5

would say ''do this the old buggy way'
and
<php6

or whatever would be 'go to new standard' mode.
but what happens to include files? Aeegghh!!




> Converting strings to integers instead of the
> other way around was an unfortunate choice. It's one of the pitfalls
> that regularly get people who are more used to other loosely typed
> languages (like me in this case).
>
> If you really want to see somebody with "too much time" to complain
> about PHP's idiosyncrasies, take a look at http://phpsadness.com/ .
> Quite an interesting collection, too, even if not everything on the list
> is new or surprising or even wrong.
well yes.

There were similar religious wars between Intel and Motorola chipsets
when we all coded in assembler. People complaining that intels registers
were quirky and not orthogonal, and all were used in slightly different
ways,. whilst other people claimed that was what made them so useful.

In the end you just learnt what they did, and got on with the job of
writing solid software for them, avoiding all the grey areas completely.



> regards,
> 5er


--
Ineptocracy

(in-ep-toc’-ra-cy) – a system of government where the least capable to lead are elected by the least capable of producing, and where the members of society least likely to sustain themselves or succeed, are rewarded with goods and services paid for by the confiscated wealth of a diminishing number of producers.
Re: switch with case 0 [message #182621 is a reply to message #182619] Sun, 18 August 2013 13:22 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Norman Peelman schrieb:

> Why is it unreasonable? After all, FORM data is all strings to begin
> with. PHP will type juggle "12345" to 12345 just fine. The whole idea
> behind this after all is not about having strings like "2foo".

GET/POST data arrive as strings, yes. So the first thing one does in a
PHP script is to validate that data and convert it *explicitly* to the
correct type. One does not "leave" it as string and expect PHP to
convert it *implicitly* later on, because one may well have cases where
there is a string like "42" or "2foo" which is supposed to remain a
string and be treated as a string and not as a number.

> FORM data, GET/POST data, all strings...

I heard you the first time.

>>>> >> switch ($mode) {
>>>> >> case SORT_ASC:
>>>> >> case SORT_DESC:
>>>> >> case SORT_REGULAR:
>>>> >> case SORT_NUMERIC:
>>>> >> case SORT_STRING:
>>>> >> case SORT_LOCALE_STRING:
>>>> >> case SORT_NATURAL:
>>>> >> case SORT_FLAG_CASE:
>>>> >> break;
>>>> >> default:
>>>> >> throw new \InvalidArgumentException("invalid sort mode:
>>>> >> $mode");
>>>> >> }
>>>>

>> No I'm not assuming that. If all the SORT_* constants are integers, then
>> only the default branch should match in that case. It doesn't in PHP,
>> because PHP is made to implicitly convert strings to integers.
>
> No, the only time the default is reached is when $mode is outside 0-7

I wrote "in that case" referring to $mode = "foo".

> (I say that because i only have 6 of the 8, I haven't updated yet.) If
> $mode = E_ERROR it still validates. This code does nothing to ensure
> $mode is what it is supposed to be.

Yes, different constants could have the same value and there is no way
for PHP to tell which one was "used" to pass the value. So you could
pass E_ERROR instead of SORT_FOO if both happen to have the same value.
It would be nice, though, to be able to detect that.

>
> What about:
> -- code --
> $mode = setSortMode("SORT_NUMERIC");
> echo $mode."\n";

That would be a workaround to achieve the above. But I find it not very
elegant to use a string in this case.

> Technically speaking, the user should not be able to *choose* an
> invalid mode but if they somehow did, I believe it should default to
> some normal behavior (even if the result isn't what they wanted.) In
> other words, default to SORT_REGULAR (pick your poison) until another
> *valid* option is chosen.

Or the code should throw an exception if an invalid argument is passed.
(After all, it's the programmer's job to ensure no invalid arguments are
passed to any function, so if it happens, it's the programmer's fault
and must be fixed.)

>> I am aware of the fact that PHP will try to convert the string into a
>> number (even when this would not possibly make any sense).
>
> How do you know when it wouldn't make sense?

Trying to convert "foo" to a number doesn't make sense. It only makes
sense when the string contains the representation of a number. That
said, if there happened to be a defined constant foo = 42, then (int)
"foo" could reasonably result in int(42). But in any case, a conversion
from string to number should never happen implicitly -- only explicitly.

> FORMS, GET/POST data = strings...

I heard you the first time.

But just to be clear, let me repeat myself once more: *explicit*
conversion from string to number is okay as long as it returns `null`
(or some other appropriate indication) in case of the string not
representing a valid number. *Implicit* conversion from string to number
is bad. Whenever there's a string and a number and PHP is supposed to do
something with them (like comparing via `<=`), it should convert the
number to a string and not the other way round.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: switch with case 0 [message #182622 is a reply to message #182621] Sun, 18 August 2013 15:20 Go to previous messageGo to next message
Norman Peelman is currently offline  Norman Peelman
Messages: 126
Registered: September 2010
Karma: 0
Senior Member
On 08/18/2013 09:22 AM, Thomas Mlynarczyk wrote:
> Norman Peelman schrieb:
>
>> Why is it unreasonable? After all, FORM data is all strings to begin
>> with. PHP will type juggle "12345" to 12345 just fine. The whole idea
>> behind this after all is not about having strings like "2foo".
>
> GET/POST data arrive as strings, yes. So the first thing one does in a
> PHP script is to validate that data and convert it *explicitly* to the

PHP started *before* the big validation era...

> correct type. One does not "leave" it as string and expect PHP to
> convert it *implicitly* later on, because one may well have cases where
> there is a string like "42" or "2foo" which is supposed to remain a
> string and be treated as a string and not as a number.
>

PHP doesn't just randomly decide to type juggle, it does so in
context. If you want a string "42", you have it. PHP won't do anything
to it until you try to do some math with it (or explicitly ask it to do so.)

>> FORM data, GET/POST data, all strings...
>
> I heard you the first time.
>
>>>> >>> switch ($mode) {
>>>> >>> case SORT_ASC:
>>>> >>> case SORT_DESC:
>>>> >>> case SORT_REGULAR:
>>>> >>> case SORT_NUMERIC:
>>>> >>> case SORT_STRING:
>>>> >>> case SORT_LOCALE_STRING:
>>>> >>> case SORT_NATURAL:
>>>> >>> case SORT_FLAG_CASE:
>>>> >>> break;
>>>> >>> default:
>>>> >>> throw new \InvalidArgumentException("invalid sort mode:
>>>> >>> $mode");
>>>> >>> }
>>>> >
>
>>> No I'm not assuming that. If all the SORT_* constants are integers, then
>>> only the default branch should match in that case. It doesn't in PHP,
>>> because PHP is made to implicitly convert strings to integers.
>>
>> No, the only time the default is reached is when $mode is outside 0-7
>
> I wrote "in that case" referring to $mode = "foo".
>
>> (I say that because i only have 6 of the 8, I haven't updated yet.) If
>> $mode = E_ERROR it still validates. This code does nothing to ensure
>> $mode is what it is supposed to be.
>
> Yes, different constants could have the same value and there is no way
> for PHP to tell which one was "used" to pass the value. So you could
> pass E_ERROR instead of SORT_FOO if both happen to have the same value.
> It would be nice, though, to be able to detect that.
>
>>
>> What about:
>> -- code --
>> $mode = setSortMode("SORT_NUMERIC");
>> echo $mode."\n";
>
> That would be a workaround to achieve the above. But I find it not very
> elegant to use a string in this case.
>
>> Technically speaking, the user should not be able to *choose* an
>> invalid mode but if they somehow did, I believe it should default to
>> some normal behavior (even if the result isn't what they wanted.) In
>> other words, default to SORT_REGULAR (pick your poison) until another
>> *valid* option is chosen.
>
> Or the code should throw an exception if an invalid argument is passed.
> (After all, it's the programmer's job to ensure no invalid arguments are
> passed to any function, so if it happens, it's the programmer's fault
> and must be fixed.)
>
>>> I am aware of the fact that PHP will try to convert the string into a
>>> number (even when this would not possibly make any sense).
>>
>> How do you know when it wouldn't make sense?
>
> Trying to convert "foo" to a number doesn't make sense. It only makes
> sense when the string contains the representation of a number.

Thomas, methinks you've decided to be dense... PHP has to *look* at
the string to determine that.

> That said, if there happened to be a defined constant foo = 42, then (int)
> "foo" could reasonably result in int(42). But in any case, a conversion


There is no constant "foo". If created, it would be foo. So, no
(int)"foo" should not result in a constant foo value. constant("foo")
does that just fine.

> from string to number should never happen implicitly -- only explicitly.
>

PHP type juggles when you ask it to do so (right/wrong/mistake). If
it did it implicitly then it would happen before you ever got to the data.

>> FORMS, GET/POST data = strings...
>
> I heard you the first time.
>
> But just to be clear, let me repeat myself once more: *explicit*
> conversion from string to number is okay as long as it returns `null`

"foo" + 2 = 2
NULL + 2 = 2

> (or some other appropriate indication) in case of the string not
> representing a valid number. *Implicit* conversion from string to number
> is bad. Whenever there's a string and a number and PHP is supposed to do
> something with them (like comparing via `<=`), it should convert the
> number to a string and not the other way round.
>
> Greetings,
> Thomas
>


--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: switch with case 0 [message #182623 is a reply to message #182622] Sun, 18 August 2013 16:28 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Norman Peelman schrieb:

> PHP started *before* the big validation era...

This may be true, but does that mean we should not validate in PHP? ;-)

> PHP doesn't just randomly decide to type juggle, it does so in
> context. If you want a string "42", you have it. PHP won't do anything
> to it until you try to do some math with it (or explicitly ask it to do
> so.)

Well, unfortunately, <, <=, >, >= and switch give you no possibility to
prevent unwanted string->int casts. For equality checks, you can use ===
and !==, but there are no corresponding operators for <, > etc. And
that's the problem.

>> Trying to convert "foo" to a number doesn't make sense. It only makes
>> sense when the string contains the representation of a number.
>
> Thomas, methinks you've decided to be dense... PHP has to *look* at
> the string to determine that.

Methinks differently, but... Of course, PHP has to look. Just looking is
okay. Messing up is not. But if PHP never tried to look at the string by
itself -- only when being told to -- things would be much better.

>> That said, if there happened to be a defined constant foo = 42, then
>> (int)
>> "foo" could reasonably result in int(42). But in any case, a conversion

> There is no constant "foo". If created, it would be foo. So, no
> (int)"foo" should not result in a constant foo value. constant("foo")
> does that just fine.

Oh come on, my English is certainly not perfect, but please -- just a
little effort trying to understand what I say...? Again:

Suppose you have a string "foo" and your task is to convert it to an
integer. Normally, you'd think there's no reasonable way to do that. But
if there happened to be a constant foo = 42 defined, it would seem
reasonable to assume that the string "foo" might refer to that constant
and therefore convert "foo" to 42. No, I'm not talking about what PHP
*is* currently doing in such a situation, I'm talking about how a
computer language should be designed to behave in such a situation.

> PHP type juggles when you ask it to do so (right/wrong/mistake). If it
> did it implicitly then it would happen before you ever got to the data.

With "foo" < 42, PHP will convert "foo" to 0 and then "do" 0 < 42.
That's what I call implicit conversion and please correct me if my usage
of that word happens to be wrong. Explicit would be (int) "foo" < 42.

> "foo" + 2 = 2
> NULL + 2 = 2

It boils down to this: "foo" + 2 doesn't mean anything. In order to mean
something, both operands must be of the same type. So, either

"foo" + (string) 2 = "foo" + "2" = "foo2"

as other languages would handle this, or

(int) "foo" + 2 = ??? + 2 = ???

or throw an exception to complain about incompatible operands.

If (int) $somevar yields 0 with $somevar = "foo", then I have no way of
knowing whether the 0 is the "legitimate" result of the cast or whether
it just means "couldn't cast that to a number, giving you back 0
instead". But if in case of failure `null` is returned, I can look at
the result of (int) $somevar and if it's `null` (and not an integer) I
know the cast failed and I can react accordingly.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: switch with case 0 [message #182624 is a reply to message #182623] Sun, 18 August 2013 19:16 Go to previous messageGo to next message
Norman Peelman is currently offline  Norman Peelman
Messages: 126
Registered: September 2010
Karma: 0
Senior Member
On 08/18/2013 12:28 PM, Thomas Mlynarczyk wrote:
> Norman Peelman schrieb:
>
>> PHP started *before* the big validation era...
>
> This may be true, but does that mean we should not validate in PHP? ;-)
>

By all means no...

>> PHP doesn't just randomly decide to type juggle, it does so in
>> context. If you want a string "42", you have it. PHP won't do anything
>> to it until you try to do some math with it (or explicitly ask it to
>> do so.)
>
> Well, unfortunately, <, <=, >, >= and switch give you no possibility to
> prevent unwanted string->int casts. For equality checks, you can use ===
> and !==, but there are no corresponding operators for <, > etc. And
> that's the problem.
>

$mode = "fop";
echo (($mode === "$mode") AND ($mode <= "foo")) ? "True\n" : "False\n";

>>> Trying to convert "foo" to a number doesn't make sense. It only makes
>>> sense when the string contains the representation of a number.
>>
>> Thomas, methinks you've decided to be dense... PHP has to *look* at
>> the string to determine that.
>
> Methinks differently, but... Of course, PHP has to look. Just looking is
> okay. Messing up is not. But if PHP never tried to look at the string by
> itself -- only when being told to -- things would be much better.
>

When you are comparing things, you are asking PHP to look at them...

>>> That said, if there happened to be a defined constant foo = 42, then
>>> (int)
>>> "foo" could reasonably result in int(42). But in any case, a conversion
>
>> There is no constant "foo". If created, it would be foo. So, no
>> (int)"foo" should not result in a constant foo value. constant("foo")
>> does that just fine.
>
> Oh come on, my English is certainly not perfect, but please -- just a
> little effort trying to understand what I say...?

I don't believe I misunderstood at all... (int)"???" could end up
matching any CONSTANT by accident. Talk about getting unknown
quantities... and your English is just fine. :)

> Again:
> Suppose you have a string "foo" and your task is to convert it to an
> integer. Normally, you'd think there's no reasonable way to do that. But
> if there happened to be a constant foo = 42 defined, it would seem
> reasonable to assume that the string "foo" might refer to that constant
> and therefore convert "foo" to 42. No, I'm not talking about what PHP
> *is* currently doing in such a situation, I'm talking about how a
> computer language should be designed to behave in such a situation.
>
>> PHP type juggles when you ask it to do so (right/wrong/mistake). If
>> it did it implicitly then it would happen before you ever got to the
>> data.
>
> With "foo" < 42, PHP will convert "foo" to 0 and then "do" 0 < 42.
> That's what I call implicit conversion and please correct me if my usage
> of that word happens to be wrong. Explicit would be (int) "foo" < 42.
>
>> "foo" + 2 = 2
>> NULL + 2 = 2
>
> It boils down to this: "foo" + 2 doesn't mean anything. In order to mean
> something, both operands must be of the same type. So, either
>
> "foo" + (string) 2 = "foo" + "2" = "foo2"
>
> as other languages would handle this, or

To me that's the same problem in reverse. + is math, . is
concatination. + needs/wants numbers, . needs/wants strings. You don't
ADD strings, you JOIN/CONCATINATE them.

>
> (int) "foo" + 2 = ??? + 2 = ???
>
= 0 + 2 = 2

"foo" . 2 = "foo2"

> or throw an exception to complain about incompatible operands.
>
> If (int) $somevar yields 0 with $somevar = "foo", then I have no way of
> knowing whether the 0 is the "legitimate" result of the cast or whether
> it just means "couldn't cast that to a number, giving you back 0
> instead". But if in case of failure `null` is returned, I can look at
> the result of (int) $somevar and if it's `null` (and not an integer) I
> know the cast failed and I can react accordingly.
>

Ok Thomas, lets think this through. If a string $somevar contains a
number, you get cast that number. If the cast results in 0 because
$somevar either does not contain a number or contains "0", does it
matter? If 0 is not an acceptable result, you the programmer should more
than likely be coding for that anyway.


> Greetings,
> Thomas
>


--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: switch with case 0 [message #182625 is a reply to message #182624] Sun, 18 August 2013 22:04 Go to previous messageGo to next message
Norman Peelman is currently offline  Norman Peelman
Messages: 126
Registered: September 2010
Karma: 0
Senior Member
On 08/18/2013 03:16 PM, Norman Peelman wrote:
> On 08/18/2013 12:28 PM, Thomas Mlynarczyk wrote:
>> Norman Peelman schrieb:
>>
>>> PHP started *before* the big validation era...
>>
>> This may be true, but does that mean we should not validate in PHP? ;-)
>>
>
> By all means no...
>
>>> PHP doesn't just randomly decide to type juggle, it does so in
>>> context. If you want a string "42", you have it. PHP won't do anything
>>> to it until you try to do some math with it (or explicitly ask it to
>>> do so.)
>>
>> Well, unfortunately, <, <=, >, >= and switch give you no possibility to
>> prevent unwanted string->int casts. For equality checks, you can use ===
>> and !==, but there are no corresponding operators for <, > etc. And
>> that's the problem.
>>
>
> $mode = "fop";
> echo (($mode === "$mode") AND ($mode <= "foo")) ? "True\n" : "False\n";
>

Better I think:

((is_string($mode) AND is_string($var)) AND $mode <= $var) ? true : false

((is_int($mode) AND is_int($var)) AND $mode <= $var) ? true : false


--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: switch with case 0 [message #182626 is a reply to message #182624] Sun, 18 August 2013 22:13 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Norman Peelman schrieb:

> $mode = "fop";
> echo (($mode === "$mode") AND ($mode <= "foo")) ? "True\n" : "False\n";

False. And no surprise. This is more fun:

// Transitivity...?
var_dump( "10" < "foo", "foo" < 2, "10" < 2 );

// Foo is both greater and smaller than 1?
var_dump( "1" == 1, "foo" > "1", "foo" < 1 );

// Appending the same character on both sides...
var_dump( "xe" > "x0", "xe2" > "x02" );
// ... should not change the result
var_dump( "1e" > "10", "1e2" > "102" );

Yes there are rules that PHP follows to create all this madness and it's
all documented. But why wasn't it made as simple and intuitive as in
other languages?

> When you are comparing things, you are asking PHP to look at them...

Yes. But PHP should not turn strings into numbers before doing the
comparison. It should rather turn numbers into strings, if necessary.

> To me that's the same problem in reverse. + is math, . is
> concatination. + needs/wants numbers, . needs/wants strings. You don't
> ADD strings, you JOIN/CONCATINATE them.

Okay, + wants numbers. So "foo" + 2 is an error. Silently turning "foo"
into 0 hides this error instead of slapping it into the programmer's face.

> Ok Thomas, lets think this through. If a string $somevar contains a
> number, you get cast that number. If the cast results in 0 because
> $somevar either does not contain a number or contains "0", does it
> matter?

Yes, I think it does matter. When I'm expecting something that resembles
a number and I get something that does not resemble a number, then
clearly there's something wrong and the situation should be handled in a
special way. There may be cases, where the silent conversion to 0 is
desirable, but the default behaviour should be an error.

> If 0 is not an acceptable result, you the programmer should more
> than likely be coding for that anyway.

Yes, I (as the programmer) should make sure not to try adding "foo" + 2.
But what about my var_dump() examples above? What if I want to compare
"1e2" > "102" as strings and not as numbers (100 > 102)? I'd have to
resort to substr_compare() to achieve that. With PHP, there's usually a
way to get what you want, but it's not always the simplest and most
obvious way. And thus one must be careful with this language to avoid
all the pitfalls. Once I wrote by mistake

if ( strlen( $string <= 64 ) ) // note the misplaced `)`

and it worked like a charm -- for months. Until a had $string values
starting with numbers... Did PHP complain? No. First it did its weird
comparison and then it passed the resulting boolean to strlen() and
strlen() didn't complain, converted the boolean to string, did its
stuff, returned an integer which got converted to a boolean to evaluate
the if condition. If you ever make a mistake and want to hide it -- put
it in a PHP script, it'll be safe there ;-)

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: switch with case 0 [message #182627 is a reply to message #182625] Sun, 18 August 2013 22:17 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Norman Peelman schrieb:

> Better I think:
>
> ((is_string($mode) AND is_string($var)) AND $mode <= $var) ? true : false
>
> ((is_int($mode) AND is_int($var)) AND $mode <= $var) ? true : false

Yes, that makes it much clearer. Still... in other languages, a simple
$mode <= $var would suffice. And one must remember that it doesn't
suffice in PHP. :-(

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: switch with case 0 [message #182628 is a reply to message #182626] Sun, 18 August 2013 23:35 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
On 18/08/13 23:13, Thomas Mlynarczyk wrote:
> No. First it did its weird comparison and then it passed the
> resulting boolean to strlen() and strlen() didn't complain, converted
> the boolean to string, did its stuff, returned an integer which got
> converted to a boolean to evaluate the if condition. If you ever make
> a mistake and want to hide it -- put it in a PHP script, it'll be safe
> there ;-)
>

At least you only have ONE implementation of PHP to contend with.

When I did similar in Javascript it took me TWO BLOODY DAYS to work out
why exactly the same code worked in Firefox and not in IE6.

And it was EXACTLY the same issue. comparing what I ASSUMED were
numbers, but they got converted to strings by IE6,

But not by firefox.

It took me one and a half days to pin the thing down, and half a day to
find a construct that actually did the same thing in both browsers.

sheesh.

I even looked up the spec. It didn't cover the case. casting is
explicitly defined in ASSIGNMENTS, but not in COMPARISONS.



> Greetings,
> Thomas
>
>


--
Ineptocracy

(in-ep-toc’-ra-cy) – a system of government where the least capable to lead are elected by the least capable of producing, and where the members of society least likely to sustain themselves or succeed, are rewarded with goods and services paid for by the confiscated wealth of a diminishing number of producers.
Re: switch with case 0 [message #182629 is a reply to message #182626] Mon, 19 August 2013 02:13 Go to previous messageGo to next message
Norman Peelman is currently offline  Norman Peelman
Messages: 126
Registered: September 2010
Karma: 0
Senior Member
On 08/18/2013 06:13 PM, Thomas Mlynarczyk wrote:
> Norman Peelman schrieb:
>
>> $mode = "fop";
>> echo (($mode === "$mode") AND ($mode <= "foo")) ? "True\n" : "False\n";
>
> False. And no surprise. This is more fun:
>
> // Transitivity...?
> var_dump( "10" < "foo", "foo" < 2, "10" < 2 );

"10" < "foo" == TRUE - alphabetically numbers are lower than letters.
But "10" is shorter in length than "foo" so it is less than by default.

"foo" < 2 == TRUE - "foo" == 0 (since it isn't greater than 0). "foo" is
cast because of the integer 2.

"10" < 2 == FALSE - cast as above.

>
> // Foo is both greater and smaller than 1?
> var_dump( "1" == 1, "foo" > "1", "foo" < 1 );

"1" == 1 == TRUE - cast as above.

"foo" > "1" == TRUE - both alphabetically and length. no cast.

"foo" < 1 == TRUE - cast as above

>
> // Appending the same character on both sides...
> var_dump( "xe" > "x0", "xe2" > "x02" );

"xe" > "x0" == TRUE - alphabetically, no cast.

"xe2" > "x02" == TRUE - alphabetically, no cast.

> // ... should not change the result
> var_dump( "1e" > "10", "1e2" > "102" );

"1e" > "10" == TRUE - evaluated as strings because "1e" does not cast to
10 ("1e1" does though.)

"1e2" > "102" == FALSE - evaluated as numbers because both strings are
numerical. You have me on this one. I understand casting when at least
one side is INT/etc. but when both are strings they should be evaluated
as strings. That is implicit casting. And there is no reason for it. :)

>
> Yes there are rules that PHP follows to create all this madness and it's
> all documented. But why wasn't it made as simple and intuitive as in
> other languages?
>
>> When you are comparing things, you are asking PHP to look at them...
>
> Yes. But PHP should not turn strings into numbers before doing the
> comparison. It should rather turn numbers into strings, if necessary.
>
>> To me that's the same problem in reverse. + is math, . is
>> concatination. + needs/wants numbers, . needs/wants strings. You don't
>> ADD strings, you JOIN/CONCATINATE them.
>
> Okay, + wants numbers. So "foo" + 2 is an error. Silently turning "foo"
> into 0 hides this error instead of slapping it into the programmer's face.

We are going in circles at this point... PHP just isn't made that way
so I can't keep arguing about it. Again, I get the basic casting method
up but not including casting two strings to compare them as numbers. If
it's because functions like *strcmp()* are for strings then maybe *that*
should be handled silently:

"1e2" < "102" == strcmp("1e2","102") // dunno about that - seems clumsy

Technically speaking, there are only two STRING operators listed:

.. concatenation
..= append

....everything else is function based for strings. You've partially
changed my mind Thomas. That you have.

>
>> Ok Thomas, lets think this through. If a string $somevar contains a
>> number, you get cast that number. If the cast results in 0 because
>> $somevar either does not contain a number or contains "0", does it
>> matter?
>
> Yes, I think it does matter. When I'm expecting something that resembles
> a number and I get something that does not resemble a number, then
> clearly there's something wrong and the situation should be handled in a
> special way. There may be cases, where the silent conversion to 0 is
> desirable, but the default behaviour should be an error.
>
>> If 0 is not an acceptable result, you the programmer should more than
>> likely be coding for that anyway.
>
> Yes, I (as the programmer) should make sure not to try adding "foo" + 2.
> But what about my var_dump() examples above? What if I want to compare
> "1e2" > "102" as strings and not as numbers (100 > 102)? I'd have to
> resort to substr_compare() to achieve that. With PHP, there's usually a
> way to get what you want, but it's not always the simplest and most
> obvious way. And thus one must be careful with this language to avoid
> all the pitfalls. Once I wrote by mistake
>
> if ( strlen( $string <= 64 ) ) // note the misplaced `)`
>
> and it worked like a charm -- for months. Until a had $string values
> starting with numbers... Did PHP complain? No. First it did its weird
> comparison and then it passed the resulting boolean to strlen() and
> strlen() didn't complain, converted the boolean to string, did its
> stuff, returned an integer which got converted to a boolean to evaluate
> the if condition. If you ever make a mistake and want to hide it -- put
> it in a PHP script, it'll be safe there ;-)
>
> Greetings,
> Thomas
>
>

I still think most of it when used properly can aid a programmer. A
big part of our discussion is actually two different things. You want
PHP to let you know up front like a compiler would. And i'm thinking
about how to use casting to my advantage. Might start a new topic about
that...

--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: switch with case 0 [message #182630 is a reply to message #182612] Mon, 19 August 2013 08:18 Go to previous messageGo to next message
Thomas 'PointedEars'  is currently offline  Thomas 'PointedEars'
Messages: 701
Registered: October 2010
Karma: 0
Senior Member
Thomas Mlynarczyk wrote:

> Norman Peelman schrieb:
>> That's why it says "foo" = 0. Now is "foo" really 0, no - but it sure
>> isn't greater than 0.
>
> In order to compare "foo" and 0 one would need either to convert the
> number 0 to a string ("0" would be the most reasonable result) or
> convert "foo" to a number (not reasonably possible). PHP, unfortunately,
> chooses the unreasonable alternative.

When you consider the possibility that a request parameter may or may not be
present, and you wanted an easy way to check this, like

if ($param)
{
// …
}

it does not look that unreasonable anymore.

The argument can be made that "0" is something, while "" is nothing. I
cannot find it reasonable by any measure that "foo" should be equal to 0.
"foo" certainly is something, while at the same time the argument can be
made that 0 is a mathematical “nothing” (the neutral element towards
addition).

But PHP, after all, also allows for strict comparison to avoid this problem.
Why do you not use it, and then complain about the language (with dubious
assertions about it, BTW)?

if ($param && $param !== "0")
{
// …
}

>> PHP looks at the string in question one character
>> at a time and builds a number until a non-numeric character is reached
>
> I am aware of all that. It was decided to make PHP work that way. I was
> merely pointing out that I consider it a very unfortunate decision to
> cast strings to numbers instead of the other way round.

I think it is the natural result of PHP being the *P*HP *H*ypertext
*P*reprocessor.

BTW, because of discussions like this one, switch-case has been either
removed in an early version from or is never going to be introduced into
Python, another programming language that uses dynamic type-checking (we
should lose the term “loose typing”, it is too loose to be useful). You
have to write

if foo == 1:
pass
elif foo == 2:
pass
elif foo == 3:
pass
else:
pass

and that is precisely what you should do in PHP if the type matters:

if ($foo === 1)
{
// …
}
else if ($foo === 2)
{
// …
}
else if ($foo === 3)
{
// …
}
else
{
/* default */
}


PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
Re: switch with case 0 [message #182631 is a reply to message #182628] Mon, 19 August 2013 10:30 Go to previous messageGo to next message
Norman Peelman is currently offline  Norman Peelman
Messages: 126
Registered: September 2010
Karma: 0
Senior Member
On 08/18/2013 07:35 PM, The Natural Philosopher wrote:
> On 18/08/13 23:13, Thomas Mlynarczyk wrote:
>> No. First it did its weird comparison and then it passed the
>> resulting boolean to strlen() and strlen() didn't complain, converted
>> the boolean to string, did its stuff, returned an integer which got
>> converted to a boolean to evaluate the if condition. If you ever make
>> a mistake and want to hide it -- put it in a PHP script, it'll be safe
>> there ;-)
>>
>
> At least you only have ONE implementation of PHP to contend with.
>
> When I did similar in Javascript it took me TWO BLOODY DAYS to work out
> why exactly the same code worked in Firefox and not in IE6.
>
> And it was EXACTLY the same issue. comparing what I ASSUMED were
> numbers, but they got converted to strings by IE6,
>
> But not by firefox.
>
> It took me one and a half days to pin the thing down, and half a day to
> find a construct that actually did the same thing in both browsers.
>
> sheesh.
>
> I even looked up the spec. It didn't cover the case. casting is
> explicitly defined in ASSIGNMENTS, but not in COMPARISONS.
>
>

That's part of the problem (that I just recently realized)... there
are no STRING *comparators* in PHP, just STRING *functions*.

--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: switch with case 0 [message #182632 is a reply to message #182630] Mon, 19 August 2013 17:39 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Thomas 'PointedEars' Lahn schrieb:

> But PHP, after all, also allows for strict comparison to avoid this problem.

True, there are === and !==. Unfortunately, though, there are no
"strict" equivalents for <, <=, > and >=. That would be nice to have.

> BTW, because of discussions like this one, switch-case has been either
> removed in an early version from or is never going to be introduced into
> Python,

I think the original reason for switch was to evaluate the expression
only once and use the result as an offset in a "jump table". And
actually, the Pythonic equivalent of switch is not an if-elif-else
structure, but a dict of functions.

> and that is precisely what you should do in PHP if the type matters:
>
> if ($foo === 1)
> {
> // …
> }
> else if ($foo === 2)
> {
> // …
> }
> else if ($foo === 3)
> {
> // …
> }
> else
> {
> /* default */
> }

Indeed, you're right.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: switch with case 0 [message #182633 is a reply to message #182629] Mon, 19 August 2013 17:55 Go to previous message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Norman Peelman schrieb:

> We are going in circles at this point... PHP just isn't made that way
> so I can't keep arguing about it.

Indeed. If I want PHP to change, I should file a feature request. But
even if everyone else agreed with me, my request would be rejected
"because it would break backwards compatibility". (An issue that might
be solvable by introducing a "strict" mode in PHP.)

> Technically speaking, there are only two STRING operators listed:
>
> . concatenation
> .= append
>
> ...everything else is function based for strings.

So, actually, operators like < or >= are not really meant for string
comparisons. Neither is switch. And with that in mind, things start to
look a bit clearer.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: AND and OR
Next Topic: Compiling PHP 5.x on Cygwin
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Sat Nov 30 15:05:07 GMT 2024

Total time taken to generate the page: 0.02645 seconds