Autor Wątek: Czy PHP jest dobre  (Przeczytany 30051 razy)

Offline albireo

  • Użytkownik

# Grudzień 02, 2014, 20:27:24
Do upierdliwych rzeczy w pythonie dodałbym jeszcze:
- iterowanie stringów - upierdliwe bo jeśli spodziewa się czegoś co przy iteracji zwraca stringa, to podanie stringa też zadziała, tylko będzie iterowało po literkach
- indeksowanie tablic od końca przy pomocy ujemnych liczb - daje to ciekawe możliwości, ale jak się operuje na indeksie w okolicach 0 i przejdzie do liczb ujemnych to zamiast zgłosić błąd, zwróci element z końca tablicy, oraz przy pobieraniu zakresu z tablicy, to pobieranie do ostatniego elementu wymaga użycia innego typu niż przedostatniego.  Lepiej by było jakby był specjalny obiekt (powiedzmy nazywający się End), który miałby prostą arytmetykę (dodawanie i odejmowanie) z intami.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline kapustman

  • Użytkownik

# Grudzień 02, 2014, 20:30:57
Cytuj
C++ jest beznadziejny z całkiem innych powodów niż wyżej wymienione języki.

Z czystej ciekawości, dlaczego C++ jest beznadziejny?

Offline jelcynek

  • Użytkownik

  • +3
# Grudzień 02, 2014, 21:29:01
Choćby dlatego, że jest swoistym frankensteinem. Nowe funkcjonalności zostają dodawane bez żadnej konsekwencji (pewnie jakaś jest, ale ja jej nie widzę). Nowe featury języka są dodawane w postaci funkcje w bibliotece standardowej, jako templaty, inne jako operatory. Jak na to się spojrzy z dala to jest to taki potworek poskładany ze wszystkiego.

#include i cały preprocessor w nowoczesnym języku nie powinien istnieć, chyba że jako plugin, nie jako podstawowy mechanizm języka (wiem, c++ minimalizuje użycie preprocessora do minimum, ale #include nadal istnieje).

Jeszcze coś bym mógł zarzucić, ale mi się nie chce. Troszkę mi się otworzyły oczy jak w pracy zetknąłem się z ADA. Język potrafi to samo co C++, wydajność ma podobną jak nie lepszą (wybaczcie, nie będzie citation), a przy tym nie wygląda jak zlepiony z 4 niepowiązanych ze sobą części. Do tego kilka ciekawych mechanizmów, których w c++ nie ma (subtype, range). Język wymusza pisanie (w miarę możliwości) bezpiecznego kodu. Oczywiście tracimy elastyczność, którą nam daję C++. W gamedevie nie użyłbym ADA ze względu na małe community, jednak zetknięcie się z tym językiem pokazało mi, że język ogólnego zastosowania to nie musi koniecznie być C++.

Niestety będzie to parszywy offtop bo jedyne co w PHP kiedykolwiek napisałem to jakiś żałosny pseudosklep internetowy na studiach.

Offline Xender

  • Użytkownik

# Grudzień 02, 2014, 22:32:03
Do upierdliwych rzeczy w pythonie dodałbym jeszcze:
- iterowanie stringów - upierdliwe bo jeśli spodziewa się czegoś co przy iteracji zwraca stringa, to podanie stringa też zadziała, tylko będzie iterowało po literkach
No i? To już błąd programisty, nie języka.
Iterowanie po stringach to dobry feature.

Jedyną nieco "dziwną" rzeczą może być to, że iterowanie po stringu zwraca pojedyncze znaki jako stringi o długości 1 (po których też można iterować :P). Ale to też przeważnie nie przeszkadza, za to wprowadzanie niepotrzebnego typu char tylko niepotrzebnie rozdmuchałoby (nieznacznie, ale jednak) język.

