Jakich pięciu nienawidzisz w swoim ulubionym języku? [Zamknięte]


403

Ostatnio na Stack Overflow pojawiła się grupa Perl-hate, więc pomyślałem, że przyniosę moje pytanie „ Pięć rzeczy, których nienawidzisz w swoim ulubionym języku ” do Stack Overflow. Wybierz swój ulubiony język i powiedz mi pięć rzeczy, których w nim nienawidzisz. Mogą to być rzeczy, które Cię denerwują, przyznają się do wad projektowych, rozpoznanych problemów z wydajnością lub dowolnej innej kategorii. Musisz go tylko nienawidzić, a to musi być twój ulubiony język.

Nie porównuj go do innego języka i nie mów o językach, których już nienawidzisz. Nie mów o tym, co lubisz w swoim ulubionym języku. Chcę tylko usłyszeć rzeczy, których nienawidzisz, ale tolerujesz, abyś mógł używać wszystkich innych rzeczy i chcę usłyszeć o języku, który chciałbyś, aby inni ludzie używali.

Pytam o to, ilekroć ktoś próbuje narzucić mi swój ulubiony język, a czasem jako pytanie do rozmowy kwalifikacyjnej. Jeśli ktoś nie może znaleźć pięciu rzeczy, których nienawidziłby w swoim ulubionym narzędziu, nie zna go wystarczająco dobrze, aby go popierać lub czerpać z niego duże dolary. Nie używał go w wystarczająco różnych sytuacjach, aby w pełni go zbadać. Opowiada się za kulturą lub religią, co oznacza, że ​​jeśli nie wybiorę jego ulubionej technologii, się mylę.

Nie obchodzi mnie, jakiego języka używasz. Nie chcesz używać określonego języka? Więc nie rób tego. Czy dokładasz należytej staranności, aby dokonać świadomego wyboru i nadal go nie używasz? W porządku. Czasami właściwa odpowiedź brzmi: „Masz silny zespół programistów z dobrymi praktykami i dużym doświadczeniem w barze. Zmiana na Foo byłaby głupia”.


To dobre pytanie również dla recenzji kodu. Ludzie, którzy naprawdę znają bazę kodów, będą mieli na nią różne sugestie, a ci, którzy nie znają jej tak dobrze, mają niespecyficzne skargi. Pytam takie rzeczy, jak: „Gdybyś mógł zacząć od nowa w tym projekcie, co zrobiłbyś inaczej?” W tej fantastycznej krainie użytkownicy i programiści mogą narzekać na wszystko i wszystko, czego nie lubią. „Chcę lepszego interfejsu”, „Chcę oddzielić model od widoku”, „Użyłbym tego modułu zamiast tego drugiego”, „Zmieniłbym nazwę tego zestawu metod” lub cokolwiek, co oni naprawdę robią podoba mi się obecna sytuacja. W ten sposób rozumiem, ile konkretny programista wie o bazie kodu. To także wskazówka na temat tego, ile programistów

Nienawiść nie jest jedynym wymiarem, aby dowiedzieć się, ile ludzi wie, ale uważam, że jest całkiem niezły. Rzeczy, których nienawidzą, dają mi również wskazówkę, jak dobrze myślą na ten temat.


11
To naprawdę miłe spostrzeżenie na stare pytanie „Twój ulubiony język”. Dobre uzasadnienie.
Tom Leys,

14
Interesujące jest dla mnie to, że pomimo SO posiadającego dużą grupę odbiorców .NET, w chwili pisania tego tekstu są 24 odpowiedzi, z których tylko jedna (moja) dotyczy .NET lub języka .NET. Nie mam pojęcia, co to mówi o SO lub .NET, ale to ciekawe ...
Jon Skeet,

22
Przez pierwsze 15 lat programowania w C / C ++ nienawidziłem (w kolejności alfabetycznej): 1. Wskaźniki 2. Wskaźniki 3. Wskaźniki 4. Wskaźniki 5. Wskaźniki
ileon

4
Zastanawiam się, ile osób skomentowało nienawiść do wybranego przez siebie języka, ponieważ nie rozumieli, jak programować w swoim wybranym języku ....
Kris.Mitchell

3
To fantastyczne pytanie. Jeśli zastanawiasz się, jak wygląda jakiś język, przeczytanie 3 różnych odpowiedzi na ten temat na tej stronie byłoby najłatwiejszą dostępną przydatną informacją. Jest to także świetny sposób na ocenę poziomu doświadczenia programisty (i pokory), jeśli znasz już język.
j_random_hacker

Odpowiedzi:


182

Pięć rzeczy, których nienawidzę w Javie:

  • Brak pierwszorzędnych funkcji.
  • Bez wnioskowania o typie.
  • Brak rozsądnych ustawień domyślnych np. Grafiki.
  • NullPointerException nie zawiera więcej informacji o tym, co jest null.
  • Rozpowszechnianie niepotrzebnie „konfigurowalnych” platform / interfejsów usługodawców / klas fabrycznych / systemów wstrzykiwania zależności. Konfigurowalność prawie nigdy nie jest używana, DRY jest poważnie naruszane, a kod czterokrotnie zwiększa rozmiar, a połowa czytelności.

Wiem, że powinienem sprawdzić Scalę.


7
@both: NPE jest pokazany w pierwszym wierszu transu stosu. Zawiera (przez większość czasu) klasę, nazwę pliku Java i numer wiersza, takie jak: „at your.faulty.code.Instance (Intance.java:1234)” Następnie wystarczy otworzyć ten plik, przejść do tego wiersza i tam to zmienna, do której nie przypisano niczego.
OscarRyz

35
@Oscar Reyes - Er, wiemy o tym. Ale w tym wierszu może znajdować się wiele zmiennych, a komunikat wyjątku nie mówi mi, która z nich jest pusta.
Zarkonnen

10
Scala ma również brodawki. Jest jednak znacznie lepszy niż Java.
pszenicy

10
+1 za proliferację zrębów itp.
Erich Kitzmueller

6
@ Valentin, wyobraź sobie zabawę z wyjątku NullPointerException znajdującego się w gigantycznym pliku dziennika z nocnego biegu i musisz dowiedzieć się, co się stało ... Debugowanie nie jest opcją.
Thorbjørn Ravn Andersen

216

Wow, jestem zaskoczony, że SQL jeszcze go nie wymyślił. Zgadnij, co oznacza, że ​​nikt go nie lubi :)

  • Niespójna składnia we wszystkich implementacjach
  • Subtelne różnice w kodzie mogą mieć ogromny wpływ na wydajność z pozornie niejasnych powodów
  • Słaba obsługa manipulacji tekstem
  • Łatwy koszt wejścia, ale stroma krzywa uczenia się w kierunku opanowania języka
  • Minimalna standaryzacja w całej społeczności dla najlepszych praktyk, w tym styl składni.

... I kilka dodatkowych powodów, aby go nienawidzić, bez dodatkowych opłat

  • klauzula WHERE jest ostatnia, co ułatwia przedwczesne wykonanie UPDATE lub DELETE, niszcząc całą tabelę. Zamiast tego GDZIE powinien iść gdzieś z przodu.
  • Trudno jest wdrożyć podział relacyjny.
  • Mogę ustawić wartość na NULL, ale nie mogę przetestować jej pod kątem równości z NULL. Mogę sprawdzić IS NULL, ale to tylko komplikuje kod - niepotrzebnie, moim zdaniem.
  • Dlaczego musimy całkowicie ponownie określić formułę dla kolumny Zgrupowanej, zamiast ustawiać alias w kolumnie, a następnie GROUP BY według aliasu (lub indeksu kolumny jak w przypadku SORT)?

7
Może nikt nie może nauczyć się go kochać, dopóki nie przestanie myśleć o nim jako o języku. :)
Alan Moore

4
+1 za wszystko. A jednak ludzie zastanawiają się, dlaczego
znoszę

2
@Alan M ... czy to nie to, co oznacza L? :)
Kev,

29
Nie rozumiem, dlaczego składnia INSERT jest tak różna od UPDATE. A MERGE jest niezrozumiały.
LaJmOn

3
Konieczność IS NULL powinna być jasna, jeśli weźmiesz pod uwagę, że NULL jest trzecim możliwym wynikiem, zaraz po PRAWDZIE i FAŁSZ. Ponieważ jego znaczenie jest „nieznane”, nie można stwierdzić, czy coś, co jest nieznane, pasuje również do innej rzeczy, która jest nieznana. Kolejny przykład: jeśli NULL jest równy NULL, oznaczałoby to, że cała koncepcja tworzenia JOINÓW byłaby niemożliwa, ponieważ dowolną wartość NULL można by dopasować do innej wartości NULL. Jeśli to rozumiesz (co nazywa się również logiką trójskładnikową), możesz zrozumieć powód wprowadzenia operatora „IS” do testowania pod kątem wartości NULL.
Alex

159

JavaScript :

  1. Wszystkie najfajniejsze rzeczy są niesamowicie skomplikowane, ale cały ten chłód jest również zamknięty w tak niewielkiej ilości kodu, że czujesz się głupio, gdy próbujesz go przestrzegać

  2. „+” to absurdalny wybór operatora do konkatenacji w słabo napisanym języku. Czy oni próbowali odstraszyć nooby?

  3. To pole minowe kompatybilności z różnymi przeglądarkami (nieważne, czy jest włączone, czy nie)

  4. Jest to na ogół niezaufane - związane z takimi zabawkami, jak blokowanie przycisku Wstecz, wyskakujące okienka, które nigdy nie umierają itp.

  5. Debugowanie jest prawie niemożliwe, ponieważ istnieje tylko kilka różnych komunikatów o błędach i kilka różnych typów (liczba, ciąg, obiekt itp.)

