Seite 1 von 1

Kombination von Vergleichsoperatoren

Verfasst: Samstag 10. Januar 2009, 10:23
von numerix
Bekanntlich bietet Python ja das folgende syntaktische Zuckerstückchen:

Code: Alles auswählen

>>> a = 200
>>> if 100 < a < 300:
...     print("Ist drin")
... 
Ist drin
Ich wüsste gern, ob es noch andere Programmiersprachen gibt, wo diese elegante Kombination von Vergleichsoperatoren möglich ist.

Verfasst: Samstag 10. Januar 2009, 11:05
von bremer
Dieser JavaScript-Code funktioniert jedenfalls nicht.

Code: Alles auswählen

<script type="text/javascript">
var a = 200;
if (100 < a < 300) 
{
document.write("<b>Ist drin.</b>");
}
</script>

Re: Kombination von Vergleichsoperatoren

Verfasst: Samstag 10. Januar 2009, 11:36
von Leonidas
numerix hat geschrieben:Ich wüsste gern, ob es noch andere Programmiersprachen gibt, wo diese elegante Kombination von Vergleichsoperatoren möglich ist.
R5RS Scheme kann das:

Code: Alles auswählen

(define a 200)

(if (< 100 a 300)
    (display "Ist drin\n")
    #f)
PLT Scheme Dokumentation hat geschrieben:Returns #t if the arguments in the given order are in strictly increasing, #f otherwise.
Und selbst wenn es nicht gehen würde, dann könnte man sich auf triviale Weise einen Operator schreiben, bei dem es geht.

In Java könnte man das auch machen, da Java kein Operator-Overloading unterstützt würde das gar nicht so exotisch sein. Da wäre es eben eine Methode die Varargs nimmt und jede einzelne prüft. Und ja, es ist hässlich, aber fehlendes Operator-Overloading macht so Code eben hässlich.

Verfasst: Samstag 10. Januar 2009, 11:43
von sma
Perl 6 kann's ebenfalls, so habe ich gerade ergooglet.

Weitere Sprachen fallen mir auf Anhieb nicht ein. Ist jetzt auch kein essentielles Feature.

In vielen Sprachen, bei denen man explizit überschreiben kann, wie ein Objekt als Wahrheitswert gewertet wird, würde man es selbst implementieren können. Scala fiele mir ein. C++ müsste eigentlich auch gehen. Hier das Äquivalent in Python - "LT" sei die primitive Operation für den Vergleich:

Code: Alles auswählen

class int:
    def __lt__(self, other):
        return ChainedOp(LT, self, other)

class ChainedOp:
    def __init__(self, op, a, b):
        self.op, self.a, self.b = op, a, b
    
    def __lt__(self, other):
        return self and ChainedOp(LT, self.b, other)
    
    def __nonzero__(self):
        return self.op(self.a, self.b) 
Stefan

Verfasst: Samstag 10. Januar 2009, 13:20
von sebastinas
sma hat geschrieben:C++ müsste eigentlich auch gehen.
``a < b < c`` wäre zwar gültiger Syntax, aber es wird nicht das heraus kommen, was du dir erwartest.

10 < 20 < 30: true
20 < 10 < 30: true
30 < 20 < 10: true
10 < 20 < -10: false
usw.

Da zuerst der linke Operator ausgewertet wird und dann true bzw. false mit der anderen Zahl verglichen wird.
Um sowas zu ermöglichen müsste man sich eigene Datentypen definieren und die Vergleichsoperatoren entsprechend überschreiben. Aber das endet wohl in einem schirchen Hack.

Verfasst: Samstag 10. Januar 2009, 13:22
von BlackVivi
bremer hat geschrieben:Dieser JavaScript-Code funktioniert jedenfalls nicht.

Code: Alles auswählen

<script type="text/javascript">
var a = 200;
if (100 < a < 300) 
{
document.write("<b>Ist drin.</b>");
}
</script>
Bei mir schon oO Ohne Probleme...

Opera Version 9.52
Windows XP SP3
...der rest ist wohl nicht so relevant, oder?

Verfasst: Samstag 10. Januar 2009, 13:26
von Trundle
@BlackVivi: Nein, es funktioniert nicht. Es ist gültige Syntax, ist aber gleichbedeutend mit (100 < a) < 300. Mach halt mal ``1 < 2 < 2``, das ergibt wahr, was es aber nicht sollte (bzw. was du nicht wolltest. Sollen tut es das schon). Syntaktisch erlaubt ist das in recht vielen Sprachen.

Verfasst: Samstag 10. Januar 2009, 13:37
von BlackVivi
Trundle hat geschrieben:@BlackVivi: Nein, es funktioniert nicht. Es ist gültige Syntax, ist aber gleichbedeutend mit (100 < a) < 300. Mach halt mal ``1 < 2 < 2``, das ergibt wahr, was es aber nicht sollte (bzw. was du nicht wolltest. Sollen tut es das schon). Syntaktisch erlaubt ist das in recht vielen Sprachen.
Nagut, soweit hab ich wohl diesmal gar nicht gedacht. Danke für die Info :)