- indeksowanie tablic od końca przy pomocy ujemnych liczb - daje to ciekawe możliwości, ale jak się operuje na indeksie w okolicach 0 i przejdzie do liczb ujemnych to zamiast zgłosić błąd, zwróci element z końca tablicy, oraz przy pobieraniu zakresu z tablicy, to pobieranie do ostatniego elementu wymaga użycia innego typu niż przedostatniego.  Lepiej by było jakby był specjalny obiekt (powiedzmy nazywający się End), który miałby prostą arytmetykę (dodawanie i odejmowanie) z intami.
Byłoby jedynie upierdliwiej.
a[-1]  # Wygląda ładnie
a[a.end-1]  # WTF?!

Polecam też pełną notację slicingu - a[start:end:step], gdzie każdy z argumentów jest pomijalny i defaultuje się do sensownej wartości.

Offline koirat

  • Użytkownik

# Grudzień 02, 2014, 22:36:12
a[-1] wygląda idiotycznie, to jak jakaś magiczna liczba. Chyba że a[-2] itd. zwraca drugi i kolejne od końca to wtedy można by to usprawiedliwić.

a.Last wygląda ładnie. Problem w tym co zrobić jak len(a) == 0

Offline Xirdus

  • Redaktor

# Grudzień 02, 2014, 23:21:07
a[-1] wygląda idiotycznie, to jak jakaś magiczna liczba. Chyba że a[-2] itd. zwraca drugi i kolejne od końca to wtedy można by to usprawiedliwić.
Tak jest.

Offline albireo

  • Użytkownik

# Grudzień 02, 2014, 23:28:07
No i? To już błąd programisty, nie języka.
Iterowanie po stringach to dobry feature.
Problem w tym, że to jest łatwo do popełnienia błąd który na dodatek trudno wychwycić, bo program dalej działa tylko daje bzdurne wyniki (parę razy się na to naciąłem). No i nie przypominam sobie żebym kiedykolwiek potrzebował iterowania po stringu, a nawet jeśli bym potrzebował, to wystarczyłoby mi żebym mógł zrobić to np tak: "asdf".chars().

Byłoby jedynie upierdliwiej.
a[-1]  # Wygląda ładnie
a[a.end-1]  # WTF?!
Chodziło mi o zapis:
a[End-1]
ewentualnie zamiast End można by wykorzystać symbol $ (jak jest np w D).

Offline Xirdus

  • Redaktor

# Grudzień 02, 2014, 23:34:50
Z czystej ciekawości, dlaczego C++ jest beznadziejny?
Kompatybilność z C, templatki i brak modułów to główne bolączki, ale nie jedyne.

Offline ArekBal

  • Użytkownik

# Grudzień 03, 2014, 01:18:58
A co jest nie tak z templatkami? Oczywiście poza tym że są skomplikowane dla kompilatora. ;)

Offline Xirdus

  • Redaktor

# Grudzień 03, 2014, 02:20:01
Są skomplikowane dla ludzi. I z braku lepszych narzędzi do mrtaprogramowania są strasznie nadużywane (std::enable_if to mój ulubiony przykład - ze świecą szukać takiego haka).

Offline Xender

  • Użytkownik

# Grudzień 03, 2014, 12:46:12
Problem w tym, że to jest łatwo do popełnienia błąd który na dodatek trudno wychwycić, bo program dalej działa tylko daje bzdurne wyniki (parę razy się na to naciąłem). No i nie przypominam sobie żebym kiedykolwiek potrzebował iterowania po stringu, a nawet jeśli bym potrzebował, to wystarczyłoby mi żebym mógł zrobić to np tak: "asdf".chars().
Meh. Nadal nie widzę powodu, by traktować interfejs stringa jako coś innego, niż kontener na znaki.
Wiesz, jak zapodasz funkcji w argumencie [[1, 2, 3]] zamiast [1, 2, 3], to też się popsuje...

Chodziło mi o zapis:
a[End-1]
ewentualnie zamiast End można by wykorzystać symbol $ (jak jest np w D).
Ale wtedy wprowadzasz zupełnie nową składnię, tylko do tego celu.
Siła obecnego rozwiązania tkwi w prostocie - indeksem może być wyrażenie.