Gdyby nie jQuery, prawdopodobnie nadal bym go nienawidził tak jak kiedyś :)


15
Zgadzam się z Mausch. ECMAscript sam w sobie jest pięknym i potężnym językiem. To nieznośne przeglądarki (: kaszel: IE), które zmieniają jego nazwę.
TJ L

32
@Mausch: gdzie mieszka javascript w zdecydowanej większości przypadków? Mówisz, że odpowiednik „samochodów nie przyczynia się do globalnego ocieplenia, to napędza samochody, które to robią” - oczywiście, ale nie rozumiem - co jeszcze robisz z samochodem?
jTresidder

20
@Chris: Tak, „+” jest dobrym operatorem do konkatenacji w silnie typowanym języku (jak Python). W słabo wpisanym języku (jak Javascript lub C) jest to okropne; decyduje (po cichu!), że „suma: + 2 + 3 nie jest„ sumą: 5 ”, ale„ sumą: 23 ”. Ktoś z większym doświadczeniem Javascript może podać lepsze przykłady.
ShreevatsaR

5
Tak, C jest słabo wpisany w porównaniu do, powiedzmy, Pythona (np. Możesz przypisać liczby całkowite do chars, rzucić wszystko na cokolwiek za pomocą wskaźników void * itp.) Jest wpisywany statycznie zamiast dynamicznie , a także wymaga jawnego pisania zamiast wnioskowanie typu, ale nie są one związane z silnym słabym typowaniem v / s. [Przypadkowe przykłady: Python zawiera ukryte dynamiczne pisanie silne, Haskell (opcjonalnie jawne) statyczne pisanie silne, Java ma wyraźne (głównie statyczne) mocne pisanie, C ma wyraźne pisanie statyczne (stosunkowo słabe).] „Mocne pisanie” i „słabe pisanie „nie są właściwie dobrze zdefiniowane.
ShreevatsaR

5
@ShreevatsaR Klasycznym przykładem jest: '3'+'2'='32', '3'-'2'=1.
Thomas Ahle

148

PHP:

1) Zmusza mnie do tworzenia niepotrzebnych zmiennych:

$parts = explode('|', $string);
$first = $parts[0];

2) Wdrożenie lambdas tak kiepskie, że z grubsza jest równoważne z używaniem eval()i tak strasznie złe, że nigdy go nie użyłem (patrz http://www.php.net/create_function ).

3) System try / catch, który może wykryć tylko około 80% błędów, które mogą wystąpić.

4) Wsparcie Regex tak samo kiepskie jak wsparcie lambda, ponieważ musi być napisane w regularnych ciągach, co czyni jedno z najtrudniejszych do nauczenia się narzędzi programistycznych około trzy razy trudniejszym. A PHP ma być „łatwym” językiem?!?!?

5) Nie ma sposobu na bezpieczne wyciągnięcie rzeczy z $ _POST bez dwukrotnego napisania lub zbudowania własnej funkcji lub użycia operatora „@”:

$x = isset($_POST['foo']['bar']) ? $_POST['foo']['bar'] : null;

6) Dodatkowa odpowiedź: „@”. Jeśli nie możesz niepokoić się poprawnym pisaniem kodu, po prostu dodaj „@”, a szkoda dla każdego, kto będzie później musiał debugować kod.


44
co z listą ($ first) = explode ('|', $ string); ?
mlarsen,

44
Idealnie chciałbym użyć some_function (explode ('|', $ string) [0]);
za dużo php

8
Jaki dziwny zakres zmiennych? Posiadanie wszystkiego lokalnego i zmuszanie cię do zadeklarowania, kiedy chcesz użyć globalnego, jest dobrym pomysłem, ponieważ uniemożliwia noobom tworzenie funkcji, które po prostu używają globalnych, zamiast używania argumentów i zwracania wartości tak, jak powinny.
scragar 10.09.2009

24
zapomniałeś o funkcjach z losową zmianą kolejności parametrów
dusoft,

39
Zapomniałeś o verbNoun, verb_noun, noun_verb, nounverb, verbnoun, nounVerb, etc> _>
Warty

135

C ++

  • Zdecydowanie zbyt łatwo jest losowo uszkodzić pamięć i stworzyć prawie niemożliwe do znalezienia błędy (chociaż Valgrind stara się to naprawić).
  • Komunikaty o błędach szablonu.
  • Podczas korzystania z szablonów łatwo jest zakończyć wszystko w jednym pliku, a następnie uzyskać głupie czasy kompilacji.
  • Standardowa biblioteka to żart we współczesnym wieku (domyślnie wciąż brak wątków lub sieci?)
  • Mnóstwo nieprzyjemnych kawałków C przebijających się przez (w szczególności wszystkie konwersje między short / int / unsigned / itp.)

13
Zgadzam się z STL, ale powiem, co to jest dobra ładna.
Bernard,

22
Unicode. szanuję prostotę ascii, ale na litość boską, jesteśmy już w XXI wieku.
wilhelmtell

29
Poprawność @Kieveli const jest właściwie jedną z rzeczy, za którymi najbardziej tęsknię podczas programowania w innych językach. szczególnie te dynamiczne. raii to duża funkcja, której często też brakuje.
wilhelmtell

6
Większość problemów z C ++ wynika z bycia standardem ISO i jest zablokowana na 10 lat.
graham.reeds

7
+1 „Komunikaty o błędach szablonu”.
João Portela

129

C # / .NET:

  • Klasy powinny być domyślnie zapieczętowane
  • Nie powinno być lockinstrukcji - zamiast tego powinieneś mieć określone obiekty blokujące i powinny istnieć metody, takie jak Acquirektóre zwracają jednorazowe tokeny blokujące. Następstwo: nie powinno być monitora dla każdego obiektu.
  • GetHashCode()i Equals()nie powinno być w System.Objectśrodku - nie wszystko nadaje się do mieszania. Zamiast mieć IdentityComparerktóry robi to samo, i zachować IComparer<T>, IComparable<T>, IEqualityComparer<T>i IEquatable<T>interfejsy dla niestandardowych porównań.
  • Słabe poparcie dla niezmienności
  • Zły sposób odkrywania metod rozszerzeń - powinna to być o wiele bardziej świadoma decyzja niż sam fakt używania przestrzeni nazw.

Te były poza moją głową - zapytaj mnie jutro, a wymyślę inną 5 :)


22
Domyślnie zapieczętowane: dziedziczenie powinno być albo zaprojektowane do klasy (co wymaga czasu i ogranicza przyszłe opcje), albo zabronione. hashCode / equals: ssie też Javę. Pewnego dnia napiszę o tym długi post na blogu. Przeczytaj Efektywna Java, aby dowiedzieć się, dlaczego łańcuch równości jest trudny w łańcuchach dziedziczenia.
Jon Skeet

88
Opieczętowanie domyślnie oznacza, że ​​pomyślałeś o każdym możliwym powodzie, dla którego ktoś może chcieć odziedziczyć po twojej klasie, i nie uważasz, że którykolwiek z nich ma sens. Przepraszam, ale żaden z nas nie jest taki mądry.
Ed S.

69
W takim przypadku nie jestem wystarczająco inteligentny, abyś mógł czerpać z mojego kodu: ponieważ nie mogę przewidzieć, jakie przyszłe zmiany mogę wprowadzić, co może złamać Twój kod. To bardzo poważny problem, IMO. Uszczelnienie kodu jest bardziej restrykcyjne, ale prowadzi do większej swobody implementacji i niezawodności.
Jon Skeet,

11
Nie mogę uwierzyć, że nikt nie wspomniał o składni „goto case”, nienawidzę tego!
Aistina,

20
To dobrze, że Jon Skeet nie zaprojektował C #, lub moja lista wyglądałaby tak: „1. klasy są domyślnie zapieczętowane; 2. blokowanie jest zbyt skomplikowane; 3. większość obiektów nie jest haszowalna”!
Gabe

113

do

  • manipulacja sznurkiem.

Ręczne radzenie sobie z buforami ciągów jest podatne na błędy. Ponieważ tak dużo obliczeń naprawdę przenosi i modyfikuje ciągi (komputery nie są używane tak często do kruszenia dużych liczb, jak ludzie myśleli, że będą dawno temu), naprawdę fajnie jest móc korzystać z zarządzanych języków lub łańcucha C ++ obiekty do radzenia sobie z nimi. Kiedy muszę to zrobić w prostej linii C, mam wrażenie, że pływam w ruchomych piaskach.


50
Zgoda. Manipulowanie
strunami to pozycje

1
Po prostu użyj bezpiecznej biblioteki ciągów DJB lub czegoś takiego. Manipulacja XML jest trudna w większości języków, a wiele programów wykonuje manipulacje XML, ale nie widać wielu postów mówiących: „Perl jest całkowicie zepsuty, ponieważ nie obsługuje węzłów DOM jako prymitywnego typu danych”. Używają biblioteki.
Steve Jessop,

5
Manipulacja ciągiem C jest do bani, ale jeśli chodzi o problemy językowe, nie jest to najgorsze.
Chris Lutz

3
strcat do konkatenacji, ale poczekaj ... czy miejsce docelowe ma wystarczającą ilość miejsca ... ok, musisz wstawić instrukcję if, aby sprawdzić ... ale poczekaj, co jeśli mój ciąg jest na stosie? Ok, musisz zachować zmienną, aby śledzić rozmiar ... A to może trwać i tak dalej i dalej ...
blwy10,

4
Potrzebujemy wątku na pięć rzeczy, których nie nienawidzimy w C ...
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

94

Co powiesz na pięć rzeczy, których nienawidzę w listach „Rzeczy, których nienawidzę w niektórych językach”? :RE

5- Malowanie pomarańczowej czerwieni nie czyni z niej jabłka.