Verfasst: Samstag 10. Januar 2009, 15:44
von Darii
sebastinas hat geschrieben:
sma hat geschrieben:C++ müsste eigentlich auch gehen.
``a < b < c`` wäre zwar gültiger Syntax, aber es wird nicht das heraus kommen, was du dir erwartest.
sma hat doch geschrieben, dass man es selbst implementieren müsste.

Verfasst: Samstag 10. Januar 2009, 15:54
von numerix
Ich fasse mal zusammen, was jetzt herausgekommen ist, wenn ich es richtig verstanden habe:
- Es gibt einige Sprachen, wo so etwas syntaktisch möglich ist, aber anders ausgewertet wird als der entsprechende Ausdruck in Python.
- Es gibt einige Sprachen, wo so etwas selbst implementierbar wäre.
- In Perl 6 und Scheme gibt es standardmäßig eine dem Python-Ausdruck entsprechende Möglichkeit. Zumindest die Scheme-Syntax ist aber für jemanden, der die Sprache nicht beherrscht, nicht so intuitiv erfassbar wie die Darstellung in Python. (Da ich Perl nicht beherrsche, weiß ich nicht, wie es da aussieht; der Perl-Code, den ich bisher gesehen habe, lässt mich aber vermuten, dass hinsichtlich der intuitiven Erfassbarkeit ähnliches gilt wie für Scheme).

Verfasst: Sonntag 11. Januar 2009, 10:01
von sma
sebastinas hat geschrieben:
sma hat geschrieben:C++ müsste eigentlich auch gehen.
``a < b < c`` wäre zwar gültiger Syntax, aber es wird nicht das heraus kommen, was du dir erwartest.
Missverständnis: Ich meinte, es müsste gehen, den < Operator wie gezeigt zu überschreiben. Dass das so nicht geht, ist klar.

Stefan

PS: Die Scheme-Syntax finde ich sehr lesbar, denn das (< 1 2 3) ist nur konsequent, wenn es ein (+ 1 2 3) gibt.

Verfasst: Sonntag 11. Januar 2009, 12:03
von Leonidas
sma hat geschrieben:PS: Die Scheme-Syntax finde ich sehr lesbar, denn das (< 1 2 3) ist nur konsequent, wenn es ein (+ 1 2 3) gibt.
Ja, ich auch. Ist einfach der "Steigt streng monoton"-Operator. Wenn ich die HyperSpec richtig lese dann ist bei Common Lisp genau das selbe möglich - ist ja auch logisch. Ein kurzer Test in Clojure hat gezeigt, dass es dort ebenfalls möglich ist. Daher kann man Annehmen, dass dies ein durchaus populäres Feature der Lisp-Familie ist.