Są skomplikowane dla ludzi. I z braku lepszych narzędzi do mrtaprogramowania są strasznie nadużywane (std::enable_if to mój ulubiony przykład - ze świecą szukać takiego haka).
Czy C++11 i 14 z funkcjami constexpr i zezwoleniem na prawie dowolne instrukcje warunkowe w środku nie powinien przynieść poprawy? Chociaż nie wiem, czy akurat to pomoże zrefaktoryzować wzorce używane do SFINAE...
« Ostatnia zmiana: Grudzień 03, 2014, 12:48:04 wysłana przez Xender »

Offline Xirdus

  • Redaktor

# Grudzień 03, 2014, 13:03:38
Czy C++11 i 14 z funkcjami constexpr i zezwoleniem na prawie dowolne instrukcje warunkowe w środku nie powinien przynieść poprawy? Chociaż nie wiem, czy akurat to pomoże zrefaktoryzować wzorce używane do SFINAE...
Remedium na nadużywanie SFINAE mają być koncepty. Jednak największym problemem przy takich zmianach jest legacy code, który niemal z definicji się nie dostosuje.

Offline albireo

  • Użytkownik

# Grudzień 03, 2014, 13:32:28
Meh. Nadal nie widzę powodu, by traktować interfejs stringa jako coś innego, niż kontener na znaki.
Wiesz, jak zapodasz funkcji w argumencie [[1, 2, 3]] zamiast [1, 2, 3], to też się popsuje...
Problem w tym, że jak w argumencie zamiast ["cos tam"] podam "cos tam" to program przeważnie będzie dalej działał tylko dawał dziwne wyniki, natomiast jak zamiast zamiast [1, 2, 3] podam  [[1, 2, 3]] (czy też odwrotnie) to przeważnie dostanę jakiś wyjątek (np że nie można dodawać inta do listy).

Ale wtedy wprowadzasz zupełnie nową składnię, tylko do tego celu.
Siła obecnego rozwiązania tkwi w prostocie - indeksem może być wyrażenie.
Gdzie ty tu widzisz nową składnię, przecież End (nawet jakby nazywał się $) to byłby normalny obiekt którego też można użyć w wyrażeniach (to że w D to hack, to inna sprawa). Co więcej nawet da się go zaimplementować teraz (chociaż nie można by go nazwać $), implementacja na szybko:
Kod: (python) [Zaznacz]
class EndType:
  def __init__(self, offset=0):
    self._offset = offset

  def __sub__(self, other):
     if type(other) != int:
       raise TypeError
     return EndType(self._offset - other)
  def __add__(self, other):
     if type(other) != int:
       raise TypeError
     return EndType(self._offset + other)
  # ewentualnie zaimplementować jeszcze inne operatory
  def __index__(self):
     if self._offset >= 0:
       return 99999999999999999999999999 # duża liczba, żeby slicing działał poprawnie, lepszy byłby None, ale interpreter sprawdza typ
     return self._offset

End = EndType()
Tyle że samo to nie rozwiązuje podstawowego problemu, że "asdsad"[-1] nie zwraca błędu.

Offline Xirdus

  • Redaktor

  • +1
# Grudzień 03, 2014, 15:09:54
Problem w tym, że jak w argumencie zamiast ["cos tam"] podam "cos tam" to program przeważnie będzie dalej działał tylko dawał dziwne wyniki, natomiast jak zamiast zamiast [1, 2, 3] podam  [[1, 2, 3]] (czy też odwrotnie) to przeważnie dostanę jakiś wyjątek (np że nie można dodawać inta do listy).
Po to są unit testy, żeby wyłapać i jedno i drugie.

Offline bies

  • Użytkownik

  • +1
# Grudzień 03, 2014, 16:20:16
Po to są unit testy, żeby wyłapać i jedno i drugie.
Słaby argument. Można go sprowadzić do absurdu wnioskując, że skoro są unit testy to statyczne typowanie jest niepotrzebne.