Podczas projektowania języka projektanci zazwyczaj mają na uwadze to, do czego jest przydatny. Używanie go do czegoś zupełnie innego może działać, ale narzekanie, gdy tak nie jest, jest po prostu głupie. Weź Python. Jestem pewien, że ktoś ma lub ktoś kiedyś stworzy narzędzie do tworzenia plików exe z kodu Python. Dlaczego, na ziemi Bożej, chcesz to zrobić? Byłoby fajnie - nie zrozumcie mnie źle - ale nie ma pożytku. Przestań więc narzekać!

Dobrze zaprojektowany projekt prawdopodobnie zawiera kod z wielu języków. Nie oznacza to, że nie można ukończyć projektu tylko w jednym języku. Niektóre projekty mogą być w zakresie umiejętności dowolnego języka, którego używasz.

4- Czy stoisz na drewnianych nogach?

Platforma może mieć duży wpływ na to, co potrafi język. W dzisiejszych czasach śmieciarze, a nawet paskale wczesna próba „śmieciowania”, mogą pomóc w zanikaniu pamięci (może Malloc więcej pamięci RAM?). Komputery są szybsze i oczywiście oczekujemy więcej od naszych języków. I szczerze mówiąc, prawdopodobnie powinniśmy. Jednak za wygodę kompilatora w tworzeniu tabel mieszających lub ciągów lub za wiele innych koncepcji trzeba zapłacić ogromną cenę. Te rzeczy nie mogą być dziedziczone na platformie, z której są używane. Powiedzieć, że łatwo je dołączyć do języka, po prostu mówi mi, że możesz nie mieć nogi.

3 - Czyja to wina?

Błędy. Wiesz. Uwielbiam robale. Dlaczego kocham błędy. Ponieważ to oznacza, że ​​mogę utrzymać pracę. Bez błędów byłoby wiele zamkniętych sklepów z pizzą. Jednak użytkownicy nie znoszą błędów. Ale tutaj jest odrobina zimnej wody. Każdy błąd jest winą programistów. Nie w języku. Język o tak ścisłej składni, który znacznie zmniejszyłby liczbę możliwych do wygenerowania błędów, byłby całkowicie bezużytecznym językiem. Jego umiejętności można prawdopodobnie policzyć na jednej ręce. Chcesz elastyczności lub mocy? Masz błędy. Dlaczego? Ponieważ nie jesteś doskonały i popełniasz błędy. Weź naprawdę możliwy do zidentyfikowania przykład w C:

int a[10];
for (int idx = 0; idx < 15; idx++) a[idx] = 10;

Wszyscy wiemy, co się stanie. Jednak niektórzy z nas nie zdają sobie sprawy z tego, że ta funkcjonalność może być bardzo korzystna. W zależności od tego, co robisz. Przepełnienia bufora są kosztem tej funkcjonalności. Ten kod powyżej. Jeśli faktycznie opublikowałem to publicznie. To znowu… powiedz to ze mną… „Moja wina”. Nie C za umożliwienie mi tego.

2- Czy nie powinniśmy tego umieszczać w koszu?

Bardzo łatwo jest wskazać funkcję w języku, którego nie rozumiemy, ponieważ nie używamy jej często i nazywamy głupim. Skarż się, że tam jest itp. Goto zawsze mnie bawi. Ludzie zawsze narzekają na goto w języku. Ale założę się, że twój ostatni program zawierał rodzaj goto. Jeśli kiedykolwiek używałeś przerwy lub kontynuacji, użyłeś goto. To jest to. To prawda, że ​​to „bezpieczne” goto, ale takie właśnie jest. Goto mają swoje zastosowania. Czy używane są „niejawne” gotos, takie jak kontynuacja czy przerwa, czy jawne gotos (użycie rzeczywistego słowa kluczowego „goto” dla dowolnego języka). Nie chodzi o to, że twórcy języków są bezbłędni, ale zazwyczaj ... jeśli funkcjonalność istnieje od zarania dziejów (dla tego języka). Prawdopodobnie aspekt ten określa jakość tego języka. Czyli… to ” jest używany i prawdopodobnie nie kręci się z powodu kompatybilności wstecznej. Jest używany dzisiaj. Tak jak 5 minut temu. I używane prawidłowo. No cóż ... prawdopodobnie ktoś również używa go niewłaściwie, ale to odnosi się do # 3 na mojej liście.

1. - Wszystko jest przedmiotem.

Ok .. ten jest naprawdę podzbiorem # 2. Ale to zdecydowanie najbardziej denerwująca skarga, którą widzę na listach nienawiści. Nie wszystko jest przedmiotem. Istnieje wiele koncepcji, które nie należą ani nie muszą być przedmiotami. Umieszczanie rzeczy tam, gdzie nie należą, jest po prostu brzydkie i może obniżyć wydajność programu. Pewnie. Może niewiele w zależności od języka. Dotyczy to również # 5. Oznacza to ... tak. Globalne są w porządku. Funkcje zastosowane w metodach statycznych są prawidłowe. Łączenie programowania OO z funkcjami globalnymi jest w porządku. Teraz .. to nie znaczy, że wszyscy powinniśmy wyjść i „uwolnić” nasz kod od jego modeli obiektowych. Podczas projektowania sekcji kodu lub całego projektu powinno się zdarzyć to, co dzieje się za kulisaminależy wziąć to pod uwagę przy składaniu. Nie tylko tam, gdzie mieszka ta koncepcja i wiele innych czynników. Po co zawijać funkcje globalne w ramach klas lub pojęć przestrzeni nazw, jeśli nie ma to żadnego sensu? Weź statyczne zmienne składowe. To mnie bardzo bawi, ponieważ ... no cóż ... W zależności od języka i implementacji, oczywiście, ale ogólnie mówiąc, właśnie ogłosiłeś, że jest globalny. Tak, istnieje kilka powodów, by łączyć te koncepcje inne niż OO w opakowania OO. Jednym z nich jest oczywiście samodokumentujący się kod. To może mieć sens. Więc ... jak mówię. Nie wychodź i „uwolnij” swój kod. Ale każdy dobry nowoczesny język będzie miał globalną koncepcję poza jego modelowaniem OO. Tak, w szczególności chcę podkreślić, że język programowania OO bez globalnej koncepcji najprawdopodobniej ma poważną wadę projektową. Znów jednak .. zależy od intencji i projektu języka, więc nie próbuję wybierać żadnego konkretnego języka, a tutaj jest o wiele za dużo do przeanalizowania. W każdym razie, zastanów się, gdzie kod powinien mieszkać i być najbardziej skuteczny. Dodanie zestawu rozszerzeń do czegoś, co nie dodaje funkcjonalności ani wsparcia, po prostu szybciej zużywa klawiaturę. To nikomu nie pomaga. No cóż ... chyba że lubisz punkty brownie od osoby, która prawdopodobnie błędnie nauczyła cię, że wszystko jest przedmiotem.

Krótko mówiąc, programowanie to nie tylko bezmyślne stukanie w klawiaturę. Każdy projekt wymaga wielu rozważań projektowych. Wiem, że to banał, ale musisz na to spojrzeć pod każdym kątem. Nawet w dzisiejszych językach bezpiecznych dla czcionek. Nie tylko wyciskasz kod i oczekujesz, że będzie działał dobrze. Jasne ... to może działać, ale może nie być to właściwa droga. Ogólnie wybierz język i format, który najlepiej pasuje do konkretnego zadania ORAZ środowiska. Ale żaden język nie zabiera za to myśli. Jeśli nie myślisz ... po prostu piszesz.


19
Języki nie są idealne, a jeśli zrobisz listę rzeczy, których nienawidzisz w danym języku, możesz uzyskać ciekawe komentarze i pomysły. Po pierwsze, pozwala innym dać ci rozwiązania, o których istnieniu nie wiedziałeś (przejrzyj posty, zobaczysz kilka rzeczy, których się nauczyłeś). Po drugie, stanowi komentarz dla twórców języków (czy nie byłbyś zainteresowany, gdyby twoi użytkownicy wymyślili listę 5 rzeczy, których najbardziej nienawidzą w twoim oprogramowaniu?), A po trzecie, interesujące jest zastanowienie się nad wadami twoich narzędzi.
Sylverdrag,

4
Jeśli zobaczysz to na tym poziomie, nie tylko przerwij i kontynuuj to gotos, ale pętle to gotos (przeskocz początek pętli, jeśli warunek jest spełniony), jeśli jest goto (jeśli warunek nie jest spełniony, przeskocz nad blokiem, wywołania funkcji są goto (przeskocz na początek funkcji, a potem wróć), ...
hel

17
Tworzenie plików wykonywalnych z kodu źródłowego „nie ma sensu”? Co?
detly

4
Perl mógł stworzyć plik wykonywalny z pliku Perla od późnych lat 80-tych. Jedna rzecz do rozpowszechnienia jest przydatna. Nie trzeba a) instalować Perla, b) instalować komponentów programu, c) może napisać skrypt, aby ustawić ścieżki i wykonać to wszystko ... Tak, naprawdę bezużyteczne.
xcramps

1
Ale jeśli nie możesz utworzyć plików .exe ze źródła, użytkownicy systemu Windows nie będą mogli go uruchomić. ;)
Evan Plaice

88

