2010-09-30 5 views
10

Viele Programmiersprachen haben bereits die zusammengesetzten Anweisungen +=, -=, /= usw. Ein relativ neuer Programmierstil besteht darin, Methodenaufrufe miteinander zu "ketten", z. in Linq, JQuery und Djangos ORM. manchmalWarum gibt es keine "Compound Method Call Statement", d. H. ". ="?

ich öfter als ich möchte, finden die Notwendigkeit, diese in Django zu tun:

# Get all items whose description beginning with A 
items = Items.objects.filter(desc__startswith='A') 
if something: 
    # Filter further to items whose description also ends with Z 
    items = items.filter(desc__endswith='Z') 

ich denke, es wäre einfacher, und tatsächlich besser lesbar, wenn es eine Verbindung Methodenaufruf Aussage war so wie .= könnte, die wie folgt funktionieren:

items = Items.objects.filter(desc__startswith='A') 
if something: 
    items .= filter(desc__endswith='Z') 
  • gibt es Programmiersprachen, die dies oder etwas ähnliches zu unterstützen?
  • Wenn die Antwort nein ist, warum nicht?
  • Ist diese Art der Programmierung wirklich so neu?
  • Gibt es PEPs (Python Enhancement Proposals), die diese Idee unterstützen?
+0

Ist es für mich oder das klingt wie ein Community-Wiki? –

+0

@Cristian Ciupitu: Es tut, also habe ich es geändert. –

+0

Es erstaunt mich immer wieder zu sehen, wie Programmierer so tun, als ob Tippen der größte Teil ihrer Arbeit wäre, so dass es sich lohnt, undurchsichtige Syntax mit fragwürdiger Semantik hinzuzufügen, um sogar drei Tastenanschläge zu sparen. –

Antwort

0

Die Scala-Sammlungen unterstützen direkte Operationen, vorausgesetzt, dass die Variable var ist.

scala> var L = List("b", "c") 
L: List[java.lang.String] = List(b, c) 

scala> L ::= "a" 

scala> L 
res8: List[java.lang.String] = List(a, b, c) 

(Für diejenigen, die nicht mit Scala, ist :: ein Verfahren zur Herstellung List)

Dies ist eine Art der Programmierung, dass viele zu vermeiden, und in Scala Sie eine solche in-Place-Mutation unter Verwendung von unveränderlichen val vermeiden können s:

scala> val L = List("b", "c") 
L: List[java.lang.String] = List(b, c) 

scala> L ::= "a" 
<console>:7: error: reassignment to val 
     L ::= "a" 
+0

Seine Frage bezieht sich speziell auf In-Place-Call-Operator. – missingfaktor

+0

Er fragte: "Gibt es Programmiersprachen, die dies * oder etwas ähnliches unterstützen?". Obwohl es kein Operator ist (es ist Zucker für den Compiler) und es betrifft nur Methoden, die keine alphanumerischen Zeichen enthalten, würde ich sagen, dass es genug ist, um es zu erwähnen. –

1

IMHO, ich mag es nicht.

nur das vorstellen,

items .= click(function(){...}); 

es ist keine Syntaxfehler mehr, aber es macht keinen Sinn, nicht wahr?

ich sagen kann, es nicht sinn einfach macht, denn wenn Sie mein Beispiel erweitern, es so sein würde,

items = items.click(function(){...}); 

items.click(function(){...}); zurückkehren würde nur das Objekt items, und Sie werden es zu items zuweisen?

in diesem Beispiel

items .= filter(desc__endswith='Z'); 

wäre es sinnvoll, sondern für alle Objekte nicht wahr ist, ist vielleicht, dass der Grund, warum es nicht umgesetzt wurde.

als parent .= children();, was passiert mit parent später auf die Codes?

Ich spreche jQuery Weg.

+0

Hmm, macht Sinn für mich. Vielleicht könntest du erklären, warum es keinen Sinn ergibt? –

+0

Erklären Sie zuerst, warum diese Linie für Sie Sinn macht? – Reigel

+0

Es macht Sinn für mich, denn das wäre das Äquivalent von 'items = items.click (function() {...});' was ist gültig JQuery, nicht wahr? –

1

