Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.php > #10542 > unrolled thread

switch with case 0

Started byFiver <numeralfive@gmail.com>
First post2013-08-17 06:55 +0200
Last post2013-08-17 13:28 -0400
Articles 15 on this page of 35 — 10 participants

Back to article view | Back to comp.lang.php


Contents

  switch with case 0 Fiver <numeralfive@gmail.com> - 2013-08-17 06:55 +0200
    Re: switch with case 0 "J.O. Aho" <user@example.net> - 2013-08-17 08:35 +0200
      Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-17 08:29 +0100
      Re: switch with case 0 Luuk <luuk@invalid.lan> - 2013-08-17 09:51 +0200
      Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-17 13:16 +0200
        Re: switch with case 0 "Peter H. Coffin" <hellsop@ninehells.com> - 2013-08-17 10:56 -0500
          Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-17 17:45 +0100
            Re: switch with case 0 Tim Streater <timstreater@greenbee.net> - 2013-08-17 18:58 +0100
              Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-17 19:39 +0100
                Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-17 21:36 +0200
          Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-17 22:14 +0200
        Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-17 13:56 -0400
          Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-17 21:55 +0200
            Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-17 21:04 +0100
              Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-17 22:32 +0200
                Re: switch with case 0 Richard Yates <richard@yatesguitar.com> - 2013-08-17 15:20 -0700
              Re: switch with case 0 Fiver <numeralfive@gmail.com> - 2013-08-17 22:37 +0200
                Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-17 19:26 -0400
                Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-18 12:54 +0100
            Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-17 20:23 -0400
              Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-18 15:22 +0200
                Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-18 11:20 -0400
                  Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-18 18:28 +0200
                    Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-18 15:16 -0400
                      Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-18 18:04 -0400
                        Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-19 00:17 +0200
                      Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-19 00:13 +0200
                        Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-19 00:35 +0100
                          Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-19 06:30 -0400
                        Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-18 22:13 -0400
                          Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-19 19:55 +0200
            Re: switch with case 0 Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-08-19 10:18 +0200
              Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-19 19:39 +0200
    Re: switch with case 0 Fiver <numeralfive@gmail.com> - 2013-08-17 16:15 +0200
    Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-17 13:28 -0400

Page 2 of 2 — ← Prev page 1 [2]


#10574

FromThomas Mlynarczyk <thomas@mlynarczyk-webdesign.de>
Date2013-08-18 15:22 +0200
Message-ID<kuqhr8$csc$1@news.albasani.net>
In reply to#10572
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)

[toc] | [prev] | [next] | [standalone]


#10575

FromNorman Peelman <npeelman@cfl.rr.com>
Date2013-08-18 11:20 -0400
Message-ID<kuqool$m0p$1@dont-email.me>
In reply to#10574
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?-

[toc] | [prev] | [next] | [standalone]


#10576

FromThomas Mlynarczyk <thomas@mlynarczyk-webdesign.de>
Date2013-08-18 18:28 +0200
Message-ID<kuqsnr$3gu$1@news.albasani.net>
In reply to#10575
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)

[toc] | [prev] | [next] | [standalone]


#10577

FromNorman Peelman <npeelman@cfl.rr.com>
Date2013-08-18 15:16 -0400
Message-ID<kur6jc$4om$1@dont-email.me>
In reply to#10576
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?-

[toc] | [prev] | [next] | [standalone]


#10578

FromNorman Peelman <npeelman@cfl.rr.com>
Date2013-08-18 18:04 -0400
Message-ID<kurgec$4nd$1@dont-email.me>
In reply to#10577
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?-

[toc] | [prev] | [next] | [standalone]


#10580

FromThomas Mlynarczyk <thomas@mlynarczyk-webdesign.de>
Date2013-08-19 00:17 +0200
Message-ID<kurh5q$djk$2@news.albasani.net>
In reply to#10578
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)

[toc] | [prev] | [next] | [standalone]


#10579

FromThomas Mlynarczyk <thomas@mlynarczyk-webdesign.de>
Date2013-08-19 00:13 +0200
Message-ID<kurguq$djk$1@news.albasani.net>
In reply to#10577
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)

[toc] | [prev] | [next] | [standalone]


#10581

FromThe Natural Philosopher <tnp@invalid.invalid>
Date2013-08-19 00:35 +0100
Message-ID<kurlnh$lkl$1@news.albasani.net>
In reply to#10579
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.

[toc] | [prev] | [next] | [standalone]


#10584

FromNorman Peelman <npeelman@cfl.rr.com>
Date2013-08-19 06:30 -0400
Message-ID<kuss3n$ofd$1@dont-email.me>
In reply to#10581
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?-

[toc] | [prev] | [next] | [standalone]


#10582

FromNorman Peelman <npeelman@cfl.rr.com>
Date2013-08-18 22:13 -0400
Message-ID<kurv04$1sk$1@dont-email.me>
In reply to#10579
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?-

[toc] | [prev] | [next] | [standalone]


#10586

FromThomas Mlynarczyk <thomas@mlynarczyk-webdesign.de>
Date2013-08-19 19:55 +0200
Message-ID<kutm6f$hrn$1@news.albasani.net>
In reply to#10582
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)

[toc] | [prev] | [next] | [standalone]


#10583

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-08-19 10:18 +0200
Message-ID<31310115.f6C6Xg6MER@PointedEars.de>
In reply to#10565
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

[toc] | [prev] | [next] | [standalone]


#10585

FromThomas Mlynarczyk <thomas@mlynarczyk-webdesign.de>
Date2013-08-19 19:39 +0200
Message-ID<kutl82$fph$1@news.albasani.net>
In reply to#10583
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)

[toc] | [prev] | [next] | [standalone]


#10547

FromFiver <numeralfive@gmail.com>
Date2013-08-17 16:15 +0200
Message-ID<kuo0hn$vq0$1@dont-email.me>
In reply to#10542
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

[toc] | [prev] | [next] | [standalone]


#10555

FromNorman Peelman <npeelman@cfl.rr.com>
Date2013-08-17 13:28 -0400
Message-ID<kuobru$t9c$1@dont-email.me>
In reply to#10542
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?-

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.php


csiph-web