Pięć rzeczy, których nienawidzę w Javie (która jest obecnie moim ulubionym językiem) w żadnej kolejności.

  1. Chociaż jestem fanem Java Generics, istnieje wiele osobliwości, które wynikają ze sposobu, w jaki został zaprojektowany. W związku z tym istnieje mnóstwo irytujących ograniczeń związanych z lekami generycznymi (niektóre z nich wynikają z usunięcia typu).
  2. Sposób działania Object.clone () i Cloneable jest całkowicie zepsuty.
  3. Zamiast podążać drogą i uczynić z wszystkiego wszystko obiekt (a. SmallTalk), Sun stworzył dwie odrębne kategorie typów danych: Obiekty i prymitywy. W rezultacie istnieją teraz dwie reprezentacje podstawowych typów danych i dziwne ciekawostki, takie jak boksowanie / rozpakowywanie, i brak możliwości umieszczania prymitywów w Kolekcji.
  4. Huśtawka jest zbyt złożona. Nie zrozumcie mnie źle: Swing oferuje wiele fajnych rzeczy, ale jest to świetny przykład nadmiaru inżynierii.
  5. Ta ostatnia skarga jest zarówno winą firmy Sun, jak i tych, którzy napisali biblioteki XML dla Java. Biblioteki Java XML są zbyt skomplikowane. Aby po prostu wczytać plik XML, często muszę się martwić, jakiego parsera używam: DOM czy SAX? Interfejsy API dla każdego są równie mylące. Natywne wsparcie w języku do łatwego analizowania / pisania XML byłoby bardzo miłe.
  6. java.util.Date jest do bani. Jest to nie tylko niepotrzebnie skomplikowane, ale wszystkie przydatne metody zostały przestarzałe (i zastąpione innymi, które zwiększają złożoność).

32
Zapomniałeś o java.util.Date!
TM.

3
Ponadto: Interfejs „Cloneable” nie ma metody „clone ()”. To sprawia, że ​​interfejs The Cloneable jest Oxymoronem. A ponieważ clone () zwraca obiekt, bezpieczeństwo typu jest poza oknem (nie pojawia się żadna próba naprawy tego, nawet po wprowadzeniu Generics w J2SE 5.0).
Ryan Delucchi

2
Tak długo, jak staramy się klonować, równie dobrze może obejmować tak zwany „interfejs” do szeregowania. Kiedykolwiek go używam, zawsze chcę się dźgnąć.
wds

12
Trudne do wykonania proste rzeczy, takie jak otwarcie pliku i odczytanie go.
Eric Johnson

3
@Ryan clone () niekoniecznie musi zwracać „Object”. W J2SE 5.0 Java wprowadziła kowariancyjne typy zwracania, co oznacza, że ​​możesz zwrócić dowolny podtyp klasy podstawowej. Tak więc możliwe jest publiczne klonowanie MyType ()!
helpermethod

73

Ruby ma wiele wad związanych z jego szybkością, ale ich nie nienawidzę. Ma też wady, gdy ewangelizacja społeczności przesadza, ale tak naprawdę nie przeszkadza mi to. Oto czego nienawidzę:

  • Zamknięcia (bloki) mają 4 różne składnie tworzenia i żadna z nich nie jest optymalna. Elegancka składnia jest niekompletna i niejednoznaczna z hashami, a pełna składnia jest brzydka.
  • Społeczność zwykle sprzeciwia się prawdziwej dokumentacji, faworyzując „przeczytaj kod”. Uważam to za dziecinne i leniwe.
  • Nadużywanie metaprogramowania, szczególnie w bibliotekach, sprawia, że ​​błędy są koszmarem do wyśledzenia.
  • W powiązanej uwadze, wszechobecne metaprogramowanie utrudnia kompleksowe IDE, jeśli nie niemożliwe.
  • Sposób przekazywania bloku do funkcji jest głupi. Nie ma powodu, dla którego bloki powinny być przekazywane poza listę parametrów lub mieć nieparzystą specjalną składnię, aby uzyskać dostęp (wydajność). Uważam, że bloki powinny mieć mniej dwuznaczną składnię (inaczej skróty mogłyby używać różnych separatorów; być może <> zamiast {}), a przekazywanie parametrów do metod powinno być takie samo jak wszystkich innych parametrów.

    object.method(1, {|a| a.bar}, "blah")
    

    Te osobliwości, jak blok musi być ostatnim parametrem przekazanym, a przekazanie więcej niż jednego bloku różni się dłuższą składnią, naprawdę mnie denerwuje.


2
nieoptymalna obsługa m17n i Unicode, chociaż jest coraz lepsza. 1.9 pozostaje skomplikowane ...
Keltia,

37
Myślałem, że nadużycie metaprogramowania nazywa się „idiomatyczny rubin” :)
Slartibartfast

2
akway: Pozostałe dwie składnie to lambda i Proc.new .
Myrddin Emrys

2
Jeśli chodzi o dokumentację, kiedyś usłyszałem przemówienie kogoś pracującego w wydawnictwie Pragmatic Programmers, który powiedział, że kiedy firma została założona, chcieli książki w języku Ruby, ponieważ jedyna dostępna była w języku japońskim. Aby mogli przetłumaczyć i opublikować tę książkę przez swoją firmę. Ale to, co zrobili zamiast tego, co odczytać kod źródłowy :-) Książka Ruby była najwyraźniej jedną z książek, które uruchomiły Pragmatic Programmers.
Arthur Reutenauer,

13
Uważam za interesujące, że 3 z nich dotyczą ludzi, a nie samego języka. Ruby pozostaje językiem, którego najmniej nienawidzę.
Toby Hede

72

Perl

  • Mieszane użycie pieczęci

    my @array = ( 1, 2, 3 );
    my $array = [ 4, 5, 6 ];
    
    my $one  = $array[0]; # not @array[0], you would get the length instead
    my $four = $array->[0]; # definitely not $array[0]
    
    my( $two,  $three ) = @array[1,2];
    my( $five, $six   ) = @$array[1,2]; # coerce to array first
    
    my $length_a = @array;
    my $length_s = @$array;
    
    my $ref_a = \@array;
    my $ref_s = $array;
    
    • Na przykład żaden z nich nie jest taki sam:

      $array[0]   # First element of @array
      @array[0]   # Slice of only the First element of @array
      %array[0]   # Syntax error
      $array->[0] # First element of an array referenced by $array
      @array->[0] # Deprecated first element of @array
      %array->[0] # Invalid reference
      $array{0}   # Element of %array referenced by string '0'
      @array{0}   # Slice of only one element of %array referenced by string '0'
      %array{0}   # Syntax error
      $array->{0} # Element of a hash referenced by $array
      @array->{0} # Invalid reference
      %array->{0} # Deprecated Element of %array referenced by string '0'
      

    W Perl6nim jest napisane :

    my @array = ( 1, 2, 3 );
    my $array = [ 4, 5, 6 ];
    
    my $one  = @array[0];
    my $four = $array[0]; # $array.[0]
    
    my( $two,  $three ) = @array[1,2];
    my( $five, $six   ) = $array[1,2];
    
    my $length_a = @array.length;
    my $length_s = $array.length;
    
    my $ref_a = @array;
    my $ref_s = $array;
    
  • Brak prawdziwego OO

    package my_object;
    # fake constructor
    sub new{ bless {}, $_[0] }
    # fake properties/attributes
    sub var_a{
      my $self = shift @_;
      $self->{'var_a'} = $_[0] if @_;
      $self->{'var_a'}
    }
    

    W Perl6nim jest napisane :

    class Dog is Mammal {
        has $.name = "fido";
        has $.tail is rw;
        has @.legs;
        has $!brain;
        method doit ($a, $b, $c) { ... }
        ...
    }
    
  • Źle zaprojektowane funkcje wyrażeń regularnych

    /(?=regexp)/;           # look ahead
    /(?<=fixed-regexp)/;    # look behind
    /(?!regexp)/;           # negative look ahead
    /(?<!fixed-regexp)/;    # negative look behind
    /(?>regexp)/;           # independent sub expression
    /(capture)/;            # simple capture
    /(?:don't capture)/;    # non-capturing group
    /(?<name>regexp)/;      # named capture
    /[A-Z]/;                # character class
    /[^A-Z]/;               # inverted character class
    # '-' would have to be the first or last element in
    # the character class to include it in the match
    # without escaping it
    /(?(condition)yes-regexp)/;
    /(?(condition)yes-regexp|no-regexp)/;
    /\b\s*\b/;              # almost matches Perl6's <ws>
    /(?{ print "hi\n" })/;  # run perl code
    

    W Perl6nim jest napisane :

    / <?before pattern>  /;   # lookahead
    / <?after pattern>   /;   # lookbehind
    / regexp :: pattern  /;   # backtracking control
    / ( capture )        /;   # simple capture
    / $<name>=[ regexp ] /;   # named capture
    / [ don't capture ]  /;   # non-capturing group
    / <[A..Z]>           /;   # character class
    / <-[A..Z]>          /;   # inverted character class
    # you don't generally use '.' in a character class anyway
    / <ws>               /;   # Smart whitespace match
    / { say 'hi' }       /;   # run perl code
    
  • Brak wielokrotnej wysyłki

    sub f(   int $i ){ ... }  # err
    sub f( float $i ){ ... }  # err
    sub f($){ ... } # occasionally useful
    

    W Perl6nim jest napisane :

    multi sub f( int $i ){ ... }
    multi sub f( num $i ){ ... }
    multi sub f( $i where $i == 0 ){ ... }
    multi sub f(     $i ){ ... } # everything else
    
  • Słabe przeciążenie operatora

    package my_object;
    use overload
      '+' => \&add,
      ...
    ;
    

    W Perl6nim jest napisane :

    multi sub infix:<+> (Us $us, Them $them) |
                        (Them $them, Us $us) { ... }
    

5
Nie widzę braku prawdziwego OO jako tak złego, jak to robisz. Czasami jest to wybawiciel, szczególnie gdy używany moduł CPAN nie chciał ujawnić tego, czego potrzebujesz. A brak wielokrotnej wysyłki mógłby być gorszy: perl mógł być mocno napisany ;-)
Tanktalus

3
Podoba mi się, że Perl nie jest mocno wpisany, ale przydałoby się dodać jakieś informacje o typie.
Brad Gilbert

13
Wygląda na to, że zdecydowałeś się skrytykować język, który nie jest twoim ulubionym (powinieneś był skrytykować perl6)
Frew Schmidt

5
Jaki jest sens porównywania do Perla 6? Sugerujesz, że Perl 6 naprawia twoje problemy, czy kontynuuje je?
Robert P.

2
Wątpię, czy muszę powiedzieć więcej niż: ozonehouse.com/mark/periodic
Arafangion

57

Będę robił PHP tak, jak lubię, a Python będzie wykonywany zbyt wiele.

  • Brak przestrzeni nazw; wszystko jest w rodzaju bardzo dużej przestrzeni nazw, która jest piekłem w większych środowiskach

  • Brak standardów, jeśli chodzi o funkcje: funkcje tablicowe biorą igłę jako pierwszy argument, a stóg siana jako drugi (patrz tablica_wyszukiwania ). Funkcje ciągów często biorą najpierw stóg siana, a igły drugie (patrz strpos ). Inne funkcje używają tylko różnych schematów nazewnictwa: bin2hex , strtolower , cal_to_jd

    Niektóre funkcje mają dziwne zwracane wartości, poza tym, co jest normalne: To zmusza cię do zadeklarowania znikomej trzeciej zmiennej, podczas gdy PHP może skutecznie interpretować pustą tablicę jako fałszywą za pomocą żonglowania typami. Żadne inne funkcje nie wykonują tego samego.

    $var = preg_match_all('/regexp/', $str, $ret);
    echo $var; //outputs the number of matches 
    print_r($ret); //outputs the matches as an array
    
  • Język (do PHP6) stara się szanować prawie opóźnioną kompatybilność wsteczną, co powoduje, że niesie ze sobą złe praktyki i funkcje, gdy nie są potrzebne (patrz mysql_escape_string vs. mysql_real_escape_string ).

  • Język ewoluował od języka szablonowego do pełnego backendu. Oznacza to, że każdy może wysyłać cokolwiek, kiedy chce, i to jest nadużywane. W efekcie powstają silniki szablonów dla języka szablonów ...

  • Jest do bani przy importowaniu plików. Masz na to 4 różne sposoby (włącz, włącz, włącz, wymagaj, wymagaj), wszystkie są powolne, bardzo wolne. W rzeczywistości cały język jest wolny. Przynajmniej dość wolniej niż python (nawet z frameworkiem) i RoR z tego, co zbieram.

Nadal jednak lubię PHP. To piła łańcuchowa tworzenia stron internetowych: chcesz, aby mała lub średnia strona była wykonywana naprawdę szybko i upewnij się, że każdy może ją hostować (chociaż konfiguracje mogą się różnić)? PHP jest na miejscu i jest tak wszechobecne, że instalacja pełnego stosu LAMP lub WAMP zajmuje tylko 5 minut. Wracam teraz do pracy z Pythonem ...


4
Przypuszczam, że punkt 1 jest zaimplementowany w 5.3 :) Podczas gdy kolejność parametrów jest coraz lepsza, nazywanie jest wciąż słabe. Zgadzam się jednak z wsteczną kompatybilnością.
Ross,