Ich kann diese Fragen nicht beantworten, und ich bin nicht sicher, was ich davon halte, weil ich es vorher nicht gesehen habe, aber es hat eine interessante Anwendung: alle Inplace-Operatoren werden obsolet.

a = 1 
a .= __add__(1) 
a .= __mul__(2) 

Natürlich ist es klarer a += 1 zu schreiben, aber wenn diese Syntax früher in der Gestaltung der Sprache gekommen war, und die __add__ Methoden waren weniger hässlich (z. B. nur add), könnte die Sprache heute elf weniger Betreiber heute.

(Natürlich wäre es auch andere Auswirkungen, dass sein - insbesondere der automatische Ausweich __iadd__-__add__ verloren gehen würde Dennoch ist es ein interessantes Konzept..)

+5

(Diese Seite ist von Zeit zu Zeit einfach dumm. Warum lässt man mich ein Captcha eingeben? Habe ich die Seite nicht genug benutzt, um zu beweisen, dass ich ein richtiger Benutzer bin?) –

2

Diese in Perl 6 unterstützt wird.

+2

Noch ein Grund, sich nicht mit Perlen zu beschäftigen . Ich gehe nicht nach ihnen suchen. Sie fallen mir einfach in den Schoß. – aaronasterling

+0

@AaronMcSmooth: +1, aber es ist Perl geschrieben. –

+0

oi das ist peinlich. einer dieser Tippfehler wie wenn ich 'f' anstelle von 5 tippe. Ich wünschte nur, ich könnte bearbeiten ... – aaronasterling

0

Ich habe oft darüber nachgedacht, wenn ich Java- oder C# -Programmierung mache, wo Sie nicht nur eine, sondern oft zwei oder mehr Objektreferenzen auf beiden Seiten der Aufgabe wiederholen - zB haben Sie ein Mitglied von einigen Objekt, das eine Zeichenfolge ist, und Sie möchten einige Methoden für diese Zeichenfolge aufrufen und sie der Mitgliedsvariablen zuweisen. Seltsamerweise hat es mich in Python nicht so sehr gestört.

Der Operator .=, den Sie vorschlagen, ist eine Idee, an die ich zu der Zeit dachte, als ich C# machte. Eine weitere Möglichkeit wäre, einem führenden Punkt zu erlauben, als eine Abkürzung für das Objekt zugewiesen wird, wie folgt aus:

foo.bar.str = .lower() # same as foo.bar.str = foo.bar.str.lower() 

Pascal, Modula-2 und Visual Basic eine with Aussage (abweichend von Python Aussage der gleiche Namen), die Sie so etwas zu schreiben erlauben würden, wenn es in Python existiert (ich nenne es „mit“ hier, damit es nicht verwechselt gültigem Python ist):

using foo.bar: 
    str = str.lower() # same as foo.bar.str = foo.bar.str.lower() 

Dies ist sehr praktisch, wenn Sie gehen viel Manipulation von Mitgliedern eines einzelnen Objekts, da es eine Blockierung erlaubt. Sie haben jedoch weiterhin ein hohes Maß an Redundanz hier, die beseitigt werden könnte, wenn man die letzten beiden Ideen wie so kombiniert:

using foo.bar: 
    str = .lower() 

Das ist mir scheint, wie es ein schönes Stück syntaktischer Zucker wäre, und ich finde, Es ist sehr gut lesbar, aber es scheint nicht so, dass es auf der Prioritätenliste der meisten Sprachdesigner steht. Da Python jedoch Modula-2-Einflüsse hat, ist es vielleicht nicht ausgeschlossen, dass es irgendwann hinzugefügt wird.

0

Ruby hat diese Funktion in gewisser Weise, implementiert sie aber anders. Dies geschieht durch 'destruktive' Methoden, die die Variable verändern, an der sie aufgerufen werden. Wenn Sie beispielsweise str.split aufrufen, wird nur die Objektaufteilung zurückgegeben, sie wird jedoch nicht geändert. Aber wenn du str.split anrufst! es ändert es an Ort und Stelle. Die meisten eingebauten Array- und String-Methoden haben eine destruktive und nicht-destruktive Version.

Verwandte Themen