2010-09-30 12 views
10

Wiele języków programowania zawiera już złożone instrukcje: +=, -=, /= itd. Stosunkowo nowym stylem programowania jest "łańcuchowe" wywoływanie metod na siebie nawzajem, np. w Linq, JQuery i ORM Django.Dlaczego nie ma "instrukcji połączenia metody złożonej", tj. ". ="?

ja czasami częściej niż chciałbym, znaleźć trzeba to zrobić w Django:

# 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') 

myślę, że byłoby łatwiej i faktycznie bardziej czytelny, jeśli nie było oświadczenie metoda związek takie wezwanie jak .= które mogłyby działać tak:

items = Items.objects.filter(desc__startswith='A') 
if something: 
    items .= filter(desc__endswith='Z') 
  • czy istnieją jakieś języki programowania, które obsługują to lub coś podobnego?
  • Jeśli odpowiedź brzmi "nie", dlaczego nie?
  • Czy ten styl programowania jest naprawdę nowy?
  • Czy są jakieś PEP (Propozycje ulepszeń Pythona), które obsługują ten pomysł?
+0

Czy to dla mnie, czy to brzmi jak wspólnota wiki? –

+0

@Cristian Ciupitu: Tak, więc to zmieniłem. –

+0

Zawsze zadziwia mnie to, że programiści zachowują się tak, jakby pisanie było największą częścią ich pracy, więc zapisanie nawet trzech naciśnięć klawiszy jest warte dodania nieprzejrzystej składni z wątpliwą semantyką. –

Odpowiedz

0

Kolekcje Scali obsługują operacje na miejscu, pod warunkiem, że zmienna to var.

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) 

(Dla tych, którzy znają Scala, :: to metoda List)

Jest to styl programowania, że ​​wiele unikać, aw Scala można uniknąć takiej mutacji w miejscu za pomocą niezmiennej val 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

Jego pytanie dotyczy w szczególności operatora połączeń wewnętrznych. – missingfaktor

+0

Zapytał: "Czy są jakieś języki programowania, które obsługują to * lub coś w tym stylu *?". Chociaż nie jest operatorem (jest to cukier dla kompilatora) i dotyczy tylko metod, które nie zawierają znaków alfanumerycznych, powiedziałbym, że wystarczy, aby uzasadnić wymienienie. –

1

IMHO, nie lubię go.

sobie wyobrazić to,

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

to nie jest błąd składni anymore, ale to nie ma sensu, prawda?

mogę powiedzieć, że to nie ma sensu, po prostu dlatego, że jeśli poszerzyć moim przykładem, byłoby tak,

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

items.click(function(){...}); po prostu zwrócić przedmiot items, i przypisać go do items?

w tym przykładzie

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

byłoby sensowne, ale nie jest prawdą, do wszystkich obiektów, może to jest przyczyną tego, że nie został zrealizowany.

co do parent .= children();, co stanie się z parent w późniejszym czasie na kodach?

Mówię w sposób jQuery.

+0

Hmm, ma dla mnie sens. Może mógłbyś wyjaśnić, dlaczego to nie ma sensu? –

+0

Wyjaśnij najpierw, dlaczego linia ta miałaby dla ciebie sens? – Reigel

+0

Ma to dla mnie sens, ponieważ dla mnie byłby to odpowiednik 'items = items.click (function() {...});" który jest prawidłowym JQuery, prawda? –

1

Nie mogę odpowiedzieć na te pytania i nie jestem pewien, co o tym sądzę, ponieważ nie widziałem tego wcześniej, ale ma on interesującą aplikację: wszyscy lokalni operatorzy stają się przestarzali.

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

Oczywiście, to jaśniej napisać a += 1, ale jeśli ta składnia przyszedł wcześniej w konstrukcji języka, a metody __add__ były mniej brzydki (np. Tylko add), dzisiaj język może mieć jedenaście mniej operatorów dzisiaj.

(Oczywiście, nie byłoby inne implikacje, że - w szczególności automatyczne awaryjna od __iadd__ do __add__ byłoby stracone Mimo to ciekawa koncepcja.).

+5

(Ta strona jest od czasu do czasu po prostu głupia Dlaczego wprowadzam mnie do captcha? Czy nie korzystałem z witryny wystarczająco, aby udowodnić, że jestem prawdziwym użytkownikiem?) –

2

ta jest obsługiwana w Perl 6.

+2

to kolejny powód, aby nie zadzierać z perłą . Ja się ... Nie szukam ich. Po prostu wpadają mi na kolana. – aaronasterling

+0

@AaronMcSmooth: +1, ale jest napisane Perl. –

+0

o to kłopotliwe. jeden z tych literówek, na przykład gdy wpisuję "f" zamiast 5. Tylko żałuję, że nie mogę edytować ... – aaronasterling

0

Często o tym myślałem, robiąc programowanie w języku Java lub C#, w którym powtarzają się nie tylko jedno, ale często te same dwa lub więcej odwołań do obiektów po obu stronach zadania - np. Masz członka jakiegoś obiekt będący ciągiem znaków i chcesz wywołać niektóre metody w tym łańcuchu i przypisać je do zmiennej składowej. Co dziwne, nie przeszkadza mi to prawie tak często w Pythonie.

Proponowany operator .= to jeden z pomysłów, o którym myślałem w czasie, gdy robiłem C#. Innym rozwiązaniem byłoby umożliwienie kropką się jako skrót dla obiektu są przypisane w następujący sposób:

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

Pascal, Modula-2, i Visual Basic posiada with oświadczenie (różny od wyciągu Pythona z ta sama nazwa), które pozwalają, aby napisać coś takiego, jeśli istniała w Pythonie (nazywam to „za pomocą” tu więc nie jest mylone ważnego Pythonie):

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

jest to bardzo wygodne, gdy idziesz do robienia wielu manipulacji członkami pojedynczego obiektu, ponieważ pozwala on na blok. Jednak nadal masz poziom redundancji tutaj, które mogłyby zostać wyeliminowane, jeśli łączy dwa ostatnie pomysły tak:

using foo.bar: 
    str = .lower() 

to wydaje mi się, że będzie to ładny kawałek cukru składniowej, a znajdę jest bardzo czytelny, ale nie wygląda na to, że znajduje się wysoko na liście priorytetów większości projektantów językowych. Ponieważ jednak Python ma wpływy Modula-2, być może nie jest wykluczone, że ostatecznie zostanie dodany.

0

Ruby ma tę funkcję w pewien sposób, ale implementuje ją inaczej. Dzieje się to za pomocą "destrukcyjnych" metod, które zmieniają zmienną, na którą są wywoływane. Na przykład wywołanie str.split właśnie zwraca obiekt podzielony, ale go nie zmienia. Ale jeśli zadzwonisz do str.split! zmienia to na miejscu. Większość wbudowanych macierzy i metod łańcuchowych ma niszczycielską i nieniszczącą wersję.

Powiązane problemy