4
Kocham # 4. To jedna z rzeczy, która najbardziej mnie martwiła przez cały czas.
Franz

1
Myślę, że argument prędkości jest dość subiektywny. Szybkość zależy znacznie bardziej od wydajności kodu niż od samego języka. Słaby kod PHP jest prawdopodobnie wolniejszy niż wysokiej jakości kod Pythona, ale dobry PHP może również działać lepiej niż słaby Python.
selfawaresoup

17
no_really_now_mysql_escape_the_string_im_serious ()
Salaryman

2
przestrzenie nazw schmamespaces. PHP jest w Internecie, więc wszystko powinno być globalne
Evan Plaice

50

Oto kilka rzeczy, których nie lubię w Javie (która nie jest moim ulubionym językiem):

  • Kasowanie typu generycznego (tj. Bez zweryfikowanych generycznych)
  • Niemożność wychwycenia wielu wyjątków (różnych typów) w jednym bloku catch
  • Brak destruktorów (finalizacja () jest bardzo słabym zamiennikiem)
  • Brak wsparcia dla zamknięć lub traktowania funkcji jako danych (anonimowe klasy wewnętrzne są bardzo gadatliwym substytutem)
  • Sprawdzone wyjątki w ogólności, a dokładniej, sprawdzanie wyjątków niemożliwych do odzyskania (np. Wyjątek SQLE)
  • Brak wsparcia dla dosłownych kolekcji na poziomie językowym
  • Brak wnioskowania o typie, gdy wywoływane są konstruktory klas ogólnych, tzn. Parametry parametrów muszą być powtarzane po obu stronach „=”

1
@Svish - Myślę, że chodzi o to, że używałbyś tego konstruktu tylko wtedy, gdy nie obchodzi cię, z jakim typem wyjątku masz do czynienia. Innymi słowy, jeśli chcesz obsłużyć je wszystkie identycznie
Dónal

3
Nie nazwałbym braku destrukterów wadą, gdy język ma GC, i GC, który jest coraz lepszy z każdym wydaniem. W java 1.1.8 brakowało niszczycieli, ale nie w java 6, ponieważ gc jest tak znacznie poprawiony.
Mike Reedell,

7
C # naprawia wszystkie z wyjątkiem przechwytywania wielu wyjątków. Generyczne są weryfikowane, destruktory są zastępowane za pomocą / IDisposable, zamknięcia są implementowane metodami anonowymi i lambdas, wyjątki nie są zaznaczone, istnieją literały kolekcji i istnieje 'var', aby uniknąć dwukrotnego określenia typu skonstruowanego.
Daniel Earwicker

1
Java zdecydowanie ma zamknięcia. Anonimowa klasa wewnętrzna zamyka swoje lokalne zmienne końcowe. Zgadzam się, że anonimowe klasy wewnętrzne nie są właściwym substytutem dla anonimowych funkcji, ale zamknięciami.
Adam Jaskiewicz

2
Anonowe klasy wewnętrzne NIE są zamknięciami: spróbuj utworzyć wywołanie zwrotne gościa zawierające coś w rodzaju „sum + = current.amount ()”, gdzie „sum” jest nieokreśloną zmienną z otaczającego zakresu. Zamknij, ale nie cygaro.
Roboprog,

40

C ++

  1. Składnia szablonu
  2. Problemy z dziedziczeniem diamentów
  3. Mnóstwo / brak standardowych bibliotek, które mają współczesne języki (choć zwiększenie jest bliskie).
  4. IOStreams
  5. Składnia używana w IOStreams

Pyton

  1. Spacje są znaczące (czasami)
  2. podkreślone słowa kluczowe
  3. Ograniczona obsługa wątków (przynajmniej obecnie)
  4. „ja” zamiast „tego”
  5. Spacje są znaczące (czasami)

80
Możesz odnosić się do „ja” jako do tego, co naprawdę chcesz (chociaż może być trudne dla innych). „Self” nie jest słowem kluczowym i możesz nazwać zmienną dowolnie.
mipadi

36
proszę bardzo, wymieniłbym znaczenie spacji (zwłaszcza wcięcia) w Pythonie jako jedną z jego największych zalet ...;)
Oliver Giesen,

22
„spacje są znaczące” to jedna z najlepszych cech Pythona !! ps próbuje uruchomić to w
tłumaczu

4
Nie zgadzam się z całą twoją listą python, z wyjątkiem obsługi wątków. Białe znaki nie mają znaczenia, wcięcia są znaczące; jest duża różnica.
Christian Oudard

3
Łał. To tak, jakby nikt nie wynalazł edytora tekstu, który wyróżnia / pokazuje białe znaki / tabulatory jako specjalne znaki (Co, kodujesz w notatniku?). Ponadto, jeśli rozszerzysz tabulatory na spacje, idź zgiń w ogniu.
Fałszywe imię

37

Cel C

1) Brak przestrzeni nazw, tylko ręczne konwencje nazewnictwa - nie przeszkadza mi to w kategoriach separacji klas, ale brakuje mi możliwości importowania wszystkich definicji klas w przestrzeni nazw w jednym wierszu (np. Import com.me.somelibrary. *).

2) W bibliotekach nadal są dziury w ważnych obszarach, takich jak obsługa RegEx.

3) Składnia właściwości jest nieco niezdarna i wymaga trzech wierszy (w dwóch osobnych plikach) do zadeklarowania właściwości.

4) Podoba mi się model zachowania / wydania, ale łatwiej jest zwolnić odniesienie, a następnie przypadkowo skorzystać z niego później.

5) Chociaż Xcode nie jest tak naprawdę funkcją językową, jest tak przeplatany za pomocą Objective-C, że nie mogę przestać myśleć o tym aspekcie ... w zasadzie autouzupełnianie jest bardzo niepewne. To bardziej system, który nagradza cię za znalezienie czegoś, co istnieje, a następnie przedstawia to jako wybór. Ale przypuszczam, że nigdy nie lubiłem autouzupełniania silników.


2
Zgadzam się co do przestrzeni nazw, poprzedzanie klas kodami literowymi jest głupie. Dodałbym brakujące wsparcie dla prawdziwych zmiennych klas, nie lubię ich oszukiwać za pomocą statystyk plików.
zoul

2
Właściwości celu C. Poważnie, są szokujące, nie rozumiem szumu, szczególnie widząc, jak dobrze C # je robi.
Justicle

