Głupie C#

Musiałem napisać pewną rzecz, niestety musiało toto działać pod windowsem. Kombinować z różnymi py2exe mi się nie chciało, bo (a) pewnie by wyszła ogromna binarka i (b) cholera wie jak by to w praktyce działało i ile czasu bym na uruchamianiu tego spędził. Poszedłem więc po najmniejszej linii oporu, czyli skorzystałem z faktu, że mam w systemie zainstalowane mono i kompilator c#. Oj.

Pomijam już standardowe upierdliwości tego typu języków -- np. musiałem sobie 'emulować' zwykły język z nieobiektowymi funkcjami deklarując wszystkie metody głównej klasy jako statyczne (gdzieś kiedyś czytałem, że do kursu podstaw programowania obiektowego wybrali C++ właśnie dlatego, że tam można po prostu napisać main() i mieć zwykły, nieklasowy kod), albo wkurzająca ilość klepania w klawisze, jaka jest wymagana. To jeszcze nic. Zabił mnie standardowy framework .netowy. Python został pomyślany tak, żeby te kilka wbudowanych typów danych dawało się połączyć ze sobą tak, że wystarczają w 99% zastosowań. Na dodatek daleko posunięta standaryzacja interfejsów do komunikacji z różnymi obiektami spodowowała, że praktycznie zawsze wiem jak czegoś użyć. No i ta łatwość ciachania stringów. A w .necie? Szukałem w standardowym typie tablicowym jakiegoś odpowiednika appenda. SetValue wyglądał obiecująco, ale w końcu nie doszedłem do tego, jak to działa. Na szczęście znalazłem typ ArrayList, który miał metodę Add. W trakcie kodowania była zabawa. Rozmiar tablicy (System.Array) się sprawdza nazwatablicy.Length. Rozmiar ArrayLista się sprawdza nazwaarraylista.Count. Tablicę się sortuje System.Array.Sort(nazwatablicy). ArrayLista się sortuje nazwaarraylista.Sort(). Ja nie wykluczam, że to na jakimś poziomie abstrakcji kieruje się jakąś logiką, ale dla mnie to jest zwykłe (wkurwiające) marnowanie mojego czasu. Każdy cholerny typ muszę obmacać, żeby się dowiedzieć w jaki sposób implementuje podstawową funkcjonalność. Pewnie się jeszcze okaże, że gdzieś tam istnieje głęboko ukryty typ, który łączy najwygodniejsze cechy ArrayLista i Arraya. Nikt tym baranom nigdy nie powiedział, że żeby obiekty były rzeczywiście wygodne w użyciu, to muszą być jak najbardziej intuicyjne?

