|
Re: Operator precedence [message #184996 is a reply to message #184990] |
Sun, 23 February 2014 14:42 |
GS
Messages: 3 Registered: February 2014
Karma: 0
|
Junior Member |
add to buddy list ignore all messages by this user
|
|
Christoph Michael Becker <cmbecker69(at)arcor(dot)de> wrote:
> I've stumbled upon the following code:
>
> !$a && $a = 42;
>
> Apparently, this is meant instead of
>
> if (!$a) $a = 42;
>
> or
>
> !$a AND $a = 42;
>
> However, I am quite confused that it works because the = operator has
> lower precendence than the && operator[1]. Actually that should mean
> the statement is equivalent to
>
> (!$a && $a) = 42;
>
> But this obviously won't work.
>
> Why does the mentioned statement has the "expected" result? Is it
> reliable to write it that way?
>
> [1] <http://www.php.net/manual/en/language.operators.precedence.php>
>
This shows one of the major problems with PHP: there is no formal language
definition, you have to go by examples in the help file to intuit what is
or is not valid. Where is the BNF definition of the language? There is none
AFAICT.
Under "Control structures" the PHP help file says "Any PHP script is built
out of a series of statements" but offers no definition of what constitutes
a statement. Under "Expressions" the manual says "Expressions are the most
important building stones of PHP. In PHP, almost anything you write is an
expression." How do we square that with the previous claim? In the end I
think you should avoid using PHP for anything critical since it is a
language defined by handwaving, where you can't formally determine the
meaning of a construct, yuo either have to try it out or find an analogous
example in the help file.
In your example, the answer to why the construction works is given in a
footnote to the section "Operator Precedence" which states
"Note: Although = has a lower precedence than most other operators, PHP
will still allow expressions similar to the following: if (!$a = foo()), in
which case the return value of foo() is put into $a. "
The formal meaning of this footnote is "BOOGA BOOGA!"
This kind of thing give me the heeby jeebies and makes me think I should be
using some other language for server side scripting (maybe perl is better
defined?)
|
|
|
|
Re: Operator precedence [message #185005 is a reply to message #184990] |
Sun, 23 February 2014 15:56 |
|
Christoph Michael Becker <cmbecker69(at)arcor(dot)de> writes:
> I've stumbled upon the following code:
>
> !$a && $a = 42;
>
> Apparently, this is meant instead of
>
> if (!$a) $a = 42;
>
> or
>
> !$a AND $a = 42;
>
> However, I am quite confused that it works because the = operator has
> lower precendence than the && operator[1]. Actually that should mean
> the statement is equivalent to
>
> (!$a && $a) = 42;
>
> But this obviously won't work.
The precedence table is wrong -- or at least something of a
simplification. The grammar for PHP (for which I had to resort to the
source code) does not reflect that table for the = operator. The
grammar has explicit rules for = that result in the precedence being
ignored in this particular case.
The precedence comes into play when the YACC (or Bison or whatever)
source says something like
exp: ...
| exp '=' exp
| ...
but instead is says:
exp: ...
| variable = exp
(this is a somewhat abbreviated explanation) so there can never be a
full expression on the left hand side. Note that this works:
$a + $a = 42;
and parses like
$a + ($a = 42);
There is nothing special about && in this respect. The precedence does
count in some situations. For example, compare
$a = true && $b = false; // $a = (true && ($b = false));
and
$a = true and $b = false; // ($a = true) and ($b = false);
> Why does the mentioned statement has the "expected" result? Is it
> reliable to write it that way?
Interesting question. I don't know where the language is defined.
Maybe one day the source code will reflect the documentation of vice
versa. Maybe one day both will match some other, external,
specification.
> [1] <http://www.php.net/manual/en/language.operators.precedence.php>
--
Ben.
|
|
|
|
Re: Operator precedence [message #185013 is a reply to message #185008] |
Sun, 23 February 2014 18:36 |
|
On 2/23/14, 4:34 PM, Jerry Stuckle wrote:
> On 2/23/2014 2:42 PM, GS wrote:
>> This shows one of the major problems with PHP: there is no formal
>> language
>> definition, you have to go by examples in the help file to intuit what is
>> or is not valid. Where is the BNF definition of the language? There is
>> none
>> AFAICT.
>>
>
> Incorrect. There is a formal definition, as indicated in the doc at
> www.php.net.
>
Do you have a pointer to where "expression" is precisely defined (other
than reading code).
A statement in the documentation says:
PHP provides a full and powerful implementation of expressions, and
documenting it entirely goes beyond the scope of this manual.
Note that this is the "Language Reference" under "Expressions", if that
isn't the right spot to formally define the term (or at least place a
pointer to the formal definition), I am not sure what would be.
This shows that PHP is not a "formally defined language".
That doesn't mean it isn't powerful, or useful, or the right tool to use
in some places, but does say that it lacks some formal rigor.
The lack of formal rigor says that there are some questions which just
can't be answered by reading the language documentation.
The original question was a good example of this. the assignment
operator is described as having a precedence (fairly low) just like all
other operators, with some vague comments that it is done in a way that
certain things just work. In comments on looking at the code, the left
operand of assignment is a variable, and not an expression, effectively
giving assignment a very high precedence to the left, and a very low
precedence to the right (if the grammar even does end up being actually
describable precisely with precedence). To my knowledge, this detail is
NOT formally presented in the documentation.
This is somewhat the result of the type of language PHP is. PHP is
inherently a "single source" language, there is one implementation, and
that ultimately is the definition of what the language is (for that
version). This is as opposed to a language like C, where there is a
formal spec for the language, and many people can write their own
implementation, and that implementation can be judged by if it fully
meets the specification or not.
I am NOT proposing the PHP should stop and go to the effort to build a
standard of the level of C and the like, it isn't used as that type of
language. It might not hurt to "back-port" some of the details of
grammar as parsed, into an appendix.
|
|
|
|
Re: Operator precedence [message #185015 is a reply to message #185014] |
Sun, 23 February 2014 23:49 |
|
Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
> On 2/23/2014 6:36 PM, Richard Damon wrote:
>> On 2/23/14, 4:34 PM, Jerry Stuckle wrote:
>>> On 2/23/2014 2:42 PM, GS wrote:
>>>> This shows one of the major problems with PHP: there is no formal
>>>> language
>>>> definition, you have to go by examples in the help file to intuit what is
>>>> or is not valid. Where is the BNF definition of the language? There is
>>>> none
>>>> AFAICT.
>>>>
>>> Incorrect. There is a formal definition, as indicated in the doc at
>>> www.php.net.
>>>
>> Do you have a pointer to where "expression" is precisely defined (other
>> than reading code).
>
> Try any Introduction to Programming book. Documentation (not just
> PHP) does not normally define commonly used terms.
I don't think it's that clear cut. Expressions are built from
operators, but is ',' an operator in PHP? It appears in the operator
precedence table but it isn't an operator in an sense that would
normally be understood by someone familiar with these terms.
<snip>
>> That doesn't mean it isn't powerful, or useful, or the right tool to use
>> in some places, but does say that it lacks some formal rigor.
>
> Once again, incorrect.
>
>> The lack of formal rigor says that there are some questions which just
>> can't be answered by reading the language documentation.
>
> It can if you have a basic understanding of programming.
Again, I don't think it's that simple. How would you determine if the
following program is permitted and, if it is, what it does?
if (false) label: else echo "else\n";
goto label;
You could try it, of course, but that's hardly very formal.
>> The original question was a good example of this. the assignment
>> operator is described as having a precedence (fairly low) just like all
>> other operators, with some vague comments that it is done in a way that
>> certain things just work. In comments on looking at the code, the left
>> operand of assignment is a variable, and not an expression, effectively
>> giving assignment a very high precedence to the left, and a very low
>> precedence to the right (if the grammar even does end up being actually
>> describable precisely with precedence). To my knowledge, this detail is
>> NOT formally presented in the documentation.
>
> No, the original question shows a basic lack of knowledge of terms
> used in programming. As does your argument.
This puzzles me. What basic knowledge would have cleared up the
original question?
The assignment operators in PHP have, in effect, different precedences
on the left and the right (a feature that some languages flaunt) but
that is not common and certainly not part of what I'd call basic
knowledge. The documentation gives one example of this peculiarity, but
that does not clear the matter up conclusively. For example, in some
languages permit assignment to the result of a conditional expression,
but I think it's hard to tell from the documentation what these two do:
$bool ? $a : $b = 42;
($bool ? $a : $b) = 42;
The operator precedence table suggests that both mean the same thing,
but they don't. I don't think the meaning of either is easily
determined from the documentation.
<snip>
--
Ben.
|
|
|
Re: Operator precedence [message #185016 is a reply to message #185015] |
Mon, 24 February 2014 06:56 |
|
Ben Bacarisse wrote:
> […] Expressions are built from operators, but is ',' an operator in PHP?
> It appears in the operator precedence table but it isn't an operator in an
> sense that would normally be understood by someone familiar with these
> terms.
ECMAScript has a “Comma Operator”, too.
<http://ecma-international.org/ecma-262/5.1/#sec-11.14>
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
|
|
|
|
|
|
|
|
Re: Operator precedence [message #185028 is a reply to message #185017] |
Mon, 24 February 2014 16:23 |
|
Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
> On 2/23/2014 11:49 PM, Ben Bacarisse wrote:
>> Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
>>
>>> On 2/23/2014 6:36 PM, Richard Damon wrote:
>>>> On 2/23/14, 4:34 PM, Jerry Stuckle wrote:
>>>> > On 2/23/2014 2:42 PM, GS wrote:
>>>> >> This shows one of the major problems with PHP: there is no formal
>>>> >> language
>>>> >> definition, you have to go by examples in the help file to intuit what is
>>>> >> or is not valid. Where is the BNF definition of the language? There is
>>>> >> none
>>>> >> AFAICT.
>>>> >>
>>>> > Incorrect. There is a formal definition, as indicated in the doc at
>>>> > www.php.net.
>>>> >
>>>> Do you have a pointer to where "expression" is precisely defined (other
>>>> than reading code).
>>>
>>> Try any Introduction to Programming book. Documentation (not just
>>> PHP) does not normally define commonly used terms.
>>
>> I don't think it's that clear cut. Expressions are built from
>> operators, but is ',' an operator in PHP? It appears in the operator
>> precedence table but it isn't an operator in an sense that would
>> normally be understood by someone familiar with these terms.
>
> It is an operator, as indicated by its appearance in the table of
> operators. Operators are not limited to +-*/.
I am familiar with languages that have a ',' operator, which is why I
brought it up. Normally, combining expressions with an operator makes a
new expression, but that's not true in PHP for the comma. For example,
f() and g() are expressions, but (f(), g()) is not. That's why,
presumably, there is no description of what it does in the section on
operators -- it isn't one!
<snip>
>>>> The lack of formal rigor says that there are some questions which just
>>>> can't be answered by reading the language documentation.
>>>
>>> It can if you have a basic understanding of programming.
>>
>> Again, I don't think it's that simple. How would you determine if the
>> following program is permitted and, if it is, what it does?
>>
>> if (false) label: else echo "else\n";
>> goto label;
>>
>> You could try it, of course, but that's hardly very formal.
>
> What language gives every possible way for you to screw up your
> programming?
You seemed to be disagreeing with the statement that there are some
questions which just can't be answered by reading the language
documentation. All I was doing was giving an example of a question I
could not answer from the documentation.
I agree it's very much a corner case (and many not worth an answer) but
there are other such questions. For example, from the documentation
alone I can't explain why ($i++, $j++) is not a valid expression, given
that it appears to consist of brackets and operators and variables, all
put together in the usual way.
> If you want to find out how some screwed-up code works in ANY
> language, you try it and find out.
That's a flawed method. If I have an algorithm that shifts bits about,
but sometimes shifts them *all* out, how can I be sure what
1 << PHP_INT_SIZE*8
really does? If I test it, and it does what I want, can I be sure that
on some other hardware it will do the same? Does PHP define the
meaning of this expression, or does it leave it open (and possibly up to
what the hardware does)?
<snip>
>> The assignment operators in PHP have, in effect, different precedences
>> on the left and the right (a feature that some languages flaunt) but
>> that is not common and certainly not part of what I'd call basic
>> knowledge. The documentation gives one example of this peculiarity, but
>> that does not clear the matter up conclusively. For example, in some
>> languages permit assignment to the result of a conditional expression,
>> but I think it's hard to tell from the documentation what these two do:
>>
>> $bool ? $a : $b = 42;
>> ($bool ? $a : $b) = 42;
>
> Show me what language provides you with examples of every possible
> combination of operators and expressions.
I never suggested otherwise. However, in more rigorously defined
languages you can find out what combinations are permitted from the
specification. With PHP, I often end up just trying things because I
can't find the answer in the documentation. I then assume that what
happens now is what will always happen -- i.e. that the reference
implementation is the specification.
>> The operator precedence table suggests that both mean the same thing,
>> but they don't. I don't think the meaning of either is easily
>> determined from the documentation.
>>
>> <snip>
>>
> So you try it out, as you do in any language. But just because you
> can come up with some weird combination of operators which isn't
> listed in the doc does not mean the language is not rigorously
> defined.
I think that's exactly what it means.
> But it does mean you are trolling.
Eh? This whole thread is an interesting technical discussion about the
degree to which PHP programs are well-defined. If you really think my
contributions are trolling, you know the well-worn advice: don't feed
me.
--
Ben.
|
|
|
Re: Operator precedence [message #185029 is a reply to message #185016] |
Mon, 24 February 2014 16:25 |
|
Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
> Ben Bacarisse wrote:
>
>> […] Expressions are built from operators, but is ',' an operator in PHP?
>> It appears in the operator precedence table but it isn't an operator in an
>> sense that would normally be understood by someone familiar with these
>> terms.
>
> ECMAScript has a “Comma Operator”, too.
But my point was the PHP doesn't have one -- not in any normal sense of
the word. ECMAScript really does have one (like C and C++ do).
<snip>
--
Ben.
|
|
|
|
Re: Operator precedence [message #185032 is a reply to message #185029] |
Mon, 24 February 2014 18:38 |
|
Ben Bacarisse wrote:
> Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
>> Ben Bacarisse wrote:
>>> […] Expressions are built from operators, but is ',' an operator in PHP?
>>> It appears in the operator precedence table but it isn't an operator in
>>> an sense that would normally be understood by someone familiar with
>>> these terms.
>>
>> ECMAScript has a “Comma Operator”, too.
>
> But my point was the PHP doesn't have one --
But it does:
for ($i = 0, $j = 42; $i < $j; ++$i);
^
> not in any normal sense of the word.
Please define what you consider to be an operator in a “normal sense of the
word”.
> ECMAScript really does have one (like C and C++ do).
Why do you think C and C++ have a comma operator (like ECMAScript)?
PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)
|
|
|
|
|
Re: Operator precedence [message #185038 is a reply to message #185034] |
Mon, 24 February 2014 19:37 |
|
Christoph Michael Becker wrote:
> Thomas 'PointedEars' Lahn wrote:
>> Ben Bacarisse wrote:
>>> Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
>>>> Ben Bacarisse wrote:
>>>> > […] Expressions are built from operators, but is ',' an operator in
>>>> > [PHP?
>>>> > It appears in the operator precedence table but it isn't an operator
>>>> > in an sense that would normally be understood by someone familiar with
>>>> > these terms.
>>>>
>>>> ECMAScript has a “Comma Operator”, too.
>>>
>>> But my point was the PHP doesn't have one --
>>
>> But it does:
>>
>> for ($i = 0, $j = 42; $i < $j; ++$i);
>> ^
>
> The comma is used in sevaral places in the PHP grammar[1]. However,
> IMHO your example (inside a for_expr) is the only case where the comma
> is used as an operator. The other uses are for declaration and
> parameter lists (spoken in a broad sense).
I am aware of that.
>>> not in any normal sense of the word.
>>
>> Please define what you consider to be an operator in a “normal sense of
>> the word”.
>
> It might be defined as an operator that can be used in arbitrary
> expressions.
A speculation, one that is almost self-evidently false. Just consider the
operators (including, but not just in, programming languages) that require
their operands to be of a certain type.
> Consider the following ECMAScript expression:
>
> a = 1, b = 2;
>
> The "equivalent" expression in PHP is a syntax error:
>
> $a = 1, $b = 2;
I am aware of that.
>>> ECMAScript really does have one (like C and C++ do).
>>
>> Why do you think C and C++ have a comma operator (like ECMAScript)?
>
> According to the C grammar[2]:
>
> exp : assignment_exp
> | exp ',' assignment_exp
>
> [1] <http://lxr.php.net/xref/PHP_5_5/Zend/zend_language_parser.y>
> [2] <http://www.cs.man.ac.uk/~pjj/bnf/c_syntax.bnf>
ACK; I stand corrected. For reasons I cannot explain (probably it is just
late), I had assumed that the comma operator in ECMAScript also worked with
assignments, and this is what I tested with C and C++:
$ cat foo.c
#include <stdio.h>
int main() {
int x = 42, 23;
printf("%i\n", x);
return 0;
}
$ gcc -Wall -o foo.out foo.c
foo.c: In function ‘main’:
foo.c:4:15: error: expected identifier or ‘(’ before numeric constant
int x = 42, 23;
^
$ cat foo.cpp
#include <iostream>
using namespace std;
int main() {
int x = 42, 23;
cout << x << endl;
return 0;
}
$ g++ -Wall -o foo.out foo.cpp 2>&1| tee /tmp/v6wTKDF/0
foo.cpp: In function ‘int main()’:
foo.cpp:5:15: error: expected unqualified-id before numeric constant
int x = 42, 23;
^
However, in ECMAScript:
| >>> var x = 42, 23;
| SyntaxError: Unexpected number
What I meant instead was
| >>> 42, 23
| 23
which does work like that in certain contexts in C and C++, but not in PHP:
$ cat foo.c
#include <stdio.h>
int main() {
printf("%i\n", (42, 23));
return 0;
}
$ gcc -Wall -o foo.out foo.c 2>&1| tee /tmp/vJ0RqVR/0
foo.c: In function ‘main’:
foo.c:4:21: warning: left-hand operand of comma expression has no effect
[-Wunused-value]
printf("%i\n", (42, 23));
^
$ ./foo.out
23
$ cat foo.cpp
#include <iostream>
using namespace std;
int main() {
cout << (42, 23) << endl;
return 0;
}
$ g++ -Wall -o foo.out foo.cpp
foo.cpp: In function ‘int main()’:
foo.cpp:5:16: warning: left operand of comma operator has no effect
[-Wunused-value]
cout << (42, 23) << endl;
^
$ ./foo.out
23
$ php -r 'echo (42, 23) . "\n";'
PHP Parse error: syntax error, unexpected ',' in Command line code on line
1
[Interesting that gcc says “operand” and “comma *expression*”, while g++
says “operand” and “comma *operator*”.]
PointedEars
--
Sometimes, what you learn is wrong. If those wrong ideas are close to the
root of the knowledge tree you build on a particular subject, pruning the
bad branches can sometimes cause the whole tree to collapse.
-- Mike Duffy in cljs, <news:Xns9FB6521286DB8invalidcom(at)94(dot)75(dot)214(dot)39>
|
|
|
|
|
Re: Operator precedence [message #185043 is a reply to message #185040] |
Mon, 24 February 2014 21:29 |
|
Christoph Michael Becker wrote:
> Thomas 'PointedEars' Lahn wrote:
>> Christoph Michael Becker wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> Ben Bacarisse wrote:
>>>> > not in any normal sense of the word.
>>>>
>>>> Please define what you consider to be an operator in a “normal sense of
>>>> the word”.
>>>
>>> It might be defined as an operator that can be used in arbitrary
>>> expressions.
>>
>> A speculation,
>
> ACK. :)
>
>> one that is almost self-evidently false. Just consider
>> the
>> operators (including, but not just in, programming languages) that
>> require their operands to be of a certain type.
>
> I have to admit that this "definition" was far to inaccurate. However,
> regarding the syntax alone it has some appeal.
This “definition” is simply nonsense. An operator is not only an operator
when it “can be used in arbitrary expressions”. In mathematics, from which
is the definition that fits best here, an operator is a mapping from
elements of one or more sets to elements of another or to the same set. So
*by definition* its context and its operands (members of said sets) matter.
>>>> > ECMAScript really does have one (like C and C++ do).
>>>>
>>>> Why do you think C and C++ have a comma operator (like ECMAScript)?
>>>
>>> According to the C grammar[2]:
>>>
>>> exp : assignment_exp
>>> | exp ',' assignment_exp
>>>
>>> [1] <http://lxr.php.net/xref/PHP_5_5/Zend/zend_language_parser.y>
>>> [2] <http://www.cs.man.ac.uk/~pjj/bnf/c_syntax.bnf>
>>
>> ACK; I stand corrected. For reasons I cannot explain (probably it is
^^^^^^^^^^^^^^^^^
>> just late), I had assumed that the comma operator in ECMAScript also
>> worked with assignments, and this is what I tested with C and C++:
>>
>> $ cat foo.c
>> #include <stdio.h>
>>
>> int main() {
>> int x = 42, 23;
>
> According to the C grammar[1], this use of the comma is not part of an
> "exp", but rather an "init_declarator_list".
>
>> […] printf("%i\n", x);
>> return 0;
>> }
>>
>> $ gcc -Wall -o foo.out foo.c
>> foo.c: In function ‘main’:
>> foo.c:4:15: error: expected identifier or ‘(’ before numeric constant
>> int x = 42, 23;
>> ^
>>
>> However, in ECMAScript:
>>
>> | >>> var x = 42, 23;
>
> This use of the comma is not part of ECMAScript's "Expression", but
> rather of "VariableDeclarationList".
Please stop telling me things I know:
>> | SyntaxError: Unexpected number
>>
>> What I meant instead was
>>
>> | >>> 42, 23
>> | 23
PointedEars
--
When all you know is jQuery, every problem looks $(olvable).
|
|
|
Re: Operator precedence [message #185049 is a reply to message #185032] |
Mon, 24 February 2014 22:08 |
|
Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
> Ben Bacarisse wrote:
>
>> Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
>>> Ben Bacarisse wrote:
>>>> […] Expressions are built from operators, but is ',' an operator in PHP?
>>>> It appears in the operator precedence table but it isn't an operator in
>>>> an sense that would normally be understood by someone familiar with
>>>> these terms.
>>>
>>> ECMAScript has a “Comma Operator”, too.
>>
>> But my point was the PHP doesn't have one --
>
> But it does:
>
> for ($i = 0, $j = 42; $i < $j; ++$i);
But try this:
for (($i = 0, $j = 42); $i < $j; ++$i);
In general, putting an expression in parentheses does not stop it being
an expression. The permission to use ',' in a for statement is special
syntax: it's not part of the syntax for an expression. To give another
example, if the ',' in a for statement built an expression you should be
able to change:
for ($i = 0; f($1), $i < 10; $i++) { ...; }
into
$i = 0;
while (f($1), $i < 10) { ...; $i++; }
but you can't, because while takes an expression as the condition, and
f($i), $i < 10 is not an expression!
>> not in any normal sense of the word.
>
> Please define what you consider to be an operator in a “normal sense of the
> word”.
It's a syntactic symbol that can be used to combine simpler expressions
in such a way that the result is also, syntactically, an expression. In
PHP, you can't take two expressions (E1) and (E2) and write ((E1), (E2))
to get a new expression - the syntax for expressions simply doesn't
permit the use of ',' as an operator.
>> ECMAScript really does have one (like C and C++ do).
>
> Why do you think C and C++ have a comma operator (like ECMAScript)?
Because they do.
--
Ben.
|
|
|
Re: Operator precedence [message #185050 is a reply to message #185049] |
Mon, 24 February 2014 22:17 |
|
Ben Bacarisse wrote:
> Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
>> Ben Bacarisse wrote:
>>> Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
>>>> Ben Bacarisse wrote:
>>>> > […] Expressions are built from operators, but is ',' an operator in
>>>> > [PHP?
>>>> > It appears in the operator precedence table but it isn't an operator
>>>> > in an sense that would normally be understood by someone familiar with
>>>> > these terms.
>>>>
>>>> ECMAScript has a “Comma Operator”, too.
>>>
>>> But my point was the PHP doesn't have one --
>>
>> But it does:
>>
>> for ($i = 0, $j = 42; $i < $j; ++$i);
>
> But try this:
>
> for (($i = 0, $j = 42); $i < $j; ++$i);
Bogus example.
> In general, putting an expression in parentheses does not stop it being
> an expression.
>
> The permission to use ',' in a for statement is special
> syntax: it's not part of the syntax for an expression. To give another
> example, if the ',' in a for statement built an expression you should be
> able to change:
>
> for ($i = 0; f($1), $i < 10; $i++) { ...; }
>
> into
>
> $i = 0;
> while (f($1), $i < 10) { ...; $i++; }
>
> but you can't, because while takes an expression as the condition, and
> f($i), $i < 10 is not an expression!
Irrelevant.
>>> not in any normal sense of the word.
>>
>> Please define what you consider to be an operator in a “normal sense of
>> the word”.
>
> It's a syntactic symbol that can be used to combine simpler expressions
> in such a way that the result is also, syntactically, an expression.
A very narrow definition of “operator”.
PointedEars
--
Sometimes, what you learn is wrong. If those wrong ideas are close to the
root of the knowledge tree you build on a particular subject, pruning the
bad branches can sometimes cause the whole tree to collapse.
-- Mike Duffy in cljs, <news:Xns9FB6521286DB8invalidcom(at)94(dot)75(dot)214(dot)39>
|
|
|
Re: Operator precedence [message #185052 is a reply to message #185017] |
Mon, 24 February 2014 22:41 |
|
On 2/24/14, 7:00 AM, Jerry Stuckle wrote:
> What language gives every possible way for you to screw up your
> programming?
>
> If you want to find out how some screwed-up code works in ANY language,
> you try it and find out.
>
Herein lies the path to madness.
Take the following C code
#include <stdio.h>
int main() {
int i = 4;
i = ++i + i++;
printf("%i\n", i);
return 0;
}
Question, you want to find out what this is supposed to do. By your
statement, you run it on a system. The problem is that the answer you
get is only valid for THAT system, and possible for that EXACT piece of
code.
The REAL answer is you compare the code to the formal specification of
the language, and you get the answer.
Too many people use your answer, and then complain because they get a
different answer on another machine, or in different circumstances, and
then complain that the compiler is "broken", when the real answer is
that THEIR program was the one that was broken.
(For those not familiar with C, the answer in this case is that the
program has performed "undefined behavior" by modifying i twice without
a sequence point, and thus *ANY* resultant behavior is acceptable.
Here is a question, does PHP's documentation promise how the equivalent
PHP statement will execute?
....
>> The assignment operators in PHP have, in effect, different precedences
>> on the left and the right (a feature that some languages flaunt) but
>> that is not common and certainly not part of what I'd call basic
>> knowledge. The documentation gives one example of this peculiarity, but
>> that does not clear the matter up conclusively. For example, in some
>> languages permit assignment to the result of a conditional expression,
>> but I think it's hard to tell from the documentation what these two do:
>>
>> $bool ? $a : $b = 42;
>> ($bool ? $a : $b) = 42;
>>
>
> Show me what language provides you with examples of every possible
> combination of operators and expressions.
Read the C Grammer definition. It precisely describes how ANY expression
is to be parsed.
It does give the compiler freedom to choose the order to execute the
parse tree, so things without inherent order have no promise of order,
but this is made explicit.
>
>> The operator precedence table suggests that both mean the same thing,
>> but they don't. I don't think the meaning of either is easily
>> determined from the documentation.
>>
>> <snip>
>>
>
> So you try it out, as you do in any language. But just because you can
> come up with some weird combination of operators which isn't listed in
> the doc does not mean the language is not rigorously defined.
> with
> But it does mean you are trolling.
>
Rigorously defined would mean "precisely or exactly defined", which,
yes, does say that if you can come up with a "weird" combination, that
is not documented as to what is to happen, the definition is not
rigorous. A Formal definition, will be complete, as that is part of
being formal.
|
|
|
Re: Operator precedence [message #185053 is a reply to message #185030] |
Mon, 24 February 2014 23:32 |
|
Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
> On 2/24/2014 4:23 PM, Ben Bacarisse wrote:
>> Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
<snip>
>>> It is an operator, as indicated by its appearance in the table of
>>> operators. Operators are not limited to +-*/.
>>
>> I am familiar with languages that have a ',' operator, which is why I
>> brought it up. Normally, combining expressions with an operator makes a
>> new expression, but that's not true in PHP for the comma. For example,
>> f() and g() are expressions, but (f(), g()) is not. That's why,
>> presumably, there is no description of what it does in the section on
>> operators -- it isn't one!
>
> Documentation indicates what you CAN do - not what you CAN'T do. This
> is true of languages, databases, spreadsheets and about anything else
> around.
What can you do with the ',' operator? From the PHP documentation:
An operator is something that takes one or more values (or
expressions, in programming jargon) and yields another value (so that
the construction itself becomes an expression).
I can't see any usage of ',' that matches this definition. By the
manual's own definition, ',' in not an operator in PHP.
As to your general point, the C language standard is an excellent
example of documentation that says both what you can do and what you
can't do. In extreme cases the distinction disappears, because a
language that specifies exactly what can be done, implicitly defines
what can't. But n practice it's easier to do a bit of both. For
example, you might give a general grammar, and then explain some
restrictions, such as what forms are not permitted on the left of an
assignment.
>> <snip>
>>>> >> The lack of formal rigor says that there are some questions which just
>>>> >> can't be answered by reading the language documentation.
>>>> >
>>>> > It can if you have a basic understanding of programming.
>>>>
>>>> Again, I don't think it's that simple. How would you determine if the
>>>> following program is permitted and, if it is, what it does?
>>>>
>>>> if (false) label: else echo "else\n";
>>>> goto label;
>>>>
>>>> You could try it, of course, but that's hardly very formal.
>>>
>>> What language gives every possible way for you to screw up your
>>> programming?
>>
>> You seemed to be disagreeing with the statement that there are some
>> questions which just can't be answered by reading the language
>> documentation. All I was doing was giving an example of a question I
>> could not answer from the documentation.
>
> See above.
So you think my example is of something that can't be done and that is
why you can't tell what the code done by
>
>> I agree it's very much a corner case (and many not worth an answer) but
>> there are other such questions. For example, from the documentation
>> alone I can't explain why ($i++, $j++) is not a valid expression, given
>> that it appears to consist of brackets and operators and variables, all
>> put together in the usual way.
>>
>
> See above. Also, this is PHP, not C or C++.
>
>>> If you want to find out how some screwed-up code works in ANY
>>> language, you try it and find out.
>>
>> That's a flawed method. If I have an algorithm that shifts bits about,
>> but sometimes shifts them *all* out, how can I be sure what
>>
>> 1 << PHP_INT_SIZE*8
>>
>> really does? If I test it, and it does what I want, can I be sure that
>> on some other hardware it will do the same? Does PHP define the
>> meaning of this expression, or does it leave it open (and possibly up to
>> what the hardware does)?
>>
>
> That is how you test anything. And you can NEVER be sure that ANY
> operation will work the same when you change
> compilers/interpreters. You need to be looking at the documentation
> for the software you're using, not something else.
>
> For instance a 32 bit C compiler will have different results than a 64
> bit C compiler, even if both are run on a 64 bit machine. And even
> different 32 bit C compilers can have different output. For instance,
> in a 32 bit C compiler, an int can be 8, 16, or 32 bits long - all
> within the specs
No, C does no permit int to be less that 16 bits wide -- 8 is not
allowed.
> (which only states the length of an int is >= the
> length of a short, and <= the length of a long). So it is entirely
> possible one C compiler will have a 16 bit int, while another has a 32
> bit int. And both are within the C spec.
Yes, but the language gives minimum guarantees which can be used to
permit code to be ported. It also (often) explicitly says where there
is no guarantee. For example, shifting right by the width of the type
being shifted is explicitly "undefined". It's useful to know that,
because you can simply avoid the situation in the first place. That's
simpler that testing it, seeing that it does what you expect, and then
finding that it fails on some other hardware.
> And on 64 bit hardware, an int could be 64 bits long.
More surprisingly, so could a char!
>> <snip>
>>>> The assignment operators in PHP have, in effect, different precedences
>>>> on the left and the right (a feature that some languages flaunt) but
>>>> that is not common and certainly not part of what I'd call basic
>>>> knowledge. The documentation gives one example of this peculiarity, but
>>>> that does not clear the matter up conclusively. For example, in some
>>>> languages permit assignment to the result of a conditional expression,
>>>> but I think it's hard to tell from the documentation what these two do:
>>>>
>>>> $bool ? $a : $b = 42;
>>>> ($bool ? $a : $b) = 42;
>>>
>>> Show me what language provides you with examples of every possible
>>> combination of operators and expressions.
>>
>> I never suggested otherwise. However, in more rigorously defined
>> languages you can find out what combinations are permitted from the
>> specification. With PHP, I often end up just trying things because I
>> can't find the answer in the documentation. I then assume that what
>> happens now is what will always happen -- i.e. that the reference
>> implementation is the specification.
>>
> The PHP doc shows you what combinations are permitted. You are asking
> about what is NOT permitted.
Yes, because that is part of the specification of the language. Aren't
you curious to know what expression forms are permitted on the left of
an assignment? Would you not find a grammar for PHP to be a useful part
of the documentation? These thing seem unexceptional to me.
<snip>
>>> So you try it out, as you do in any language. But just because you
>>> can come up with some weird combination of operators which isn't
>>> listed in the doc does not mean the language is not rigorously
>>> defined.
>>
>> I think that's exactly what it means.
>
> Fine. Go ahead and document every possible bad combination of
> operators. I won't wait up for your results.
Well, I'd rather not. PHP has a more special cases than other languages
I've used, so it would be harder than for those. But I am surprised
that that you think it's so unreasonable to expect at least a moderately
rigorous definition of what is and is not permitted. As I said before,
it seems perfect reasonable to me. Even a grammar for the language
(surely not that hard) would have eliminated the OP's question from the
get go.
>>> But it does mean you are trolling.
>>
>> Eh? This whole thread is an interesting technical discussion about the
>> degree to which PHP programs are well-defined. If you really think my
>> contributions are trolling, you know the well-worn advice: don't feed
>> me.
>
> You claim you understand why things which can't be done are not
> documented. Then you argue because what you want to try is not
> documented, and denigrate PHP because it doesn't follow YOUR
> definition of "rigorously defined".
I don't recognise any of that.
I was making a sound technical point in reply to you: that PHP does not
have a ',' operator except in some sort of literalist sense: the manual
says it does, so it does, despite the fact that its meaning is undefined
and you can't use it in expressions to make bigger expressions.
Your counter argument seems to be that the manual is not obliged to
document what you can't do. I disagree about that, but even if this is
granted, it is surely a mistake to list ',' as an operator when it
clearly isn't.
<snip>
--
Ben.
|
|
|
Re: Operator precedence [message #185054 is a reply to message #185050] |
Mon, 24 February 2014 23:45 |
|
Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
> Ben Bacarisse wrote:
>
>> Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
>>> Ben Bacarisse wrote:
>>>> Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
>>>> > Ben Bacarisse wrote:
>>>> >> […] Expressions are built from operators, but is ',' an operator in
>>>> >> [PHP?
>>>> >> It appears in the operator precedence table but it isn't an operator
>>>> >> in an sense that would normally be understood by someone familiar with
>>>> >> these terms.
>>>> >
>>>> > ECMAScript has a “Comma Operator”, too.
>>>>
>>>> But my point was the PHP doesn't have one --
>>>
>>> But it does:
>>>
>>> for ($i = 0, $j = 42; $i < $j; ++$i);
>>
>> But try this:
>>
>> for (($i = 0, $j = 42); $i < $j; ++$i);
>
> Bogus example.
>
>> In general, putting an expression in parentheses does not stop it being
>> an expression.
This is why it's not bogus. By all means explain why your understanding
of what an operator permits the construction of something that is not an
expression, but don't just say "bogus".
I contend that for ',' to be an operator, it should form part of an
expression, and I contend that expressions can be put in parentheses and
remain expressions. You can challenge either notion, but then I think
we will be disagreeing only about definitions.
<snip>
>>> Please define what you consider to be an operator in a “normal sense of
>>> the word”.
>>
>> It's a syntactic symbol that can be used to combine simpler expressions
>> in such a way that the result is also, syntactically, an expression.
>
> A very narrow definition of “operator”.
Maybe, but it comports with what PHP considers to be an operator:
"An operator is something that takes one or more values (or
expressions, in programming jargon) and yields another value (so that
the construction itself becomes an expression)."
If you have a different definition, we could just agree on the fact that
PHP has no ',' operator as PHP defines the term.
What is your definition?
--
Ben.
|
|
|
|
|
Re: Operator precedence [message #185060 is a reply to message #185055] |
Tue, 25 February 2014 11:56 |
|
Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
> On 2/24/2014 11:32 PM, Ben Bacarisse wrote:
>> Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
>>
>>> On 2/24/2014 4:23 PM, Ben Bacarisse wrote:
>>>> Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
>> <snip>
>>>> > It is an operator, as indicated by its appearance in the table of
>>>> > operators. Operators are not limited to +-*/.
>>>>
>>>> I am familiar with languages that have a ',' operator, which is why I
>>>> brought it up. Normally, combining expressions with an operator makes a
>>>> new expression, but that's not true in PHP for the comma. For example,
>>>> f() and g() are expressions, but (f(), g()) is not. That's why,
>>>> presumably, there is no description of what it does in the section on
>>>> operators -- it isn't one!
>>>
>>> Documentation indicates what you CAN do - not what you CAN'T do. This
>>> is true of languages, databases, spreadsheets and about anything else
>>> around.
>>
>> What can you do with the ',' operator? From the PHP documentation:
>
> Where in the PHP manual does it say ',' is an operator?
"A full list of PHP operators follows in the section Operator
Precedence." (which is the section immediately following)
That list includes ',' as you yourself stated:
"It is an operator, as indicated by its appearance in the table of
operators. Operators are not limited to +-*/.".
But if that is no longer your position, then we are in agreement.
<snip>
>> As to your general point, the C language standard is an excellent
>> example of documentation that says both what you can do and what you
>> can't do. In extreme cases the distinction disappears, because a
>> language that specifies exactly what can be done, implicitly defines
>> what can't. But n practice it's easier to do a bit of both. For
>> example, you might give a general grammar, and then explain some
>> restrictions, such as what forms are not permitted on the left of an
>> assignment.
>
> No, the C specification does NOT say what you cannot do. Some books
> may add some things you cannot do, but the language itself doesn't.
> Check it out yourself - it's available at the ANSI website (for a
> price). Some university and/or technical libraries also have a copy.
How many examples would you like? For example, the C standard gives a
grammar for expressions and then, for each operator, it gives
constraints on that general form. The grammar permits 1 = 1, but the
constraints on the = operator state that the expression on the left hand
side must be a modifiable lvalue. The upshot is that you can tell what
forms of expression are and are not permitted. In particular, C does
not permit (cond ? a : b) = expr; but C++ does.
PHP is, as far as I can tell, silent on this matter. Don't you think
some more clarity about what is permitted and what is not permitted
would be useful?
(If you want to make a linguistic point that a constraint on what you
can do is not the same as saying that you cannot do something, then I
refer you to my C++ quote below.)
<snip>
>>> For instance a 32 bit C compiler will have different results than a 64
>>> bit C compiler, even if both are run on a 64 bit machine. And even
>>> different 32 bit C compilers can have different output. For instance,
>>> in a 32 bit C compiler, an int can be 8, 16, or 32 bits long - all
>>> within the specs
>>
>> No, C does no permit int to be less that 16 bits wide -- 8 is not
>> allowed.
>
> Actually, the ANSI C spec DOES allow it. The spec sets no hard
> minimum or maximum for the size of any of the numeric values. C can
> still run on 8 bit processors, also (as in imbedded systems).
It seems odd to be disagreeing about easily verifiable facts. ANSI C is
often used to refer to the first C standard (1989), in which case look
at section 2.2.4.2 "Numerical limits". If you mean the current ANSI
standard, that's ISO/IEC 9899:2011 and the section you need is
"5.2.4.2.1 Sizes of integer types <limits.h>". (You also need the
section from each that states that the constraints imposed by limits.h
apply to both hosted and free-standing implementations.)
>>> (which only states the length of an int is >= the
>>> length of a short, and <= the length of a long). So it is entirely
>>> possible one C compiler will have a 16 bit int, while another has a 32
>>> bit int. And both are within the C spec.
>>
>> Yes, but the language gives minimum guarantees which can be used to
>> permit code to be ported. It also (often) explicitly says where there
>> is no guarantee. For example, shifting right by the width of the type
>> being shifted is explicitly "undefined". It's useful to know that,
>> because you can simply avoid the situation in the first place. That's
>> simpler that testing it, seeing that it does what you expect, and then
>> finding that it fails on some other hardware.
>
> The only minimum is that an int must not be smaller than a short.
No, there are others -- in particular, a minimum range of representable
values for each of the standard integer types. For int it is from
-32767 to +32767.
<snip>
>>> The PHP doc shows you what combinations are permitted. You are asking
>>> about what is NOT permitted.
>>
>> Yes, because that is part of the specification of the language. Aren't
>> you curious to know what expression forms are permitted on the left of
>> an assignment? Would you not find a grammar for PHP to be a useful part
>> of the documentation? These thing seem unexceptional to me.
>
> No, the specification of a language states only what is allowed. For
> instance, the C++ spec specifies which operators may be overridden.
> It does NOT specify that the '.' operator may not be overridden.
Are you just saying wrong things to wind me up? Section 13.5
"Overloaded operators" of the current C++ standard says:
"The following operators cannot be overloaded:
. .* :: ?:"
Similar wording exists in the 1998 and 2003 standards.
<snip>
> PHP is documented exactly the same as all of the other 20-odd
> languages I've used over the years. About the only difference is that
> PHP doc is written in a friendlier language (have you ever read an
> ANSI spec, for instance?).
Given the above, I think you can conclude that I have. But we do agree:
I like the informal, friendly, language of the reference manual. But
for many other languages I've used, there is also a relatively rigorous
specification that forgoes friendly language in order to answer exactly
the kind of questions that I and OP raised in this thread. It's not
essential, and I understand why no one wants to produce it, but that it
would be a good idea does not seem to me to be at all controversial.
<snip>
> Please show where in the manual it shows you can use the ',' operator
> like you want.
I don't want to use it in any particular way. In that, the manual is
100% correct because it says nothing at all about how one might use ','
in the way it describes operators as working. Bun I was just querying
your statement that it is one. If you don't think it's an operator, we
are in agreement about that.
--
Ben.
|
|
|
|
|
Re: Operator precedence [message #185064 is a reply to message #185063] |
Tue, 25 February 2014 13:55 |
|
Christoph Michael Becker wrote:
> Thomas 'PointedEars' Lahn wrote:
>> Christoph Michael Becker wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> Christoph Michael Becker wrote:
>>>> > Thomas 'PointedEars' Lahn wrote:
>>>> >> Ben Bacarisse wrote:
>>>> >>> not in any normal sense of the word.
>>>> >> Please define what you consider to be an operator in a “normal sense
>>>> >> of the word”.
>>>> > It might be defined as an operator that can be used in arbitrary
>>>> > expressions.
>>>> A speculation, one that is almost self-evidently false. Just consider
>>>> the operators (including, but not just in, programming languages) that
>>>> require their operands to be of a certain type.
>>>
>>> I have to admit that this "definition" was far to inaccurate. However,
>>> regarding the syntax alone it has some appeal.
>>
>> This “definition” is simply nonsense. An operator is not only an
>> operator when it “can be used in arbitrary expressions”. In mathematics,
>> from which is the definition that fits best here, an operator is a
>> mapping from elements of one or more sets to elements of another or to
>> the same set.
>
> That sounds "very similar" to the definition of a function. ;)
Yes, this is not a coincidence.
>>>> However, in ECMAScript:
>>>>
>>>> | >>> var x = 42, 23;
>>>
>>> This use of the comma is not part of ECMAScript's "Expression", but
>>> rather of "VariableDeclarationList".
>>
>> Please stop telling me things I know:
>
> I have posted a message to Usenet. If you already knew these details,
> fine. However, other readers might not.
I had already conceded that I was wrong, and explained why. You have been
preaching to the choir.
> Furthermore I was trying to stress my (resp. Ben's) point, that a comma
> is not always an operator, even if a language defines a comma operator.
No disagreement there. However, strange as it may seem, without proof to
the contrary “,” *is* an operator in PHP. That it is one is not negated by
its being of limited use (which contradicts the manual; we may assume that
it was intended to work like in C/C++/ECMAScript, but was never implemented
this way; a documentation bug should be filed).
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
|
|
|
|
|
Re: Operator precedence [message #185071 is a reply to message #185067] |
Tue, 25 February 2014 14:43 |
|
Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>> I have my own problems with PHP - for instance, it is entirely possible
>> to create an object without calling a constructor - a violation of OO
>> principles. But I work around it.
>
> How is it possible to create an object without its constructor (if
> defined) being called?
Implicitly: Call a factory method instead (which is neither “a violation of
OO principles” nor PHP-specific).
This can be useful. As you may recall, recently we discussed thread-safe
date formatting in de.comp.lang.php; I suggested the intl extension:
$ php -r 'echo IntlDateFormatter::create("hi@calendar=BUDDHIST",
IntlDateFormatter::FULL, IntlDateFormatter::LONG)->format(mktime(1, 2, 3, 4,
5, 2006)) . "\n";'
बुधवार, 5 अप्रैल ईस्वी2006 को 1:02:03 पूर्वाह्न GMT+2
PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee
|
|
|
|
|