6
Właściwie podoba mi się ten aspekt Lisp i ObjC - potrzebujesz tylko edytora z dobrym dopasowaniem nawiasów, takiego jak Emacs lub XCode. Zazwyczaj piszę nawiasy klamrowe przed wpisaniem czegokolwiek w nich, więc tak naprawdę nie mam problemów z dopasowywaniem ... a XCode może również podświetlić region objęty nawiasiem klamrowym, klikając dwukrotnie dowolny z nawiasów klamrowych.
Kendall Helmstetter Gelner

1
@Chris S: Mówisz, że YES/NObooleany to zła rzecz? A co ważniejsze, czy mówisz, że Nazwane parametry są złe? Rozumiem boole, ale nazwane parametry są prawdopodobnie jedną z najlepszych cech ObjC (pod względem czytelności).
jbrennan

3
Może jestem masochistą, ale lubię nazwy klas z prefiksem. Dzięki temu wyszukiwanie w google i dokumentacji jest krystalicznie czyste, nigdy nie ma wątpliwości co do tego, jakiego rodzaju łańcucha używasz, jeśli klasa nazywa się NSString.
kubi

36

C ++

  • Smyczki.
    Nie są one interoperacyjne z ciągami platformy, więc w połowie przypadków używasz std :: vector. Zasady kopiowania (kopiowanie podczas zapisu lub głębokie kopiowanie) nie są zdefiniowane, więc nie można dać gwarancji wydajności dla prostej składni. Czasami opierają się na algorytmach STL, które nie są zbyt intuicyjne w obsłudze. Zbyt wiele bibliotek tworzy własne, które są niestety wygodniejsze w użyciu. Chyba że musisz je połączyć.

  • Różnorodne reprezentacje ciągów
    Jest to trochę problem z platformą - ale nadal mam nadzieję, że byłoby lepiej, gdyby wcześniej była dostępna mniej uparta standardowa klasa ciągów. Następujące ciągi znaków, których często używam:

    • ogólny LPCTSTR,
    • LPC (W) STR przydzielony przez CoTaskMemAlloc,
    • BSTR, _bstr _t
    • (w) ciąg znaków,
    • Ciąg c,
    • std :: wektor
    • klasa roll-my-own ( westchnienie ), która dodaje sprawdzanie zasięgu i podstawowe operacje do bufora (w) char * o znanej długości
  • Zbuduj model.
    Jestem chory na śmierć przez cały czas, grzebiąc w bzdurach z deklaracjami typu „kto-co-co”, optymalizując prekompilowane nagłówki i obejmując utrzymanie co najmniej przyrostowych czasów kompilacji itp. To było świetne w latach osiemdziesiątych, ale teraz? Jest tak wiele przeszkód w pakowaniu fragmentu kodu, aby można go było ponownie wykorzystać, że nawet pies mamy się nudzi, słuchając mnie.

  • Trudny do przeanalizowania
    To sprawia, że ​​zewnętrzne narzędzia są szczególnie trudne do napisania i poprawnego działania. A dzisiaj nam, facetom z C ++, brakuje głównie łańcucha narzędzi. Uwielbiam moje odbicie C # i delegatów, ale mogę żyć bez nich. Bez wielkiego refaktoryzacji nie mogę.

  • Wątek jest zbyt trudny
    Język nawet go nie rozpoznaje (do tej pory), a swobody kompilatora - choć świetne - są bolesne.

  • Inicjacja statyczna i na żądanie. Technicznie, oszukiwam tutaj: to kolejny element układanki w „pakiecie kodu do ponownego użycia”: Koszmarem jest zainicjowanie czegoś tylko wtedy, gdy jest to potrzebne. Najlepszym rozwiązaniem wszystkich innych problemów redystycznych jest wrzucenie wszystkiego do nagłówków, problem ten mówi „neeener - nie możesz”.


To prawda, że ​​wiele z nich wykracza poza ścisły zakres językowy, ale IMO cały łańcuch narzędzi musi być oceniany i ewoluować.


Przeglądanie dokumentacji na STL jest jak szukanie instrukcji, jak zbudować kartę graficzną od podstaw.
aviraldg

Szczerze mówiąc, większość z tych punktów brzmi, jakbyś nigdy nie zadał sobie trudu, aby poprawnie nauczyć się C ++ ... staje się to dość oczywiste w punkcie 3, ponieważ strażnicy integracji są czymś, co powinien wiedzieć każdy programista C ++. Nie jestem również pewien, jak rozumieć punkt 1, czy jesteś zdezorientowany std::string? może przeczytanie dobrej dokumentacji i / lub samouczka na temat std::vector(i dlaczego nie powinieneś używać std::stringw miejscach, w których nigdy nie został zaprojektowany) może to wyjaśnić.

@nebukadnezzar: Znalazłem Meyersa oświetlającego STL, ale to nie rozwiązuje podstawowych problemów. Szczerze mówiąc, brzmi to tak, jakbyś nigdy nie musiał utrzymywać dużego projektu, nigdy nie musiałeś wyłapywać okrągłej zależności w hierarchii obejmującej dziesiątki. Wiem, że to strażnicy, ale dlaczego musimy się nimi przejmować? BTW. nie naprawiają każdego problemu. Jak „standardowy” jest, std::stringjeśli nie mogę go używać przez połowę czasu? (C ++ 0x przynajmniej to naprawia, ale wciąż tkwi w dziesiątkach bibliotek, które używają różnych reprezentacji ciągów).
peterchen

but why do we have to bother with them (inclusion guards)- ponieważ C ++ nie ma modułów. How "standard" is a std::string if I can't use it half of the time?- Myślę, że to zależy od sposobu, w jaki korzystasz std::string. Klasa string umożliwia dostęp do danych ciągu const char*poprzez via std::string::c_str, co już czyni go std::stringcałkowicie kompatybilnym z każdą klasą / funkcją, która również przyjmuje const char*argumenty.

ponieważ C ++ nie ma modułów - dokładnie moja skarga: model kompilacji jest antyczny (po prostu zaakceptowałbym również inne rozwiązanie niż moduły). ----- doskonale kompatybilny - ale doskonale niekompatybilny z wieloma innymi scenariuszami (argumentowałbym, że poprawienie C ++ 0x to mówi, że mam tutaj rację.) Byłbym szczęśliwy, gdyby std :: string było wystarczająco wszechobecne, aby zostały przyjęte jako THE string class 10 lat temu, ale tak nie było - druga skarga.
peterchen

35

JavaScript :

  • ObjectPrototyp może być modyfikowana. Każdy obiekt w twoim programie otrzymuje nowe właściwości i coś prawdopodobnie się psuje.

  • Wszystkie obiekty są mapami skrótu, ale trudno jest bezpiecznie z nich korzystać. W szczególności, jeśli zdarzy się jeden z twoich kluczy __proto__, masz kłopoty.

  • Brak zamknięcia obiektu w czasie odniesienia funkcji. W rzeczywistości żadne zamknięcie obiektu nie thisjest ustawiane - zamiast tego jest ustawiane za każdym razem, gdy funkcja jest wywoływana za pomocą notacji obiektu lub newoperatora. Powoduje wiele zamieszania, szczególnie podczas tworzenia wywołań zwrotnych zdarzeń, ponieważ thisnie jest ustawiony zgodnie z oczekiwaniami programisty.

    • Następstwo: wywołanie funkcji bez notacji obiektu lub newoperatora powoduje thisustawienie wartości równej obiektowi globalnemu, co powoduje znaczne uszkodzenie.
  • Operator dodawania został przeciążony, aby wykonać konkatenację łańcuchów, mimo że dwie operacje są zasadniczo różne. Powoduje ból, gdy oczekiwana wartość będzie liczbą.

  • ==a !=operatorzy dokonują przymusu typu. Porównania między różnymi typami obejmują listę zasad, których żaden śmiertelnik nie może w pełni zapamiętać. Jest to ograniczone przez istnienie operatorów ===i !==.

  • Zarówno nulli undefinedistnieje, z subtelnie różne, ale zbędnych znaczeń. Dlaczego?

  • Dziwna składnia do konfigurowania łańcuchów prototypów.

  • parseInt(s)oczekuje liczby w stylu C, więc traktuje wartości z wiodącymi zerami jako liczby ósemkowe itp. Możesz przynajmniej, parseInt(s, 10)ale zachowanie domyślne jest mylące.

  • Brak zasięgu bloku.

  • Może zadeklarować tę samą zmienną więcej niż jeden raz.

  • Może używać zmiennej bez deklarowania jej, w takim przypadku jest ona globalna i prawdopodobnie psuje twój program.

  • with { }.

  • Naprawdę trudne do udokumentowania za pomocą narzędzi podobnych do JavaDoc.


3
Dla nulli undefined: czasami naprawdę chcesz wiedzieć, czy zmiennej przypisano wartość, czy nie. Ponieważ null jest wartością, niezdefiniowany jest jedynym sposobem, aby powiedzieć. To prawda, że ​​jedynym razem, kiedy uznałem to za przydatne, było tworzenie funkcji getter / setter.
Zach

1
„jeśli jeden z twoich kluczy jest proto ” - cóż, jest to słowo zastrzeżone o szczególnym znaczeniu. to tak, jakby narzekać, że nie można użyć forjako nazwy zmiennej.
nickf

5
@nickf: Kluczem do skrótu jest ciąg. Ciągi mogą mieć dowolną wartość, w tym słowa zastrzeżone. W szczególności wartość "for"jest ważna jako klucz skrótu. __proto__nie jest słowem zastrzeżonym. Specjalne wartości ciągów, które nie działają zgodnie z oczekiwaniami, gdy są używane jako klucze skrótu, naruszają uzasadnione oczekiwania dotyczące działania tablic asocjacyjnych w dowolnym języku. Naruszają także specyfikację EcmaScript.
Daniel Cassidy