Muszę jednak pochwalić za zrobienie instrukcji foreach. Dla mnie, przyzwyczajonego obecnie do pythonowego fora, było to właściwie jedyne światełko w tunelu. Jednak cała reszta... brrrr. Jak patrzę na ten kod, w którym 50% zawartości to tylko literki zadowalające kompilator (no i oczywiście trzeba pilnować, żeby co chwilę użyć jakiejś dużej litery, bo taki tu jest styl nazewnictwa), ale nie wnoszące nic do funkcjonalności, to mnie trzepie. Ani to czytelne, ani wygodne w użyciu. "Powinni tego zabronić."

  1. 1. doza

    za to boo rządzi :) szkoda tylko, że jeszcze ciut niedopracowane

  2. 2. MiMaS

    Hint: sytuację poprawia spojrzenie na ArrayList jak na kolekcję, nie tablicę...

  3. 3. nazgul

    polecam:
    monop System.Array
    monop System.Collections.ArrayList

    Jak w każdym środowisku kwestią zasadniczą jest przyzwyczejenie się do bibliotek i języka.
    Tu przynajmniej nie jest tak, że autorzy wbudowali każdą funkcję, która im przyszła na myśl w język tworząc kupę globalnie widocznego śmiecia, gdzie "wszystko jest do wszystkiego"
    ;-)

  4. 4. mmazur

    Ja wiem, że za sposobem działania tych interfejsów stoi jakaś logika (i zapewne gdybym wiedział co to jest kolekcja, to bym rozumiał czemu te obiekty są zrobione tak, a nie inaczej) i jestem prawie pewien, że w standardowej bibliotece .netowej mogę znaleźć typy danych do wszystkiego, czego tylko mógłbym zapragnąć. Tyle tylko, że pierw musiałbym je znaleźć, a później jeszcze dokładnie obadać w jaki sposób się ich używa (i dotyczy to także funkcjonalności, która, przynajmniej dla mnie, intuicyjnie się pokrywa).

    Tak, ja wiem, że to wszystko ma sens i zostało zrobione do konkretnych zastosowań, ale python mnie po prostu rozpieścił jeśli chodzi o podejście 'potrzebuję, siadam i robię' i jak muszę używać .neta, to mną telepie. Zwłaszcza, że nie mam wprawy i spędzam czas na googlaniu za podstawami (jak np. znalezienie typu danych, który robi to, co mi akurat potrzebne). Im prostszy i bardziej intuicyjny jest język, tym przyjemniej się go używa.

    A co do bloatu w pythonie, to herezje waść prawisz. Robiąc nowe wydania pythonowcy właśnie cholernie pilnują, żeby dawać te rzeczywiście potrzebne funkcje i to tak, żeby ich było jak najłatwiej używać. I im się to jak najbardziej udaje :)

  5. 5. doza

    System.Array, tak samo jak string, ma stałą długość (Length),
    natomiast kolekcje mają zwykle zmienną długość (Capacity - zaalokowana ilość miejsca, Count - aktualna liczba elementów)

    Oczywiście, że można to zunifikować - ale kosztem wydajności

  6. 6. mmazur

    Python ma read only tupla i zmienną tablicę. Ale dla odmiany obsługuje się je dokładnie tak samo :)

  7. 7. zdzichuBG

    Nie wiesz co to kolekcja i się dziwisz, że nie rozumiesz budowy bilioteki standardowej. Chyba nie tędy droga?
    Zresztą jak już koniecznie musiałeś na .net robić to po co się ,,męczyć'' z językiem którego nie znasz, skoro mogłeś pisać w pajtonie (vide IronPython).

  8. 8. mmazur

    A gdzie ja napisałem, że się dziwię, że nie rozumiem? Wyraźnie kilkukrotnie napisałem, że to zapewne ma sens (przekładając na pythona -- Array == tuble, Collection.ListArray == tablica), tyle że dla mojej wygody priorytet powinna brać ogólnie pojęta standaryzacja i jednorodność interfejsów, a nie fakt, że to jest spójne z jakimiś innymi zasadami.

    (po raz trzeci -- ja *nie* twierdzę, że c# to jest do niczego nie nadający się złom; jestem po prostu rozpieszczony nieupierdliwością i prostotą pythona i mnie drażni używanie języka, który robi jakieś rzeczy nie po mojej myśli 'w imię wyższych celów')

    A co do ironpythona i boo, to powód jest taki sam jak z py2exe -- istniała niezerowa szansa, że tylko stracę czas, bo to nie zadziała, a mi zależało na skończeniu całości w ciągu kilku godzin zważywszy, że już i tak sporo czasu zmarnowałem przy próbach robienia międzymordzia wuwowego (w pythonie właśnie), które okazało się jednak nie spełniać oczekiwań.

  9. 9. nazgul

    a) Zgadzam się, że nazwa na to samo (Length i Count - liczba elementów aktualnie w kolekcji) powinna nazywać się tak samo. Tu IMHO całkiem słusznie masz pretensje, choć obie nazwy są intuicyjne

    b) Problem sprowadza się do znajomości danej biblioteki. Ja czuję takie same obrzydzenie, poczucie bezsensu i kiczowatości, kiedy widzę biblioteki pytonowskie. Człowiek już tak ma, że nie lubi tego co nieznane i do tego musi się męczyć, żeby to poznawać...

    c) .NET był tworzony z myślą o code completion (najlepiej takim inteligentnym jak w VS), które praktycznie eliminuje Twój problem - ciskasz . i po dwóch sekundach wiesz jakiej funkcji użyć.

  10. 10. mmazur

    Hmmm. Co do drugiego punktu, to rzeczywiście musiałbym się mocniej wgryźć w dostępną funkcjonalność. I to jeszcze na dodatek w taki sposób, żeby nie oceniać zawartości .neta poprzez pryzmat bezpośredniego przełożenia na to, jak analogiczną rzecz bym zrobił w pythonie. Może kiedyś, jak już będę miał z kilka projektów c# za sobą. (acz i tak twierdzę, że python w założeniu jest językiem znacznie prostszym i bardziej spójnym)

    A co do dopełniania kodu, to nie wpadło mi do głowy, że teraz przecież wszystkie IDE to mają. A wtedy jest bez różnicy czy pole obiektu nazywa się Size, Length, czy Count, gdyż jak zobaczę listę dostępnych do wyboru pól, to szybko powinienem zlokalizować to, co mnie interesuje.
    To równocześnie 'usprawiedliwia' jeszcze jeden powód mojej irytacji -- że w pythonie mogę sobie po prostu odpalić interpreter w trybie interaktywnym i pooglądać zawartość dowolnej instancji w trakcie działania, a w c# muszę grzebać po dokumentacji. Ano nie muszę, jeśli używam odpowiedniego IDE (a nie vima).

  11. 11. mmazur

    (acz nadal zostaje problem tego, że jakaś metoda może w rzeczywistości być statyczna dla klasy i code completition mi jej nie pokaże... zapewne tak by było w przypadku sorta dla zwykłej tablicy?)

Adde commentarium: (textile lite)