PHP contra Perl
-
In Perl hab ich noch nie gearbeitet. Aber kann es wirklich schlimmer werden als PHP??
For converted Perl programmers: use strict comparison operators (===, !==) in place of string comparison operators (eq, ne). Don't use the simple equality operators (==, !=), because ($a == a eq $b) would return FALSE.
For instance...
"mary" == "fred" is FALSE, but
"+010" == "10.0" is TRUE (!)*seufz*
Auch hab ich mal nen Fehler gesucht, weil strpos FALSE liefert wenn er was nicht findet und ich wunder mich warum er es nicht findet. Die Auflösung war, dass er es an der Stelle 0 findet, was korrekt ist, aber leider zu einer klitzekleinen Komplikation geführt hat.
if( 0 == "sdkufg" ) // Ergibt true
-
Optimizer schrieb:
if( 0 == "sdkufg" ) // Ergibt true
Das glaube ich dir nicht. Was aber sein kann, und wovon ich ausgehe, dass du es meinst:
0==strpos("asdfghjkl","e");
- Das gibt dann true zurück, weil false auch den wert 0 hat... aber macht man das hier:
0===strpos("asdfghjkl","e");
liefert es false zurück, weil hier wirklich exakt darauf geachtet wird, dass es 0 und nicht false ist. Für mich eine gute Logik, sodass es dem Programmierer vorbehalten bleibt, es so zu sehen, dass 0=false ist (Wie in C/C++) oder eben nicht. Ich weiß nicht, wieso du dich darüber aufregst... mein gott... macht man halt ein gleichheitszeichen mehr rein...
-
Optimizer schrieb:
In Perl hab ich noch nie gearbeitet. Aber kann es wirklich schlimmer werden als PHP??
For converted Perl programmers: use strict comparison operators (===, !==) in place of string comparison operators (eq, ne). Don't use the simple equality operators (==, !=), because ($a == a eq $b) would return FALSE.
For instance...
"mary" == "fred" is FALSE, but
"+010" == "10.0" is TRUE (!)*seufz*
sehe da kein problem, dass ist doch nur definitions-sache und man muss halt wissen welchen operator man wo verwendet.
In C++ schreibst du ja auch nichtchar a[10], b[10];
if(a == b);
-
DrGreenthumb schrieb:
In C++ schreibst du ja auch nicht
char a[10], b[10];
if(a == b);Du etwa nicht?
-
Windoof schrieb:
Optimizer schrieb:
if( 0 == "sdkufg" ) // Ergibt true
Das glaube ich dir nicht.
Dann probier es doch aus. Glauben hilft dir hier nicht weiter. PHP wandelt bei solchen vergleichen den String implizit in ein int um.
Es gibt nur eines was noch schlimmer ist als eine untypisierte Sprache: Ein untypisierte Sprache die völlig sinnlose Konvertierungen implizit durchführt.DrGreenthumb schrieb:
char a[10], b[10];
if(a == b);Ich sehe den Zusammenhang nicht.
"+010" == "10.0"
sollte IMHO ein Stringvergleich sein (also wenn dann a und b vom Typ std::string), stattdessen werden beide Seiten (die beide Strings sind !!!) implizit in Zahlen konvertiert (obwohl eins auch noch Ganzzahl und das andere FP ist) und verglichen. Während der Pointer-Vergleich bei C++ selten sinnvoll aber wenigstens logisch ist, werden hier irgendwelchen völlig unsinnigen Konvertierungen durchgeführt.
Das ist affig. Da kannst du mir erzählen was du willst. Und wie gesagt, ich sehe den Zusammenhang nicht zu deinem Code.
-
Optimizer schrieb:
Ich sehe den Zusammenhang nicht.
In beiden Fällen muss man wissen, was == bedeutet. Wenn man PHP programmiert, muss man halt wissen, dass Zeichenketten mit eq (oder was auch immer) verglichen werden und == eine andere Bedeutung hat, so wie du in C strcmp nehmen musst und es in C++ bei stringobjekten auf einmal doch wieder mit == geht.
Vielleicht wird so ein "wischiwaschi-Vergleich" im Kontext der Webprogrammierung viel häufiger benötigt als der genaue Zeichenkettenvergleich.
Ich kenne weder Perl noch PHP genauer aber nur weils ungewohnt erscheint, muss es ja nicht unlogisch sein.
-
Also, um nochmal hervorzuheben, was ich unlogisch finde:
Ich finde es nicht unlogisch, dass wenn ich in C++ zwei Pointer vergleiche, dass nicht der Stringinhalt verglichen wird. Ich finde es nicht unlogisch, wenn bei std::string der Inhalt verglichen wird.
Ich finde es unlogisch, wenn ich etwas dieser Form habe:
einString == nochEinStringdass beide Strings implizit in Zahlen konvertiert werden. Insbesondere, wenn es sich um Strings wie "sodiufh" handelt. DAS ist unlogisch. "dsuokfg" ist keine Zahl. Das ist auch nicht 0. 0 ist auch nicht das selbe wie "keine Zahl". Sowas gehört geschlagen.
Du musst das Ganze jetzt noch unter dem Aspekt sehen, dass es so etwas wie Typen in PHP nicht direkt gibt. Du hast keine Möglichkeit, dich gegen so ein Verhalten zu wehren, weil _alles_ irgendwie in _alles_ umgewandelt wird. Ich finde es aber unlogisch, wenn ich links und rechts zwei gleiche Typen habe, dass beide umgewandelt werden. Weiter. Wenn also "soduhfölisgh" in 0 umgewandelt wird und mit der Zahl 0 verglichen true ergibt.
Warum gibt dann eigentlich"sgdukf" == "skudgfkusgd"
nicht
0 == 0
sondern liefert dann auf einmal false?
Fragen über Fragen. Die man sicher irgendwo nachlesen kann. Aber das System ist Schrott. Es ist halt nirgendwo konsequent.
"abc" == 0
true
"xyz" == 0true
"abc" == "xyz"false
macht schon keinen Sinn mehr. Der Vergleichsoperator ist damit nicht transitiv.
"10.0" == "000010"true
und jetzt dafür wieder das.
-
Optimizer schrieb:
Es ist halt nirgendwo konsequent.
"abc" == 0
true
"xyz" == 0true
"abc" == "xyz"false
macht schon keinen Sinn mehr. Der Vergleichsoperator ist damit nicht transitiv.
"10.0" == "000010"true
und jetzt dafür wieder das.
also, wie gesagt, ich kenne PHP nicht, aber ich sehe hier schon konsequenz.
So wie du bei "string" einen Pointer oder eine Zeichenkette siehst, sieht der ==-Operator eben einfach den Wert, also nicht die Repräsentation im Computer sondern eher das, was man auch als Mensch sieht.Woanders würde man sich dafür vielleicht eine Funktion human_compare(T, T) schreiben. Hier braucht man das jetzt offenbar so oft, dass es gleich ein Operator dafür gibt. Wieso nicht.
-
Was meinst du jetzt mit 'Wert' ? Den Wert als Zahl? Warum schlägt dann der Vergleich "abc" == "xyz" fehl? Weil das keine Zahlen sind? Warum trifft dann der Vergleich "abc" == 0 zu? Ne, das ist IMHO nicht konsequent.
Und ich erwarte von einem op==, dass er transitiv ist. Sprich:
Es sei x == y und y == z
=> x == z
-
Optimizer schrieb:
"abc" == 0
true
"xyz" == 0true
"abc" == "xyz"false
macht schon keinen Sinn mehr. Der Vergleichsoperator ist damit nicht transitiv.
"10.0" == "000010"true
und jetzt dafür wieder das.
der Grund, warum das false liefert, ist weil der Inhalt von !abc" nicht gleich wie der von "xyz". Ich verstehe was du meinst, aber du solltest auch besser wissen, was php macht. PHP macht keine Typunwandlung rein willkürlich, sondern wenn es erfordelich ist. Wenn du "abc"=="cde" hast, dann weiß PHP, dass sowohl links als auch Rechts ein string steht und somit ist eine Typumwandlung überflüssig. Bei 0=="abc" ist es so, das PHP sieht, dass 0 ein int ist und abc ein string, so wandelt "abc" in ein int um, oder umgekehrt, das 0 in einem string. Die Typumwandlung erfolgt nur, wenn links und rechts ungleiche Typs stehen.
Aber "abc"==$var1 ist tatsäclich riskant, deshalb bietet PHP Funktionen wie is_int, is_string, is_scalar,... und sollte davor benutzt werden.
-
supertux schrieb:
Aber "abc"==$var1 ist tatsäclich riskant, deshalb bietet PHP Funktionen wie is_int, is_string, is_scalar,... und sollte davor benutzt werden.
Ja, klar, das bringt das nicht-Typsystem sowieso mit sich. Deiner obigen Logik kann ich auch folgen. Ich habe nur folgendes Problem: Wenn ich deine Logik weiterspinne, komme ich zu diesem Fall:
"10.0" == "000010"
Ich möchte das jetzt unter deinem Gesichtspunkt betrachten:
Wenn du "abc"=="cde" hast, dann weiß PHP, dass sowohl links als auch Rechts ein string steht und somit ist eine Typumwandlung überflüssig.
Ich weiß jetzt, dass ich links und rechts einen String habe, denn ich habe ihn in schönen Anführungszeichen gesetzt. Trotzdem verhält sich PHP nicht so, wie es deiner (und meiner) Logik entspricht.
Leider bist du auch nicht auf das Problem mit der Transitivität eingegangen. Der Operator == wird in der PHP Dokumentation als "Gleichheitsoperator" bezeichnet. "Gleichheit" ist, wie man weiß, in jeder beliebigen M (also Elementtyp beliebig!!) eine Äquivalenzrelation. Äquivalenzrelationen müssen folgende Bedingungen erfüllen:
- Reflexivität
- Symmetrie
- TransitivitätUnd letzteres erfüllt der op== in PHP nicht. Diese Sprache ist damit mit der Logik (und ich rede hier nicht von meiner Logik, sondern der formal korrekten Logik) nicht greifbar. Und mich stört sowas, wenn ein op== keine Äquivalenzrelation ist.
-
oh Mann... wenn du eine Äquivlenzrelation haben willst, dann nim ein Baltt Papier und beweise die Übunsgaufgaben von Lineare Algebra
Im Ernst, ich verstehe was du meinst, aber ich glaube nicht, dass die PHP Entwickler daran gedacht haben, dass es eine Äquivalenzrelation sein soll.Außerdem machst du einen Fehler. Auch bei Sprachen, die == als Äquivalenzrelation haben, liefert == einen greifbaren Wert zurück, wie TRUE/FALSE, 0 oder 1 oder was weiß ich. Eine richtige Äquivalenzrelation tut sowas nicht, weil sie eine Äquivrel. und keine Funktion ist. Aber ist == in keiner Sprache wirklich eine Äquivalenzrelation. Und du weißt, eine Äquivalrel. stellt Beziehungen zwischen Elementen einer Menge, bildet sie aber niergendswo ab.
-
Außerdem machst du einen Fehler. Auch bei Sprachen, die == als Äquivalenzrelation haben, liefert == einen greifbaren Wert zurück, wie TRUE/FALSE, 0 oder 1 oder was weiß ich. Eine richtige Äquivalenzrelation tut sowas nicht, weil sie eine Äquivrel. und keine Funktion ist.
Hmmmm, kann ich nicht ganz nachvollziehen. In C++ ist == eine Äquivalenzrelation, außer du implementierst ihn für deine eigenen Typen falsch. In Java/C# auch.
Und es ist ja keine Abbildung. Der Rückgabewert true oder false gibt ja nur an, ob die Aussage wahr oder falsch ist. Jede Relationale Aussage kann wahr oder falsch sein, ich würde das jetzt nicht als Funktion auffassen.Ich kann mir jetzt nirgendwo in besagten Sprachen einen Fall vorstellen, wo x == y und y == z wahre Aussagen sind, x == z dagegen falsch. In C++ ist es natürlich möglich, aber standardmäßig ist das Verhalten auch dort korrekt.
Und wenn dir das Beispiel nicht zusagt, können wir ja wieder zu "10.0" == "000010" bzw. "sodosih" == "skudgf" wechseln.
Hier ist das Verhalten des Operators vom Wert der Operanden abhängig. Also ne Logik kann ich da nicht entdecken.
-
du hast mich nicht verstanden. Eine Äquivalenzrelation stellt nur die Bezihung zwischen Elementen einer Menge, wenn eine gegebene Bedingung gilt. == liefert in C/C++ einen Wert zurück, etwa 1 oder TRUE oder nenn ihn wie du es willst. Und das ist ein Unterschied, denn == ist eher eine Funktion (mathematisch gesehen) als eine Äquivalenzrelation (auch mathematische gesehen)
-
Optimizer schrieb:
"Gleichheit" ist, wie man weiß, in jeder beliebigen M (also Elementtyp beliebig!!) eine Äquivalenzrelation. Äquivalenzrelationen müssen folgende Bedingungen erfüllen:
- Reflexivität
- Symmetrie
- TransitivitätUnd letzteres erfüllt der op== in PHP nicht.
Du gehst von einer anderen Definition von Gleichheit als PHP aus.
in PHP ist == nicht transitiv. Punkt. Sollte allgemeinhin bekannt sein, auch wenn die PHP Doku es nicht direkt erwaehnt.
Du kannst jederzeit die Typen selber bestimmten (wozu kann man denn casten?)
Das Problem das du mit PHP hast ist, dass es keine Typen gibt und zwar wirklich keine. "foo" ist eine string repraesentation des int wertes 0, wenn du so willst. Wenn du "-1"==-1 machst, bekommst du true, weil beides -1 darstellt. Bei "-foo"==-1 bekommst du false, weil "-foo" eben als int repraesentation 0 hat.
Das ist kein bisschen unlogisch, sondern einfach nur anders als bei Sprachen wie Java oder C++.
Wenn du wirklich 2 strings vergleichen willst, nimm strcmp oder mach strval auf beide operanden. Um so die repraesentation so zu deiner zufriedenheit anzupassen.
PHP hat diesen Schritt bewusst gewaehlt, weil es die beste Loesung fuer das Problem ist -> wie willst du 2 unterschiedliche Typen vergleichen?
Entweder ist
"0" != 0.0
oder
0 == "foo"fuer eins musst du dich entscheiden.
oder du machst es wie perl und erfindest eq und ==
PHP hat beide wege gewaehlt
"0"==0.0
und
strcmp(0,"foo")==0cool, gell?
das ist keineswegs unlogisch, lediglich anders als bei anderen sprachen.
in der praxis stoert das nicht transitive verhalten von == aber kein bisschen.
[quote[Diese Sprache ist damit mit der Logik (und ich rede hier nicht von meiner Logik, sondern der formal korrekten Logik) nicht greifbar.[/quote]
Was natuerlich nicht stimmt. Weil du von falschen voraussetzungen ausgehst.Und mich stört sowas, wenn ein op== keine Äquivalenzrelation ist.
Mich nicht, und?
-
Shade Of Mine schrieb:
Du gehst von einer anderen Definition von Gleichheit als PHP aus.
Das ist doch keine Aussage. Du gehst von einer anderen Definition von "Blau" aus als ich. Gleichheit ist eine mathematisch definierte Äquivalenzrelation und ich kenne sonst keine Sprache, die das verletzt. Ich bring doch den mathematischen Schnickschnack nicht zum Spaß. Während ich hier eine allgemein akzeptierte Grundlage bringe sagst du einfach "PHP definiert es anders". Nicht nur das. Du sagst "Ich definiere es anders als PHP".
Das Problem das du mit PHP hast ist, dass es keine Typen gibt und zwar wirklich keine. "foo" ist eine string repraesentation des int wertes 0, wenn du so willst. Wenn du "-1"==-1 machst, bekommst du true, weil beides -1 darstellt. Bei "-foo"==-1 bekommst du false, weil "-foo" eben als int repraesentation 0 hat.
Das ist kein bisschen unlogisch, sondern einfach nur anders als bei Sprachen wie Java oder C++.
Nimm mich bitte ein bisschen wörtlicher. Ich hab nicht gesagt, dass ich das unlogisch finde. Ich habe gesagt, dass ich es unlogisch finde, dass der op== sich je nach Wert der Operanden anders umwandelt und vergleicht:
"foo" ist eine string repraesentation des int wertes 0
und "bar" auch, oder? Fein, kann ich mit leben. Trotzdem fällt der Vergleich "foo" == "bar" negativ aus. Und das ist unlogisch. Nicht das, was du mir oben ankreiden willst, so intolerant bin ich auch wieder nicht.
Es fehlt einfach die Konsequenz.
Wenn du wirklich 2 strings vergleichen willst, nimm strcmp oder mach strval auf beide operanden. Um so die repraesentation so zu deiner zufriedenheit anzupassen.
Das Vergleichen von Strings ist jetzt nicht mein Problem...
PHP hat diesen Schritt bewusst gewaehlt, weil es die beste Loesung fuer das Problem ist -> wie willst du 2 unterschiedliche Typen vergleichen?
Entweder ist
"0" != 0.0
oder
0 == "foo"fuer eins musst du dich entscheiden.
Kann ich nicht nachvollziehen. Ich sehe keine Notwendigkeit "foo" den numerischen Wert 0 zu verpassen. Man hätte den Vergleich 0 == "bar" besser einfach negativ ausfallen lassen sollen und von mir aus 0 == "0" positiv. Aber etwas, was offenkundig keine Zahl ist, einfach den Wert 0 zu verpassen, finde ich reichlich seltsam. Falls ich jetzt einfach grad nur nicht mitkomme, dann erklär mir doch bitte etwas ausführlicher, warum das nötig/praktikabel ist.
Diese Sprache ist damit mit der Logik (und ich rede hier nicht von meiner Logik, sondern der formal korrekten Logik) nicht greifbar.
Was natuerlich nicht stimmt. Weil du von falschen voraussetzungen ausgehst.
Wieso? Ich bin von der Dokumentation ausgegangen, die etwas mit "Gleichheit" verspricht. Also bin ich von Gleichheit ausgegangen und das ist definiert. Dabei spielt es keine Rolle, wie die Prüfung in der Praxis durchgeführt wird. Ob wie in Java Referenzen verglichen werden (was ja eigentlich eine Identitäsprüfung ist, aber genauso transitiv), wie bei std::string der Inhalt oder ob es überhaupt keine Typen gibt wie in PHP spielt dabei keine Rolle. Der Begriff Gleichheit ist viel abstrakter definiert und beschreibt nur das Verhalten der Relationen. Und wie gesagt, ich habe noch nirgendwo gesehen, dass das verletzt wird.
Und mich stört sowas, wenn ein op== keine Äquivalenzrelation ist.
Mich nicht, und?
Nichts und. Das ist doch sehr schön, dass es dich nicht stört.
Trotzdem darf ich ja wohl sagen, dass es mich schon stört.
-
Optimizer schrieb:
Gleichheit ist eine mathematisch definierte Äquivalenzrelation und ich kenne sonst keine Sprache, die das verletzt.
in C++ ergibt "Hallo" == "Hallo" && "Hallo" == "Hallo" auch nicht zwingend true.
In PHP ist einfach das abstraktionslevel höher. Der Variablen-Typ ist uninteressant.
Also 10 == 10.0 == "0010" == "zehn". Jenachdem wie mans interpretiert.In anderen Sprachen baut man sich das uU. mit wilden Verrenkungen nach.
-
DrGreenthumb schrieb:
Optimizer schrieb:
Gleichheit ist eine mathematisch definierte Äquivalenzrelation und ich kenne sonst keine Sprache, die das verletzt.
in C++ ergibt "Hallo" == "Hallo" && "Hallo" == "Hallo" auch nicht zwingend true.
In PHP ist einfach das abstraktionslevel höher. Der Variablen-Typ ist uninteressant.
Also 10 == 10.0 == "0010" == "zehn". Jenachdem wie mans interpretiert.In anderen Sprachen baut man sich das uU. mit wilden Verrenkungen nach.
Da wirfst du aber gerade zwei Dinge zusammen. Um es gleich vorweg zu nehmen: Ich bin schon die ganze Zeit auf der höchstmöglichen Abstraktionsebene.
Der Typ interessiert mich auch nicht.
In deinem C++ Beispiel vergleichst du nicht die Strings. Mehr gibt es dazu nicht zu sagen. Sei a, b, c vom Typ const char*:
a == b und b == c
a == c
Das ist auch in C++ so. Wenn die Adressen jeweils gleich sind hat auch a und c die selbe Adresse.
Deine ganzen "Hallo"s müssen aber nicht die selbe Adresse haben. Wie du Gleichheit feststellst ist völlig egal, es muss nur die Transitivität stimmen und das tut sie, wenn
- std::strings vergleichst
- const char* vergleichstBei deinem "Hallo" kennst du aber die Adresse (also den Wert, den du vergleichst) gar nicht also kannst du schlecht ne Aussage machen.
-
Optimizer schrieb:
a == b und b == c
a == c
Das ist auch in C++ so.in PHP nicht? Anhand der PHP-Kenntnisse die ich in diesem Thread gewonnen habe, sehe ich kein problem.
"abc" == 0
true
"xyz" == 0true
"abc" == "xyz"false
macht schon keinen Sinn mehr. Der Vergleichsoperator ist damit nicht transitiv.kannst du diese Variablen in dein Beispiel einsetzen?
-
Ja:
"abc" == 0 und 0 == "xyz"
"abc" == "xyz"
Die Folgerung funktioniert aber in PHP nicht, liefert also false, obwohl die beiden Vorausetzungen true geliefert haben. Dass der op== in PHP sich nicht transitiv verhält, bestreitet ja Shade auch nicht. Ihn stört es nur nicht, mich halt schon. Das heißt natürlich nicht, dass ich für "abc" == "xyz" true haben will, sondern mich stört natürlich das ... == 0.
Aber egal, das hab ich ja jetzt gesagt und das darf jeder finden wie er will.