2
Thomas: Newline nie zawsze kończy zdanie. Dlatego rozsądni koderzy kończą każdą instrukcję średnikiem, aby kod był bardziej przejrzysty.
Daniel Cassidy

2
newline may or may not end a statement depending on contextjest jednym z moich 5 najlepszych list
reinierpost

34

Pyton:

  • Brak pisania statycznego
  • Domyślna obsługa argumentów (w szczególności fakt, że możesz zmienić domyślny argument dla przyszłych rozmówców!)
  • Zbyt wiele wymaganych znaków podkreślenia (należy wywołać konstruktorów __init__)
  • Brak odpowiednich prywatnych członków i funkcji (konwencja mówi tylko, że większość rzeczy, które zaczynają się od podkreślenia są prywatne, z wyjątkiem wszystkich takich rzeczy, __getattr__które nie są)
  • Zabawna składnia dla printing do pliku (ale naprawiają to w Pythonie 3)

10
To, co chciałbym, to opcja użycia typów statycznych.
Greg Hewgill,

4
BTW: init tak naprawdę nie jest konstruktorem, obiekt został już utworzony, kiedy tam wejdziesz (zgadnij, czym jest ja ...). Konstruktor jest zupełnie nowy, w którym masz dostęp do klasy, która ma zostać utworzona.
André

90
Jeśli wolisz pisać statycznie, dlaczego Python jest Twoim ulubionym językiem?
finnw

9
finnw: Pisanie statyczne jest świetne dla niektórych rodzajów programów i tak naprawdę nie jest potrzebne w przypadku innych typów. Zwykle nie przeszkadza mi brak pisania statycznego, ale kiedy go potrzebujesz, naprawdę miło jest mieć przynajmniej taką opcję.
Greg Hewgill,

8
Powiedziałbym, że brak pisania statycznego jest cechą, nie brakuje funkcjonalności ...
arnorhs

32

DO#

  • Chciałbym móc switch()na każdym rodzaju, a to casemoże być dowolny wyraz.

  • Nie można używać składni inicjalizującej obiekty z polami / private setautopropami „tylko do odczytu” . Zasadniczo chcę pomocy językowej w tworzeniu niezmiennych typów.

  • Użycie {}dla przestrzeni nazw i klasy oraz bloków metod i właściwości / indeksatorów oraz bloków wielu instrukcji i inicjatorów tablic . Trudno jest ustalić, gdzie jesteś, gdy są daleko od siebie lub są niedopasowane.

  • Nienawidzę pisać (from x in y ... select).Z(). Nie chcę wracać do składni wywołania metody, ponieważ w składni zapytania brakuje czegoś.

  • Chcę doklauzuli dotyczącej składni zapytań, która jest podobna foreach. Ale tak naprawdę nie jest to zapytanie.

Naprawdę tu docieram. Myślę, że C # jest fantastyczny i trudno jest znaleźć wiele zepsutych.


14
+1 za włączenie dowolnego typu
o

+1 za problemy z zamianą i {} problemy, o których do tej pory tak naprawdę nie myślałem
Masłów,

Nienawidzę {}. Wyglądają za bardzo jak (). Niedopasowanie nigdy nie stanowiło dla mnie większego problemu, ponieważ zawsze stawiam je na tym samym poziomie, chyba że są one w zasadzie jedno-liniowe.
Loren Pechtel

2
+1 dla zapytania linq. Zwłaszcza gdy chcesz zwrócić tylko jeden obiekt. Zamiast (od xw y wybierz) .pierwszy (), dlaczego nie (od xw y wybrać górę 1) lub coś, co by pasowało bliżej faktycznej składni sql.
AdmSteck

jeśli chcesz, możesz przełączyć () na dowolny typ, a tym przypadkiem może być dowolne wyrażenie sprawdź dopasowanie wzoru F #. c-sharpcorner.com/UploadFile/mgold/…
gradbot

26

PHP

  1. Brak funkcji debugowania, jeśli nie kontrolujesz serwera, a nawet wtedy są trochę do dupy
  2. Ogromna ilość złego kodu PHP unoszącego się wokół sprawia, że ​​wszyscy programiści PHP mają złą nazwę
  3. Niespójne nazewnictwo funkcji
  4. Niemożność posiadania zmiennej o typie statycznym, jeśli jej potrzebuję (jestem wielkim fanem pisania dynamicznego przez 90% czasu)
  5. REGISTER_GLOBALS jest diabłem

25
REGISTER_GLOBALS raz zjadł mojego psa :(
Pim Jager

2
1: Polecam xdebug i klienta GUI, takiego jak MacGDBp. To naprawdę łagodzi ból ... Zgadzam się z innymi punktami.
Jonas Due Vesterheden

5
# 2: O Boże, nie zaczynaj od tego. Zawsze muszę bronić się jako programista PHP przed ludźmi, którzy widzieli tylko bałagan, który wiele osób tworzy przy pomocy PHP.
selfawaresoup

1
+1 za # 2 Spędziłem zbyt dużo czasu broniąc się jako programista PHP.
UnkwnTech

+1 za # 2 - powoduje również złe wynagrodzenie :(
Shiki

25

C (OK, to nie jest moja ulubiona, ale jeszcze tego nie zrobiono).

  • Składnia biblioteki gniazd.
  • Brak przeciążenia funkcji.
  • Struny w stylu C.
  • Przepełnienia bufora.
  • Zagadkowa składnia. Nie wiem, ile razy szukałem takich rzeczy jak atoi, klepałem się w czoło i krzyczałem „Oczywiście!”

EDYCJA: Prawdopodobnie mógłbym wymyślić więcej, gdybym sięgnął po więcej kodu bibliotecznego (tak jak zrobiłem z gniazdami, ale te są szczególnie złe), ale już czułem, że oszukuję za wybranie C. Tak wiele języków istnieje tylko po to, aby wziąć dobre części C i zastąp złe, że to trochę jak pokonanie martwego konia.


22
Jaka składnia gniazda? C nie ma pojęcia o gniazdach.
Ferruccio,

3
No weź! Możesz wymyślić pięć. Czy arytmetyka wskaźników nie jest po prostu do kitu? :)
brian d foy,

8
+1 Śmiałem się z „Ciągów w stylu C.” I @brain_d_foy: arytmetyka wskaźników jest do bani tylko wtedy, gdy jej nie rozumiesz.
Chris Lutz

1
@Chris Luts: Nawet wtedy, gdy uczyłem się zwykłego C (zanim poznałem C ++ lub inny język OO), po prostu wiedziałem, że coś jest nie tak z tablicami znaków. :)
Bill the Lizard

2
wskaźnik arytmetyki jest piłą mechaniczną - bardzo wydajną, ale ryzykujesz wzięcie całej nogi
Thorbjørn Ravn Andersen

24

Common Lisp:

  1. Słowa kluczowe są często zbyt nieporadne.
  2. Wsparcie biblioteki jest żałosne.
  3. Nie działa dobrze w systemach operacyjnych, które chcą ściślej obsługiwać pamięć.
  4. Nie ma dobrych udogodnień do interakcji z systemem operacyjnym.
  5. Funkcja „pętli” nie jest dobrze zdefiniowana i na pewno nie wygląda na Lispy.

2
„pętla” może nie być marna, ale co jest źle zdefiniowane?
Daniel Cassidy,

2
Sam nie czytałem standardu, głównie pracuję nad utworem Paula Grahama „On Lisp”. Mówi, że standard jest w większości przykładami i wcale nie definiuje dobrze przypadków narożnych.
David Thornley,

3
nie masz na myśli słów kluczowych, czy są zbyt pracowite?
GClaramunt

Zgadzam się, że nie jest to „lispy”, ale CLtLv2 spędza na nim dużo czasu. Po prostu myślę, że został zaprojektowany, aby zrobić o wiele za dużo. sunsite.univie.ac.at/textbooks/cltl/clm/…
Hans Van Slooten

Oprócz „pętli”, „format” również nie jest bardzo Lisplike. Nienawidzę zarówno „formatu”, jak i „pętli”, mimo że Lisp jest moim ulubionym językiem.
Paul Reiners,

24

BrainF * ck

  • Najważniejsze jest to, że Turing jest kompletny ?! Mogę zrobić więcej w wyrażeniach regularnych Perla!

  • Brak przedmiotów. Dalej ludzie! Cześć , cześć ...

  • Brak bibliotek sieciowych. Chcę tylko zeskrobać stronę internetową, GOSH.

  • Brak pierwszorzędnych funkcji. Gratulacje - możesz rozmawiać ze znajomymi z Javy.

  • Nieskończona taśma do przechowywania i nic więcej. Jest to tak pretensjonalne, że równie dobrze moglibyśmy pisać Lisp.


6
Nie ma obsługi przestrzeni nazw ani modułów dynamicznych. Jak możemy oczekiwać od pisania systemów kontroli instalacji chemicznych bez takich podstaw?
Donal Fellows

Bez cukru składniowego, np.> 10 (przesuń 10 razy), 0 (wstaw zero), +5 (dodaj 5).
Szkwał

23

JavaScript

  1. liczby jako ciągi znaków - matematyka może być frustrująca, gdy liczby są interpretowane jako ciągi znaków. 5 + 2 = 52? Grrr ...
  2. uprawnienia - wszystkie najlepsze rzeczy wymagają zgody użytkownika!
  3. aktualizacje ekranu - przeglądarka musi być w stanie ustalonym, aby zaktualizować ekran. Wydaje się, że nie ma sposobu, aby zmusić ekran do aktualizacji w środku skryptu.
  4. Powoli - chociaż Chrome Google'a jest fajny ...
  5. Różnice w przeglądarce powodują, że używanie języka jest [ocenzurowane].

4
Liczby jako ciągi znaków można łatwo naprawić. Jeśli kiedykolwiek masz ciąg, musisz go przeanalizować (x, 10). Olbrzymia porażka występuje wtedy, gdy pominiesz cyfrę 10 i interpretuje ona „017” jako OCTAL
Orion Edwards

3
false == 0 == [] == "", ale null i NaN nie są. NaN! = NaN. null == null.
Jimmy,

7
typeof „a string” == „string”. typeof new String („inny ciąg”) == ”obiekt. new String („ a ”). konstruktor ==„ a ”.constructor. typeof new Array () ==„ obiekt ”
Jimmy,

1
for (x w obiekcie) zwraca funkcje
Jimmy

14
-1, ta lista dotyczy głównie problemów z przeglądarką, a nie samego języka.
Mauricio Scheffer

20

PHP:

  • Nigdy nie można być pewnym, że niektóre prawie powszechne rozszerzenia są dostępne na wszystkich serwerach WWW.
  • stara się być wszystkim w przyszłości (goto, zamknięcia, ...)
  • wiele zagrożeń bezpieczeństwa dla niedoświadczonych użytkowników
  • Przydałoby się więcej przeciążenia operatora
  • wszyscy biedni programiści, którzy nie uczą się, jak sprawić, by działał poprawnie, i nadają mu złą nazwę

Niemniej PHP jest (skrypty) język. ;-)


OK, jeszcze tylko jedna rzecz do zrobienia!
brian d foy,

4
Całkowicie zgadzam się z punktem 5 - byłby również na liście Javascript.
Steve Claridge

Nie zgadzam się z „wszystkimi biednymi programistami, którzy nie uczą się, jak sprawić, by działał poprawnie, i nadają mu złą nazwę”. Zastąpiłbym go „masowymi rozwiązaniami dotyczącymi opcji konfiguracji języka środowiska wykonawczego”.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

18

VB6

  1. Tylko Windows.
  2. Nie jest już obsługiwany.
  3. Tablice mogą zaczynać się od dowolnej liczby, a następnie wszystkie są znormalizowane do 0.
  4. skompilowane aplikacje zależą od prawidłowego działania wielu bibliotek DLL.
  5. Wiele skomplikowanych elementów sterujących, takich jak element sterujący przeglądarki lub skomplikowane fragmenty kodu, mają tendencję do łamania IDE po uruchomieniu kodu nieskompilowanego, ale działa dobrze po skompilowaniu.

13
VB to czyjś ulubiony język? O_o. Dlaczego „syntaz, który jest zupełnie inny i niezgodny z innymi językami” i „daje złe nawyki w odniesieniu do innych języków”?
Jonta

3
Uważam, że # 3 jest bardzo potężną funkcją, a nie błędem - naprawdę chciałbym mieć VB.NET. AWK ma to w pewnym sensie, ale potem w tablicach AWK naprawdę kryją się hasze w przebraniu :(
Joe Pineda

3
Na 1 i 4, a .NET C # nie wymaga KOMPLETNEJ RAMY i systemu operacyjnego ??? (hej, słyszałem, że jesteś mono bigotem ... to wciąż jest dla ciebie „kompletny framework” i wątpię, żeby debian kiedykolwiek go zjadł). Jeśli chodzi o 5, żaden rozsądny programista VB6 (z powrotem na dzień) nie utrzymywał domyślnej opcji „Kompiluj na żądanie” WŁĄCZONE ...
jpinto3912

2
Nadal muszę czasami obsługiwać vb6. Pet pieves: nie można zainicjować zmiennej w deklaracji, żadnych sparametryzowanych konstruktorów, jednej klasy na plik itp. Jeśli rozwiązaliby te problemy, język mógłby trwać przez kolejne 10 lat.
AngryHacker

14
Co powiesz na „Wznów błąd przy następnym”… to tak, jakby powiedzieć „ten kod to F ** KED, ale i tak go
uruchommy

18

Ruby to mój ulubiony język, oto czego nie lubię:

  • Zielone wątki + blokowanie bibliotek C = gigantyczna awaria
  • TAK BARDZO WOLNO
  • Sama biblioteka standardowa jest niespójna z użyciem huku! metody
  • Moduł include + ext jest niechlujny.
  • Nie można określić zakresu „klas otwartych” - chcę dodać ciąg # dostuff, ale nie chcę, aby przenikał do wszystkich bibliotek stron trzecich
  • Brak binarnego rozwiązania do wdrażania.

3
Próbowałeś już Ruby 1.9.1? Oferuje ogromne przyspieszenie w porównaniu do Ruby 1.8.6
Christian Stade-Schuldt

Spróbuj jrubyc. JVM JIT FTW!
KitsuneYMG

+1 za uwzględnienie rozsądnych problemów, w przeciwieństwie do „nienawidzi” od najlepiej ocenianej odpowiedzi Ruby.
Phrogz

17

Delphi:

  • IDE jest nieco niestabilny.
  • Wgląd w kod jest czasem mylony.
  • Debugowanie bywa czasem błędne.
  • Aktualizacja kilku plików projektu może być uciążliwa.
  • W przypadku uruchamiania, gdy jeden lub więcej pakietów jest niedostępnych, komunikat o błędzie pojawia się kilka razy.

5
Wszystkie te wydają się raczej skargami na Delphi IDE niż Delphi język (AKA Object Pascal)
Dónal

11
Prawdopodobnie dlatego, że Object Pascal jest idealny ;-)
Mark Bessey,

3
Jestem trochę spóźniony na imprezę, ale i tak idzie: - dwukrotne zapisywanie podpisów metod (interfejs + implementacja) - WYMAGANA jest nazwa jednostki, aby była identyczna z nazwą pliku. WTF?!?
Martijn

1
Uważam, że początek… jest lepszy - są o wiele wyraźniejsze niż {}. Spędzasz dużo więcej czasu na czytaniu kodu niż na pisaniu. Jednak dla pewnej przeszkody - nie możesz użyć zdefiniowanych podzakresów wyliczonych typów w sprawie, nawet jeśli jest to całkowicie legalne, jeśli zadeklarujesz zakres właśnie w tej sprawie. Ponadto nie ma żadnych odniesień do przodu między jednostkami.
Loren Pechtel

1
@AlexanderN: Nie, nigdy nie był tak żywy, popularny ani świetny.
Andreas Rejbrand

16

JavaScript

  • Każdy skrypt jest wykonywany w jednej globalnej „przestrzeni nazw” ... na co trzeba uważać podczas pracy ze skryptami z różnych źródeł

  • Jeśli zmienna jest używana, ale nie została wcześniej zdefiniowana, jest uważana za zmienną globalną

  • Dostawcy przeglądarek opracowują standardy według własnego uznania, dzięki czemu kodowanie dla naszych programistów korzystających z tak pięknego języka jest trudniejsze niż powinno być

  • Rozróżnianie wielkości liter - biorąc pod uwagę, że nie ma przyzwoitego IDE do rozwijania js ze sprawdzaniem czasu kompilacji

  • Obejścia (takie jak użycie hasOwnPropertymetody) w celu wykonania niektórych, w przeciwnym razie prostych operacji.


AFAIK, wszystkie rozszerzenia języka JS (nie DOM) przez producentów przeglądarek zostały przynajmniej popchnięte do standardowego przyjęcia - nawet jeśli proces normalizacji tego nie osiągnął. hasOwnProperty / obejścia: miecz obosieczny. Aby wymusić „prostotę”, tracimy dużo mocy i elastyczności. Ta skarga zawsze mnie wkurza. Pisz poprawnie swoje pętle (i dokładnie sprawdź członków obiektu)!
powiek

15

Haskell:

  1. Wycieki przestrzeni z leniwej oceny.
  2. Hierarchia numeryczna nieskonstruowana w odniesieniu do abstrakcji matematycznych.
  3. Surowe monadyczne we / wy może utrudnić debugowanie.
  4. Duże implementacje obsługują operacje we / wy w sposób, który wydaje się niezupełnie zgodny ze standardem. (W szczególności wyprowadzanie znaków wyprowadza tylko 8 bitów niskich - a następnie budowany jest kod, który wykorzystuje to założenie do robienia binarnych operacji we / wy. Ick.)
  5. Asocjatywność ($)operatora można zmienić, aby niektóre wyrażenia były ładniejsze.

Większość z nich nie osiąga poziomu nienawiści, a są ludzie próbujący naprawić lub skonstruować solidne obejścia dla każdego z nich.

Edycja: Było trochę zamieszania w związku z punktem 5. W szczególności niektórzy ludzie myślą, że miałem na myśli kolejność argumentów, a ja nie. Zamiast wyjaśniać, co miałem na myśli, wskażę ludziom następujący link: http://hackage.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociativity , który dobrze to wyraża.


3
Dlaczego chcesz zmienić skojarzenie ($)? nawiasy fghx jako „((fg) h) x” i „f $ g $ h $ x” nawiasy jako „f (g (hx))” ...
Erik Hesselink

1
I <3 Haskell. Standardowa biblioteka musi zawierać góry abstrakcji matematycznych, w tym przestrzenie wektorowe i in. Preludium potrzebuje również operatora, który łączy łańcuch podobnie jak ($), ale od lewej do prawej {source |> func1 |> filter func2 |> map (func3 10)}.
yfeldblum

10
Brakowało Ci naprawdę złego: tendencji programistów Haskell do używania nazw zmiennych o jednej literze.
Benjamin Confino,

1
Operator lewostronny ($) to po prostu aplikacja funkcyjna, która w Haskell jest reprezentowana przez znak spacji. @ Justice: Wypróbuj funkcję flip. (|>) = flip ($)
Apocalisp

1
Czy ktoś może wyjaśnić punkt # 5? Myślałem, że właściwe skojarzenie to sedno ($).
Tim Matthews
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.