🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.c
486 messages
486 total messages Page 2 of 10 Started by Hoobert Sat, 03 Nov 2007 09:47
Page 2 of 10 • 486 total messages
Re: Ciemna strona C++
#267718
Author: Seweryn Habdank-Wojewódzki
Date: Fri, 09 Nov 2007 22:18
306 lines
12339 bytes
Witam

Czemu zawsze kłócimy się o to samo?

Sebastian Kaliszewski wrote:

>> Wskaźnik przecież może pokazywać na NULL? Przecież wskaźnik nie wie czy
>> obiekt się zmienił (wzorzec obserwator się kłania).
> 
> Jaki obserwator? Obserwator to jest bardzo złe rozwiązanie takiego
> przypadku. Obserwator służy do rozprowadzania zdarzeń (edge triggered) a
> nie udostępniania informacji o bieżącym stanie (level triggered).

Obojętne czy obserwator czy nie. Zapewne masz rację że są lepsze podejścia.
Ale one nie są jedyne. Czy kod który zaproponowałeś poniżej jest jedyny
słuszny? Jeśli tak, to powinien wejść w skład jakiejś biblioteki.

Jeśli nie to ile ma wariantów. Jeśli dużo, to czemu się dziwisz, że lepiej
mieć osobno iterator osobno kontener, a takie coś budować na własne
potrzeby? 

Tobie zawsze coś nie pasuje. ZAWSZE masz 3 ale i 5 że do każdej rzeczy w
C++. W Pythonie są jedyne słuszne rozwiązania np. jedyna słuszna lista i
nie płaczesz? A w ogóle pokaż mi co w Pythonie jest tym Testamentem? W
itertoolsach są różne rzeczy ale testamentu nie widzę, sama lista też nie
ma testamentu?
 
> Nie wiem jak się ten wzorzec nazwa, jeśli nie ma nazwy, to można go nazwać
> Testament :)  (infromacje dla przyjaciół (friends) i innych zstępnych
> zawierające wolę testamentodawcy, również po jego śmierci).

To jest ciekawe.
 
>> Pan F. nie pokazuje jak coś nie działa i jest to zrobione w dobrym stylu
>> C++.
> 
> Użycie iteratorów jest w złym stylu C++ ???

On nie użył iteratora! Wskaźnik to nie iterator. Iterator może być
wskaźnikiem. Taka silna inkluzja zbiorów. Pan F. bawi się wskaźnikami a nie
iteratorem.
 
>> O tak. Każdy iterator powinien być wizytatorem, obserwatorem, kompozytem,
>> mózgiem i wiedzą kodera w jednym.
> 
> Patrz wyżej. To jest proste, tanie i szybkie.

OK, ale IMHO nie jedyne słuszne.
 
>> Iterator przede wszystkim ma być efektywną abstrakcją, a nie kombajnem.
> 
> A potem płacz, że jakiś gówniarz włamał się i wszystko pokasował. Albo, że
> odcieli od Internetu, bo komputer był shackowany i rozsyłał spam.

Ha, ha, ha. ZTCW to włamy są przede wszystkim do websajtów pisanych w PHP.
I soft pisany stylem Pana F. też może robić dziwne rzeczy. Ale styl Pana F.
jest paskudny. Zastanów się i odpowiedz. Czy życzyłbyś sobie takiego kodera
w zespole? Nie zależnie od języka, takie haxory jak popisał Pan F. nadają
się wyłącznie jako podstawa do wysłania go na szkolonko.
 
>> Tak. A i tak kolesie pokroju Pana F. nie używają jej -- przykład tablica
>> obiektów typu foo rzutowana na bar*.
> 
> To czemu język na to pozwala?

A Python pozwala kasować metody, czemu?
Czemu nie ma sekcji prywatnej w klasach?
Czy python zakłada dobrą wolę kodera? Słusznie. 
C++ zakłada, że języka używa wykształcony koder, a nie gamoń.

Nie odpowiadasz na pytania, które są niewygodne, czemu?

>> Poza tym już nie traz narzekałeś na STL więc skąd nagle gadanie o tym,
>> że "zrób se sam" jest złe? Pan F. jak widać STL'a nie używa tak jak to
>> należy robić -- jedyne co potrafi to napisać baziewny kod, aby wykazać,
>> że gcc generuje długie błędy.
> 
> Skąd wiesz czego on używa a czego nie?

Bo przykłady są wyssane z palca! Pisze, że lubi C, a tam takie "haki" są na
porządku dziennym. Do tego, w C++ często da się "hak" zastąpić jakimś
zgrabnym kodem. W C często "hak" to jedyna wersja.
 
> Obraziłeś się, 

W żadnym wypadku, obrażanie się to nie moja domena.

> że najechał na twój kochany język

"Kochany" -- zazwyczaj takie określenie używam względem ludzi.

> i o zgrozo, najazd jest celny.

Celnych jest kilka uwag. Podkreśliłem to! 

I powiedziałem, że dla mnie to jest nic nowego, bo już od Ciebie
dowiedziałem się więcej i na przykładach DUŻO mniej wyssanych z palca. 

Tobie jestem wdzięczny, a Pana F. traktuję jako speca od haków.

>> Do tego właśnie służy CONST!!!
> 
> Co ty wyyślasz???!!?!?!?!?!?!?
> 
> int dupa(int niemodyfikowany, int& modyfikowany);
> 
> gdzie masz jakieś const??!?!

int dupa(int niemodyfikowany    // tu wszyscy orędownicy języków lepszych
                                // podnoszą larum o kopiowanie, 
                                // zatem proponuję to co poniżej
        , int& modyfikowany);

int dupa(type const & niemodyfikowany, type & modyfikowany);
int dupa(POD_type const niemodyfikowany, POD_type & modyfikowany);

int dupa(boost::call_traits<type>::param_type niemodyfikowany, 
        POD_type & modyfikowany);

>> Pokaż mi takie cos jak MPL i SPIRIT w J i w Py.
> 
> W Py masz PyParsing.

To jest odpowiednik spirita, a mpl?
 
> Zamiast zatykającego kompilator i powolnego Spirita wolę użyć Antlr -- da
> mi kod i dla Javy i dla C++ i dla C# i dla Pythona. Szybszy i w kompilacji
> i w wykonaniu niż rzeźba w spiricie.

Super.
 
> MPL to jest chore same w sobie.

Dla Ciebie. Dla mnie nie. Widocznie mamy inne punkty widzenia. Jakbyśmy
mieli takie same, to byśmy się nie kłócili :-D.
 
>> Parsery wszędzie pisze się parszywie.
> 
> Taaa, zwłaszcza w Ocamlu... Albo w Pythonie

W Ocamlu to w ogóle wszystko elegancko się pisze -- język ten zdominował
rynek. Przepraszam, ale wolę Pythona, czy Haskela.
 
>> Więc Twój argument, że Spirit jest
>> potworny jest nietrafiony.
> 
> Do parserów używa się odpowiednich narzędzi. Albo dobrego, a nie kulawego,
> języka :)

Słusznie. Tylko, że pojęcie "dobry/dobrego" należy do dziedziny rozmytych
pojęć -- kłopot polega na tym, że Twoje "dobry" jest inne niż moje.
 
>> Co do MPL. Np. w konstrukcji rozmytego algorytmu predykcyjnego mam
>> kawałki z boost::mpl (dziś lepiej jest używać boost::fusion).
>> 
>> Jest to raczej poprawa czytelności, niż utrudnienie.
> 
> Co?!?! MPL i poprawa czytelności? Bez jaj!

U mnie poprawia :-).

Masz jasno określone, że system wnioskowania/klasyfikacji składa się z
wektora funkcji przynależności, z których każda ma określony typ. To jest
jedna linia. Nic dodać nic odjąć. Jeśli tylko klasyfikator się nie zmienia
w sensie typów to taka konstrukcja jest lepsza niż co innego (zmiana
parametrów funkcji nie zmienia ich typów, tak więc system nadal może się
modyfikować np. uczyć).
 
>>>W C są wyjątki??? iteratory??? desytuktory????
>> 
>> Nie ma. Są za to inne kwiatki.
> 
> Te kwiatki są proste i ograniczone jak samo C.

Nie są, ani proste, ani ograniczone, a zakres błędów który może powstawać
jest duży.
 
> Ale nie wszędzie kod najbardziej oczywisty jest kodem niebezpiecznym i
> niestylowym. To jest domena C++.

Zapewne. To niech lewary nie piszą w C++! Nie wszyscy maja maturę, nie
wszyscy kończą studia, nie wszyscy muszą pisać w C++. 
Nikomu nie każe pisać w C++.

>> Tak? A gdzie to jest normalny zwyczaj?

Nie odpowiedziałeś na to pytanie!

>> Jeśli gdzieś są takie zwyczaje to 
>> kończy się to na posiadaniu GC.
> 
> I dobrze. GC znane jest od ponad 40 lat.

To nie jest odpowiedź na moje pytanie.
 
>> A ciekawie się dzieje, kiedy sam zaczniesz
>> grzebać w tym co robi GC i np. rozgrzebiesz w GC to na czym pracuje GC.
> 
> ?????

Poczytaj o kręceniu przy GC w run-time dla JVM, można naprawdę sobie
wykręcić to i owo.

>> Nie prawda. Zobacz sobie na to:
>> 
>> http://qsorix.jogger.pl/2006/12/14/java-jezyk-pelen-niespodzianek
> 
> I co to ma być? To jest poziom #define private public

I co? Nie da się zrobić brzydala? Da się! I co z tego! 
To nie jest wada J, to jest możliwość, jak chcesz, to z niej korzystasz.
Jak nie, to nie.

Jeden człowiek raz mi powiedział, że dostał w spadku kod, w którym takie coś
należało użyć, bo najprawdopodobniej projekt był zwalony. 
I co on by zrobił gdyby nie mógł tego typu gniota zrobić? Przepisać wszystko
od zera?
 
>> To jest właśnie poziom haków Pana F.
> 
> Nie, pan F. pokazuje rzeczywiste przypadki rzeczywistych kardynalnych
> błędów projektu samego języka, a to jest pokazanie nadużycia mechanizmu
> skąd inąd przydatnego.

Ach tak. A może skądinąd rzutowania rodem z C też są czasem przydatne?
 
>> Zrobić coś nie całkiem tak, jak to się powinno robić, a potem gadać o
>> wadach.
> 
> Co jest niecałkiem tak? UB, gdy masz głupi, prosty błąd użycia iteratora?

Wskaźnik to nie iterator. Tam przede wszystkim pojawia się paskudne
rzutowanie na bar.
 
>>>>47 -- chłopina rzutuje obiekt foo na bar a potem dziwi się, że "mu to
>>>>nie działa".
>>>
>>>Co rzutuje? Przecież to jest "normalny" polimorfizm.
>> 
>> Tak? Jeśli tak piszesz normalne programy. To nie dziwię się, że uciekasz
>> od C++.
> 
> Przykazywany jest wskaźnik na obiekt klasy pochodnej do funkcji
> oczekującej wskaźnika na obiekt klasy bazowej -- to jest *standardowe*
> użycie polimorfizmu. To, że funkcja oczekuje przekazania tablicy, tylko
> przygłupi, kulawy język nie miesza tablice ze wskaźnikami to jest to co
> jest.

To jest spadek z C.
 
> To jest karygodny błąd języka. Tłumaczenie wielbicieli C++, żeby użyć
> ciężkiego wektora 

Ciężkiego? Co Ty opowiadasz? Pokaż, że vector jest ciężki? Wydajność ma
identyczną jak tablica. Rozmiar? 12 bajtów na maszynie 32bity -- gigant.

> czy niewiele lżejszego, ale w ogóle nie należącego do 
> języka boost::array jest poprostu żałosne.

Żałosne? Co jest żałosne? Żałosne jest nieustanne machanie rękami ludzi typu
Pan F. Nie pasuje mu język, to niech go nie używa!
Niektóre wady są pokazane obiektywnie, ale przykładziki w większości to są
badziewia. 

> Mamy język w którym są tablice, ale nie można ich używać, tylko jakiś
> cięzkich typów bibliotecznych, bo język jest spieprzony. To są Jaja na
> Resorach(tm).

Tak. Jaja na resorach. Zrób sobie statystykę ile ludzi używa surowych tablic
w innych językach?

W J mało koderów używa tablic? A wiesz czemu, bo mają ubogą funkcjonalność,
i czesto są niewiele szybsze niż kontenery.

>> C++ zawrapował C bardziej dosłownie niż to robią inne języki, np.
>> CPython. Czy wadą CPythona jest to, że możesz też kod napisać w C?
> 
> Kod w C nie jest kodem w Pythonie.

No to mnie pouczyłeś. Np. takie numpy jest napisane oczywiście w
Pythonie ;-).
 
Wszystko co ma status stabliny i jest wymagana wydajność/oszczędność ramu w
CPythonie jest napisane w C. Wszystko! Czemu?

> Kod w C często jest kodem w C++. 

To jest wina edukacji i legacy people.
 
>>>>Mi to w ogóle ten kod nie działa, a jak go poprawiłem to mi działa
>>>>dobrze.
>>>
>>>Taaaak??!?!?!? O, to ciekawe!
>> 
>> Po prostu wystarczy ten kod napisać sensownie, a nie udowadniając tego co
>> Pan F. chciał wykazać.
> 
> Pan F. zademonstorwał kardynalny błąd w samym środku języka.

No to wracamy do punktu wyjścia :-D.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267719
Author: Tomasz bla Fortuna
Date: Fri, 09 Nov 2007 23:07
95 lines
4746 bytes
Dnia Fri, 09 Nov 2007 23:18:55 +0100
Seweryn Habdank-Wojewódzki <shw_mail@wp.pl> napisał(a):

> Sebastian Kaliszewski wrote:
> >> Pan F. nie pokazuje jak coś nie działa i jest to zrobione w dobrym
> >> stylu C++.
> > 
> > Użycie iteratorów jest w złym stylu C++ ???
> On nie użył iteratora! Wskaźnik to nie iterator. Iterator może być
> wskaźnikiem. Taka silna inkluzja zbiorów. Pan F. bawi się wskaźnikami
> a nie iteratorem.
(Chodziło chyba o przykład z 3 strony.)

> >> Do tego właśnie służy CONST!!!
> > Co ty wyyślasz???!!?!?!?!?!?!?
> > 
> > int dupa(int niemodyfikowany, int& modyfikowany);
> > gdzie masz jakieś const??!?!
> 
> int dupa(int niemodyfikowany    // tu wszyscy orędownicy języków
> lepszych // podnoszą larum o kopiowanie, 
>                                 // zatem proponuję to co poniżej
>         , int& modyfikowany);
> 
> int dupa(type const & niemodyfikowany, type & modyfikowany);
> int dupa(POD_type const niemodyfikowany, POD_type & modyfikowany);
Tylko wywołanie będzie wyglądało i tak w ten sposób:
int a,b; dupa(a,b);

Programista zorientuje się, że coś jest tutaj może być modyfikowane
dopiero jako obejrzy nagłówek dupy, a wskaźniki wymuszą dodanie & i
pisanie:
dupa(a,&b);

co rzuca się bardziej w oczy przy czytaniu kodu.

Z drugiej strony jak często przez by-reference przekazuje się typy
proste? I jak często przekazuje się by-value typy bardziej zlożone?

W rzeczywistości raczej i tak operuje się na wskaźnikach na obiekty i
jedyna możliwość zobaczenia czy te obiekty są modyfikowane to ów const
w nagłówku...

> >> Parsery wszędzie pisze się parszywie.
> > 
> > Taaa, zwłaszcza w Ocamlu... Albo w Pythonie
> 
> W Ocamlu to w ogóle wszystko elegancko się pisze -- język ten
> zdominował rynek. Przepraszam, ale wolę Pythona, czy Haskela.
Może rynek nie ma potrzeb na dobry język do parserów? Jego dominacją
lub nie na pewno nie można wszystkiego tłumaczyć.

No a ocamllex i ocamlyacc jest ok.

> >>>W C są wyjątki??? iteratory??? desytuktory????
> >> 
> >> Nie ma. Są za to inne kwiatki.
> > 
> > Te kwiatki są proste i ograniczone jak samo C.
> 
> Nie są, ani proste, ani ograniczone, a zakres błędów który może
> powstawać jest duży.
>  
> > Ale nie wszędzie kod najbardziej oczywisty jest kodem
> > niebezpiecznym i niestylowym. To jest domena C++.
> 
> Zapewne. To niech lewary nie piszą w C++! Nie wszyscy maja maturę, nie
> wszyscy kończą studia, nie wszyscy muszą pisać w C++. 
> Nikomu nie każe pisać w C++.
> 
Pewnie znacie ten quote. IMHO pasuje jak ulał:
C makes it easy to shoot yourself in the foot; C++ makes it harder, but
when you do, it blows away your whole leg. - Bjarne Stroustrup

C nie jest językiem prostym. Ale trudno tam doprowadzić kod do takiego
stanu, że trzebaby używać hacków/wrapperów i kombinacji wszelakiego
typu żeby naprawić drobny błąd projektowy popełniony na samym
początku.

> > Przykazywany jest wskaźnik na obiekt klasy pochodnej do funkcji
> > oczekującej wskaźnika na obiekt klasy bazowej -- to jest
> > *standardowe* użycie polimorfizmu. To, że funkcja oczekuje
> > przekazania tablicy, tylko przygłupi, kulawy język nie miesza
> > tablice ze wskaźnikami to jest to co jest.
> 
> To jest spadek z C.
Tylko w nim pozwalał na postrzelenie się w stopę, a tu pozwala na
odstrzelenie całej nogi. ;)

Pozdrawiam.
-- 
Tomasz bla Fortuna
jid: bla(at)af.gliwice.pl
pgp: 0x90746E79 @ pgp.mit.edu
www: http://bla.thera.be
Re: Ciemna strona C++
#267723
Author: Jedrzej Dudkiewicz
Date: Sat, 10 Nov 2007 01:03
15 lines
1887 bytes
Seweryn Habdank-Wojewódzki wrote:
>>> Pan F. nie pokazuje jak coś nie działa i jest to zrobione w dobrym stylu
>>> C++.
>> Użycie iteratorów jest w złym stylu C++ ???
> 
> On nie użył iteratora! Wskaźnik to nie iterator. Iterator może być
> wskaźnikiem.

Nie no, Sewery, wskaznik to iterator swobodnego dostepu. Sprawdz w 
standardzie, spelnia wszystkie warunki dla tego typu iteratorow. 
Iterator moze byc wskaznikiem w tym sensie, jak prostokat moze byc 
kwadratem. I zasada podstawienia Liskovej (czy jak tam sie to nazywa 
slicznie) nie stosuje sie tutaj :)

JD
Re: Ciemna strona C++
#267720
Author: Maciej Piechotka
Date: Sat, 10 Nov 2007 09:55
61 lines
2980 bytes
>> >> Do tego właśnie służy CONST!!!
>> > Co ty wyyślasz???!!?!?!?!?!?!?
>> > 
>> > int dupa(int niemodyfikowany, int& modyfikowany); gdzie masz jakieś
>> > const??!?!
>> 
>> int dupa(int niemodyfikowany    // tu wszyscy orędownicy języków
>> lepszych // podnoszą larum o kopiowanie,
>>                                 // zatem proponuję to co poniżej
>>         , int& modyfikowany);
>> 
>> int dupa(type const & niemodyfikowany, type & modyfikowany); int
>> dupa(POD_type const niemodyfikowany, POD_type & modyfikowany);
> Tylko wywołanie będzie wyglądało i tak w ten sposób: int a,b; dupa(a,b);
> 

Hmmm.
1. Czytelne nazwy funkcji
2. Skądś musi wziąść kolejność parametrów funkcji i ich znaczenie. To czy 
parametr jest/może być/nie jest modyfikowany powinno być w pobliżu.

> Programista zorientuje się, że coś jest tutaj może być modyfikowane
> dopiero jako obejrzy nagłówek dupy, a wskaźniki wymuszą dodanie & i
> pisanie:
> dupa(a,&b);
> 
> co rzuca się bardziej w oczy przy czytaniu kodu.
> 

char *c = "test";
const char *d = "test";

void
test(char *cc)
{
  cc[0] = 'c';
}

void
test2(char *dd)
{
  dd[0] = 'd';
}

void
test3()
{
  test(c);
  test(d);
}

OK. W gcc wyrzuca warningi ale przy char * const traktuje się niestety 
dość swobodnie... I nie ma takiej czytelności z &. A z tego co wiem 
konstrukcja w pierwszej linii nie powinna w ogóle być poprawna.


Pozdrawiam
-- 
I've probably left my head... somewhere. Please wait untill I find it.
Homepage (pl_PL): http://uzytkownik.jogger.pl/
(GNU/)Linux User: #425935 (see http://counter.li.org/)
Re: Ciemna strona C++
#267724
Author: Seweryn Habdank-Wojewódzki
Date: Sat, 10 Nov 2007 17:45
24 lines
1862 bytes
Witam

Jedrzej Dudkiewicz wrote:

>> On nie użył iteratora! Wskaźnik to nie iterator. Iterator może być
>> wskaźnikiem.
> 
> Nie no, Sewery, wskaznik to iterator swobodnego dostepu. Sprawdz w
> standardzie, spelnia wszystkie warunki dla tego typu iteratorow.

Spełnia, ale jest niewłaściwie użyty.

> Iterator moze byc wskaznikiem w tym sensie, jak prostokat moze byc
> kwadratem. I zasada podstawienia Liskovej (czy jak tam sie to nazywa
> slicznie) nie stosuje sie tutaj :)

W swoim wnioskowaniu użyłem logiki matematycznej, a nie zasady Liskovej, ale
to jest obojętne.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267721
Author: Seweryn Habdank-Wojewódzki
Date: Sat, 10 Nov 2007 17:48
85 lines
4042 bytes
Witam

Tomasz bla Fortuna wrote:

> (Chodziło chyba o przykład z 3 strony.)

Nie. Cały czas mowa o stronie slajdzie 47.
 
> Tylko wywołanie będzie wyglądało i tak w ten sposób:
> int a,b; dupa(a,b);
> 
> Programista zorientuje się, że coś jest tutaj może być modyfikowane
> dopiero jako obejrzy nagłówek dupy, a wskaźniki wymuszą dodanie & i
> pisanie:
> dupa(a,&b);
> 
> co rzuca się bardziej w oczy przy czytaniu kodu.

A czy NIE możesz użyć wskaźnika?

Tak przy okazji, kiedy w jakiejś metodzie w J przekazujesz cos to skąd wiesz
czy jest modyfikowane, czy nie? 

Możesz wykonać oczywiście operację foo.clone(), ale to powoduje drastyczny
spadek wydajności, bo zawsze tworzysz nowy obiekt -- taka J-wersja
przekazywania parametru przez wartość.
 
> Z drugiej strony jak często przez by-reference przekazuje się typy
> proste? 

Tego nie wiem.

> I jak często przekazuje się by-value typy bardziej zlożone?  
 
Powinno się to robić rzadko. Iterator i smart_ptr są przykładami kiedy tak
właśnie przekazuje się niePOD'a.

> W rzeczywistości raczej i tak operuje się na wskaźnikach na obiekty i
> jedyna możliwość zobaczenia czy te obiekty są modyfikowane to ów const
> w nagłówku...

const poprawia nie tylko czytelność. Również powoduje, że kompilator może
więcej optymalizować.
 
>> >> Parsery wszędzie pisze się parszywie.
>> > 
>> > Taaa, zwłaszcza w Ocamlu... Albo w Pythonie
>> 
>> W Ocamlu to w ogóle wszystko elegancko się pisze -- język ten
>> zdominował rynek. Przepraszam, ale wolę Pythona, czy Haskela.
> Może rynek nie ma potrzeb na dobry język do parserów? Jego dominacją
> lub nie na pewno nie można wszystkiego tłumaczyć.
> 
> No a ocamllex i ocamlyacc jest ok.

Wydaje mi się, że rynek poszedł po najmniejszej linii oporu. Okazało się, że
XML jest średnio dobry do wszystkiego. Napisano parsery XML'a i wszyscy na
tym jadą.

Ci co chcą czegoś więcej piszą sami. Są czasami jakieś wspomagacze, ale są
wszędzie tak samo paskudne (modulo paskudność języka). Po prostu zadanie
parsowania jest samo w sobie trudne.
 
> C nie jest językiem prostym. Ale trudno tam doprowadzić kod do takiego
> stanu, że trzebaby używać hacków/wrapperów i kombinacji wszelakiego
> typu żeby naprawić drobny błąd projektowy popełniony na samym
> początku.

Przede wszystkim w C się robi takie haki. Zresztą jak widać Pan F. wyrósł z
takiej szkoły. Porównaj sobie styl sugerowany przez Pana F. i przez Koenig
i Moo. Zobaczysz jakie są drastyczne różnice.

Tak samo jak Jędrzejowi napiszę i tu:

template <typename T>
void fun(T* tablica)
{
        tablica[0].whatever; // działa dobrze.
}

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267716
Author: Sebastian Kaliszewski
Date: Mon, 12 Nov 2007 16:44
57 lines
3346 bytes
Jedrzej Dudkiewicz wrote:
>> Przykazywany jest wskaźnik na obiekt klasy pochodnej do funkcji 
>> oczekującej wskaźnika na obiekt klasy bazowej -- to jest *standardowe* 
>> użycie polimorfizmu. To, że funkcja oczekuje przekazania tablicy, 
>> tylko przygłupi, kulawy język nie miesza tablice ze wskaźnikami to 
>> jest to co jest.
> 
> Wydaje mi się, że o ile przykład pokazuje prawdziwy problem, to sam jest 
> idiotyczny, tzn. strasznie wydumany. W C++, nawet gdyby tablice były 
> obsługiwane prawidłowo, tj. nie byłoby rzutowania (niejawnego) wskaźnika 
> na tablicę, to ten przykład chyba byłby ciągle marny:
> 
> class A {};
> class B : public A {
> public:
>     void do_me() { };
> };
> 
> B tablica[3];
> 
> void fun(A tablica[])
> {
>     tablica[0].do_me(); // <- co z tym?
> }

To się nie skompiluje z dwu powodów:
1. A nie ma metody do_me(), ale to jest, jak rozumiem, przeoczenie
2. Choć A jest nadtypem B, to w poprawionym C++ tablica A nie jest nadtypem 
tablicy B. Podobnei jak i dziś A** nie jest żadnym nadtypem **B.


> Znaczy - trzebaby niejawnie jakoś konwertować to na wskaźniki... No nie 
> wiem, jakaś porażka. Czyli jeszcze raz - o ile przedstawiony problem 
> jest prawdziwy, to przykład jest całkiem z kosmosu - stąd łatwo się go 
> czepiać.

W dobrym języku przykłąd byłby nierealizowalny bez reinterpet_cast. Dziś 
jest to po prostu dziura w systemie typów.


>> To jest karygodny błąd języka. Tłumaczenie wielbicieli C++, żeby użyć 
>> ciężkiego wektora czy niewiele lżejszego, ale w ogóle nie należącego 
>> do języka boost::array jest poprostu żałosne.
> 
> A co jest ciężkiego w vectorze? To nie zaczepka, tylko ciekawość, żeby 
> nie było.

1. Alokacja sterty
2. Powiększanie.
3. Brak kurczenia.

Np. zastąpienie wektora dedykowaną klasą (ciągle z alokacją sterty, ale z 
lepszym powiększaniem i kurczeniem, zoptymalizowanej do trzymania typów POD) 
dało mi w Śmieciuchu++ zysk rzędu 30%.

pzdr
\SK
Re: Ciemna strona C++
#267696
Author: Marcin ‘Qrczak’ Kowalczyk
Date: Mon, 12 Nov 2007 16:55
16 lines
1986 bytes
Dnia 12-11-2007, Pn o godzinie 17:46 +0100, Sebastian Kaliszewski pisze:

> >>> A co jest ciężkiego w vectorze?

> I kopiuje (po to żeby zaraz oryginał odstrzelić).

W C++0x będzie przenosił zamiast kopiować. To będzie ważna poprawa w tym
temacie, która po pierwsze umożliwi wektory obiektów niekopiowalnych
(wystarczy, żeby były przenaszalne), a po drugie znacznie przyspieszy
realokację wektora obiektów z doczepionymi dużymi podobiektami (np.
wektora wektorów).

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: Ciemna strona C++
#267725
Author: Sebastian Kaliszewski
Date: Mon, 12 Nov 2007 17:58
341 lines
12730 bytes
Witam

Seweryn Habdank-Wojewódzki wrote:
> Czemu zawsze kłócimy się o to samo?

Fatum? ;)


>>>Wskaźnik przecież może pokazywać na NULL? Przecież wskaźnik nie wie czy
>>>obiekt się zmienił (wzorzec obserwator się kłania).
>>
>>Jaki obserwator? Obserwator to jest bardzo złe rozwiązanie takiego
>>przypadku. Obserwator służy do rozprowadzania zdarzeń (edge triggered) a
>>nie udostępniania informacji o bieżącym stanie (level triggered).
> 
> 
> Obojętne czy obserwator czy nie. Zapewne masz rację że są lepsze podejścia.
> Ale one nie są jedyne. Czy kod który zaproponowałeś poniżej jest jedyny
> słuszny? Jeśli tak, to powinien wejść w skład jakiejś biblioteki.

To jest wzorzec (konkretniej przykład zastosowania wzorca) -- wzorce mają to 
do siebie, że słabo wchodzą w skład jakiejś biblioteki (chyba że mówimy o 
bibliotece książek). Bo w niektórych kontenerach wystarczy w testamencie 
bool, a w innych przyda się jakaś dodatkowa informacja (np. zakres, przy 
czym zmiana zakresu nie musi oznaczać uniważnienia iteratorów).

> Jeśli nie to ile ma wariantów. Jeśli dużo, to czemu się dziwisz, że lepiej
> mieć osobno iterator osobno kontener, a takie coś budować na własne
> potrzeby? 

Do istniejących kontenerów tego już się nie daje sensownie dołożyć. To musi 
być wbudowane, rozłożone pomiędzy kontener i pasujące do niego iteratory (bo 
  w C++ masz często 4 typy iteratorów dla jednego typu kontenera: forward i 
reverse, oba w wersji const i non-const),


> Tobie zawsze coś nie pasuje. ZAWSZE masz 3 ale i 5 że do każdej rzeczy w
> C++.

???

> W Pythonie są jedyne słuszne rozwiązania np. jedyna słuszna lista i
> nie płaczesz?

W Pythonie mam rozwiązania bardziej elastyczne. W C++ std niby jest 
konfigurowalne i w ogóle, ale jak przyjdzie co do czego to użycie wersji 
niebazowych idzie jak po grudzie (bo np. do niczego te niebazowe wersje nie 
pasują)


> A w ogóle pokaż mi co w Pythonie jest tym Testamentem? W
> itertoolsach są różne rzeczy ale testamentu nie widzę, sama lista też nie
> ma testamentu?

W Pythonie iterator zna blisko obiekt iterowany i nie ma invalidacji 
iteratorów. W Pythonie nie ma też problemu z przedwczesną śmiercią obiektu 
iterowanego (dzięki GC).


>>>Pan F. nie pokazuje jak coś nie działa i jest to zrobione w dobrym stylu
>>>C++.
>>
>>Użycie iteratorów jest w złym stylu C++ ???
> 
> On nie użył iteratora!

Jak nie jak użył?

Coś mi się zdaje, że zapomniałeś o której stornie pisałeś.


>>>Iterator przede wszystkim ma być efektywną abstrakcją, a nie kombajnem.
>>
>>A potem płacz, że jakiś gówniarz włamał się i wszystko pokasował. Albo, że
>>odcieli od Internetu, bo komputer był shackowany i rozsyłał spam.
> 
> 
> Ha, ha, ha. ZTCW to włamy są przede wszystkim do websajtów pisanych w PHP.

Włąmy to są przede wszystkim na domowe pecety, chodzące pod kontrolą softu 
pewnego dużego producenta pisanego głównie w C i C++.

To stąd jest rozsyłany spam, wykonywane ataki ddos, itd. Tędy też rozłażą 
się robale i wirusy.


>>>Tak. A i tak kolesie pokroju Pana F. nie używają jej -- przykład tablica
>>>obiektów typu foo rzutowana na bar*.
>>
>>To czemu język na to pozwala?
> 
> A Python pozwala kasować metody, czemu?

Bo jest dynamiczny.

> Czemu nie ma sekcji prywatnej w klasach?

Została uznana za zbędną w języku o filozofii jaką reprezentuje Python

> Czy python zakłada dobrą wolę kodera? Słusznie. 

Tak.

> C++ zakłada, że języka używa wykształcony koder, a nie gamoń.

C++ zakłada, że koder zna wszystkie pułapki. W Pythonie droga hackerska jest 
praktycznie zawsze trudniejsza od drogi rozsądnej, oczywistej.
W C++ z zasady droga oczywista jest ścieżką na manowce.


> Nie odpowiadasz na pytania, które są niewygodne, czemu?
> 
> 
>>>Poza tym już nie traz narzekałeś na STL więc skąd nagle gadanie o tym,
>>>że "zrób se sam" jest złe? Pan F. jak widać STL'a nie używa tak jak to
>>>należy robić -- jedyne co potrafi to napisać baziewny kod, aby wykazać,
>>>że gcc generuje długie błędy.
>>
>>Skąd wiesz czego on używa a czego nie?
> 
> 
> Bo przykłady są wyssane z palca!

Przykłady mają na celu pokazanie konkretnych błędnych lub błędogennych 
rozwiązań.

> Pisze, że lubi C, a tam takie "haki" są na
> porządku dziennym. Do tego, w C++ często da się "hak" zastąpić jakimś
> zgrabnym kodem. W C często "hak" to jedyna wersja.

Przy hakach z C++ to to jest zabawa.


>>>Pokaż mi takie cos jak MPL i SPIRIT w J i w Py.
>>
>>W Py masz PyParsing.
> 
> To jest odpowiednik spirita, a mpl?

W języku dynamicznym cały język to mpl.


>>MPL to jest chore same w sobie.
> 
> Dla Ciebie. Dla mnie nie. Widocznie mamy inne punkty widzenia. Jakbyśmy
> mieli takie same, to byśmy się nie kłócili :-D.

MPL to jest nadużycie przypadkowej Turing-completeness szablonów. Jest więc 
dziwne w użyciu a rzucane błędy kompilatora są "zabawne". No i zobaczyć 
build aplikacji trwający 3 dni -- bezcenne :)


>>>Parsery wszędzie pisze się parszywie.
>>
>>Taaa, zwłaszcza w Ocamlu... Albo w Pythonie
> 
> W Ocamlu to w ogóle wszystko elegancko się pisze -- język ten zdominował
> rynek. Przepraszam, ale wolę Pythona, czy Haskela.

W Haskelu też będzie łatwo.


>>>>W C są wyjątki??? iteratory??? desytuktory????
>>>
>>>Nie ma. Są za to inne kwiatki.
>>
>>Te kwiatki są proste i ograniczone jak samo C.
> 
> Nie są, ani proste, ani ograniczone, a zakres błędów który może powstawać
> jest duży.

Ale te same błędy w C++ zostają przykryte kołderką (również pełną dziur) 
wyżejpoziomowych abstracji.

W C druty i bebechy są na wierzchu. Jak coś się wali to mechanizm tego jest 
też na wierzchu. W C++ już nie ma tak lekko.


>>Ale nie wszędzie kod najbardziej oczywisty jest kodem niebezpiecznym i
>>niestylowym. To jest domena C++.
> 
> Zapewne. To niech lewary nie piszą w C++! Nie wszyscy maja maturę, nie
> wszyscy kończą studia, nie wszyscy muszą pisać w C++. 
> Nikomu nie każe pisać w C++.

Ale przez te wszystkie nieoczywiste drogi, nawet nie-lewary popełniają, 
często bardzo poważne a zarazem trudne do znalezienia, błędy.


>>>Tak? A gdzie to jest normalny zwyczaj?
> 
> Nie odpowiedziałeś na to pytanie!

W większości języków. W C++ problem własności urasta do jednego z 
najważniejszych -- zupełnie niepotrzebnie, ale taki jest projekt(?) języka.


>>>Jeśli gdzieś są takie zwyczaje to 
>>>kończy się to na posiadaniu GC.
>>
>>I dobrze. GC znane jest od ponad 40 lat.
> 
> To nie jest odpowiedź na moje pytanie.

Problem własności rozwiązauje się właśnie za pomocą GC, lub reference countingu.


>>>To jest właśnie poziom haków Pana F.
>>
>>Nie, pan F. pokazuje rzeczywiste przypadki rzeczywistych kardynalnych
>>błędów projektu samego języka, a to jest pokazanie nadużycia mechanizmu
>>skąd inąd przydatnego.
> 
> Ach tak. A może skądinąd rzutowania rodem z C też są czasem przydatne?

Rzutpowania rodem z C nic ciekawego nie wnoszą.



>>>Zrobić coś nie całkiem tak, jak to się powinno robić, a potem gadać o
>>>wadach.
>>
>>Co jest niecałkiem tak? UB, gdy masz głupi, prosty błąd użycia iteratora?
> 
> Wskaźnik to nie iterator. Tam przede wszystkim pojawia się paskudne
> rzutowanie na bar.

Zapomniałeś o którym slajdzie pisałeś.


>>>>>47 -- chłopina rzutuje obiekt foo na bar a potem dziwi się, że "mu to
>>>>>nie działa".
>>>>
>>>>Co rzutuje? Przecież to jest "normalny" polimorfizm.
>>>
>>>Tak? Jeśli tak piszesz normalne programy. To nie dziwię się, że uciekasz
>>>od C++.
>>
>>Przykazywany jest wskaźnik na obiekt klasy pochodnej do funkcji
>>oczekującej wskaźnika na obiekt klasy bazowej -- to jest *standardowe*
>>użycie polimorfizmu. To, że funkcja oczekuje przekazania tablicy, tylko
>>przygłupi, kulawy język nie miesza tablice ze wskaźnikami to jest to co
>>jest.
> 
> To jest spadek z C.

skoro tak, to należało wprowadzić odpowiednie dynamiczne mechanizmy 
pilnowania porządku. A nie zbyć sprawę UBekiem.


>>To jest karygodny błąd języka. Tłumaczenie wielbicieli C++, żeby użyć
>>ciężkiego wektora 
> 
> Ciężkiego? Co Ty opowiadasz? Pokaż, że vector jest ciężki? Wydajność ma
> identyczną jak tablica.

LOL!

1. Wektor oznacza adresowanie pośrenie, tablica niekoniecznie (albo w 
najgorszym przypadku wzgłedem stosu) -- procesory OOO obsługują tablice 
nieco szybciej.
2. Jeśli weźmiesz mechanizmy dynamiczne, to tu masz kolejne, poważne 
spowolnienie, w dodatku algorytm zmniejszania rozmiaru jest arbitralny (a co 
jest dobre do wszystkiego nie jest dobre w niczym). Jeśli wektor szybko 
rośnie to typowa implementacja rośnie ze zbyt małymi krokami, jeśli zaś 
rośnie wolno to średnio jest 50% marnowanie pamięci. Jak maleje, to 
marnotrastwo może być dowolnie duże.

> Rozmiar? 12 bajtów na maszynie 32bity -- gigant.

Plus zaalokowany kawał pamięci ze sterty, kawał który jest alokowany, 
dealkowany, gdzie woła się tony konstruktorów kopiujących, itd.

Jak w Śmieciuchu zastąpiłem vector włąsną klasą to miałem zysk wydajności ok 
30%.


>>czy niewiele lżejszego, ale w ogóle nie należącego do 
>>języka boost::array jest poprostu żałosne.
> 
> 
> Żałosne? Co jest żałosne? Żałosne jest nieustanne machanie rękami ludzi typu
> Pan F. Nie pasuje mu język, to niech go nie używa!
> Niektóre wady są pokazane obiektywnie, ale przykładziki w większości to są
> badziewia. 

Przykładziki pokazują problemy a nie styl kodowania mający na celu te 
problem obchodzić.


>>Mamy język w którym są tablice, ale nie można ich używać, tylko jakiś
>>cięzkich typów bibliotecznych, bo język jest spieprzony. To są Jaja na
>>Resorach(tm).
> 
> Tak. Jaja na resorach. Zrób sobie statystykę ile ludzi używa surowych tablic
> w innych językach?

W tych dobrych? Tylko perwerci nie używają.

> 
> W J mało koderów używa tablic? A wiesz czemu, bo mają ubogą funkcjonalność,
> i czesto są niewiele szybsze niż kontenery.

A od kiedy uważam J za dobry język? Toż to przerośnięte, ciężkie krówsko, 
typowy overdesign.


>>>C++ zawrapował C bardziej dosłownie niż to robią inne języki, np.
>>>CPython. Czy wadą CPythona jest to, że możesz też kod napisać w C?
>>
>>Kod w C nie jest kodem w Pythonie.
> 
> 
> No to mnie pouczyłeś. Np. takie numpy jest napisane oczywiście w
> Pythonie ;-).

Chodzi o to, że Python nie cierpi tak jak C++ z powodu śmieci z C.

>>Kod w C często jest kodem w C++. 
> 
> To jest wina edukacji i legacy people.

Ależ skąd. Wiele programów w C to programy zarazem w C++.


>>>>>Mi to w ogóle ten kod nie działa, a jak go poprawiłem to mi działa
>>>>>dobrze.
>>>>
>>>>Taaaak??!?!?!? O, to ciekawe!
>>>
>>>Po prostu wystarczy ten kod napisać sensownie, a nie udowadniając tego co
>>>Pan F. chciał wykazać.
>>
>>Pan F. zademonstorwał kardynalny błąd w samym środku języka.
> 
> No to wracamy do punktu wyjścia :-D.

:)

pzdr
\SK
Re: Ciemna strona C++
#267722
Author: Sebastian Kaliszewski
Date: Mon, 12 Nov 2007 18:01
31 lines
2130 bytes
Seweryn Habdank-Wojewódzki wrote:
> Witam
> 
> Tomasz bla Fortuna wrote:
> 
> 
>>(Chodziło chyba o przykład z 3 strony.)
> 
> 
> Nie. Cały czas mowa o stronie slajdzie 47.
>  

Ależ skąd. Straciłeś "tracking" :)

[...]
> const poprawia nie tylko czytelność. Również powoduje, że kompilator może
> więcej optymalizować.

To jest urban legend. Bo const to nie cecha obiektu tylko konkretnej 
referencji nań.

[...]
> Ci co chcą czegoś więcej piszą sami. Są czasami jakieś wspomagacze, ale są
> wszędzie tak samo paskudne (modulo paskudność języka). Po prostu zadanie
> parsowania jest samo w sobie trudne.

Eeee tam(tm) -- trzeba użyć dobrych narzędzi i jest Piece of Cake(tm).


pzdr
\SK
Re: Ciemna strona C++
#267697
Author: Seweryn Habdank-Wojewódzki
Date: Mon, 12 Nov 2007 21:13
39 lines
2578 bytes
Witam

Sebastian Kaliszewski wrote:

> Piotr Wyderski wrote:
>>>> A co jest ciężkiego w vectorze?
>>>
>>> Waży 12 bajtów?
>> 
>> Alokuje. I zwalnia.
> 
> I robi to w arbitralny, niekontrolowany sposób.

To jest nie istotne w zadaniu, które było tematem slajdu 47.

Proszę nie zmieniaj tematu na ogólne właściwości wektora. W tym konkretnym
przypadku jedyna wada, to taka, że alokuje, chociaż też nie jest to do
końca parszywe, bo możesz napisać swój alokator używający alokacji na
stosie co będzie identyczne z alokacją oferowaną przez otwarcie { i }.

Ale wracając do zadania, w innym miejscu tego wątku podałem rozwiązanie tego
zadania utrzymując konwencję tablic i całego ich spadku. 

Już nie ma żadnych problemów, a Pana F. nadal uważam za dywersanta i
mąciwodę. 

BTW, jego zadanie rozwiązywane jest poprzez dopisanie 1 (słownie jednej)
linii i zmienienie jednego typu na ogólniejszy. Co jeszcze bardziej
wskazuje na fakt, że Pan F. jest zadymiarzem, a o szablonach ma pojęcie
tylko takie, aby wykazywać, że produkują długie błędy.

Szkoda tylko, że to proste rozwiązanie tak późno odkryłem nie miałbyś
tematu, aby nadawać na wektory i na insze sprawy w ++.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267726
Author: Piotr Wyderski
Date: Mon, 12 Nov 2007 21:21
30 lines
2679 bytes
Sebastian Kaliszewski wrote:

>  W C++ std niby jest konfigurowalne i w ogóle, ale jak przyjdzie co do
> czego to użycie wersji niebazowych idzie jak po grudzie (bo np. do
> niczego te niebazowe wersje nie pasują)

Już nakarmione niestandardowo głupie stringi i streamy są problemem.

> 1. Wektor oznacza adresowanie pośrenie, tablica niekoniecznie (albo w 
> najgorszym przypadku wzgłedem stosu) -- procesory OOO obsługują tablice 
> nieco szybciej.

Pointer chasing.

> 2. Jeśli weźmiesz mechanizmy dynamiczne, to tu masz kolejne, poważne 
> spowolnienie, w dodatku algorytm zmniejszania rozmiaru jest arbitralny (a 
> co jest dobre do wszystkiego nie jest dobre w niczym). Jeśli wektor szybko 
> rośnie to typowa implementacja rośnie ze zbyt małymi krokami, jeśli zaś 
> rośnie wolno to średnio jest 50% marnowanie pamięci. Jak maleje, to 
> marnotrastwo może być dowolnie duże.

I tu się zastanawiam, czy patentować metodę alokacji tablic
przechowujących informację o kolumnach bazodanowych
która ma wbudowany predyktor rozmiaru następnego
bloku oparty na średniej wykładniczej. Wydajne to jest
niesamowicie i szybko się uczy wzorców użycia. :-)

    Pozdrawiam
    Piotr Wyderski
 
Re: Ciemna strona C++
#267727
Author: Seweryn Habdank-Wojewódzki
Date: Mon, 12 Nov 2007 21:33
48 lines
3179 bytes
Witam

Piotr Wyderski wrote:

> Sebastian Kaliszewski wrote:
> 
>>  W C++ std niby jest konfigurowalne i w ogóle, ale jak przyjdzie co do
>> czego to użycie wersji niebazowych idzie jak po grudzie (bo np. do
>> niczego te niebazowe wersje nie pasują)
> 
> Już nakarmione niestandardowo głupie stringi i streamy są problemem.
> 
>> 1. Wektor oznacza adresowanie pośrenie, tablica niekoniecznie (albo w
>> najgorszym przypadku wzgłedem stosu) -- procesory OOO obsługują tablice
>> nieco szybciej.
> 
> Pointer chasing.
> 
>> 2. Jeśli weźmiesz mechanizmy dynamiczne, to tu masz kolejne, poważne
>> spowolnienie, w dodatku algorytm zmniejszania rozmiaru jest arbitralny (a
>> co jest dobre do wszystkiego nie jest dobre w niczym). Jeśli wektor
>> szybko rośnie to typowa implementacja rośnie ze zbyt małymi krokami,
>> jeśli zaś rośnie wolno to średnio jest 50% marnowanie pamięci. Jak
>> maleje, to marnotrastwo może być dowolnie duże.
> 
> I tu się zastanawiam, czy patentować metodę alokacji tablic
> przechowujących informację o kolumnach bazodanowych
> która ma wbudowany predyktor rozmiaru następnego
> bloku oparty na średniej wykładniczej. Wydajne to jest
> niesamowicie i szybko się uczy wzorców użycia. :-)

Tak nawiązując do obu postów (Sebastiana i Piotra), ciekawy jestem jakie
mądrości siedzą w kontenerach Pythona. Może nic już nie można patentować,
bo wszystko opatentowane jest w Py3k.

To co jest pewne, to że Py3k będzie alokowało 2x tyle ramu co Py 2.x, dla
tego samego zbioru danych.

Do Piotra. Czy tą średnią masz dobraną na podstawie wyznaczania optymalnego
estymatora średniej dla konkretnego rozkładu żądań rozmiaru? 
Czy doświadczenie podpowiedziało Ci aby takiej średniej użyć? Np. dla
rozkładu lognormal optymalnym estymatorem jest średnia harmoniczna.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267745
Author: Seweryn Habdank-Wojewódzki
Date: Mon, 12 Nov 2007 22:28
257 lines
10805 bytes
Witam

Sebastian Kaliszewski wrote:

> Witam
> 
> Seweryn Habdank-Wojewódzki wrote:
>> Czemu zawsze kłócimy się o to samo?
> 
> Fatum? ;)

No to mamy pecha :-D.
 
>> W Pythonie są jedyne słuszne rozwiązania np. jedyna słuszna lista i
>> nie płaczesz?
> 
> W Pythonie mam rozwiązania bardziej elastyczne.

A jaka niby elastyczność jest zaimplementowana w Pythonowej liście?

>> A w ogóle pokaż mi co w Pythonie jest tym Testamentem? W
>> itertoolsach są różne rzeczy ale testamentu nie widzę, sama lista też nie
>> ma testamentu?
> 
> W Pythonie iterator zna blisko obiekt iterowany i nie ma invalidacji
> iteratorów. W Pythonie nie ma też problemu z przedwczesną śmiercią obiektu
> iterowanego (dzięki GC).

Przedwczesną, co to niby znaczy? Jak masz kontener i zanim związany
iterator, to możesz tak jak w metodzie erase dla listy, zwrócić wskaźnik na
następny element.

Natomiast *dokładnie* to co zrobiłeś w testamencie nie widzę w Pythonie, ale
pewnie słabo patrzę.
 
> Coś mi się zdaje, że zapomniałeś o której stornie pisałeś.

Cały czas pisze o 47.
 
> Włąmy to są przede wszystkim na domowe pecety, chodzące pod kontrolą softu
> pewnego dużego producenta pisanego głównie w C i C++.

Rozumiem że mówisz o UNIX np: Linux, Solaris, AIX czy HP-UX prawda? ;-)

>>>>Tak. A i tak kolesie pokroju Pana F. nie używają jej -- przykład tablica
>>>>obiektów typu foo rzutowana na bar*.
>>>
>>>To czemu język na to pozwala?
>> 
>> A Python pozwala kasować metody, czemu?
> 
> Bo jest dynamiczny.
> 
>> Czemu nie ma sekcji prywatnej w klasach?
> 
> Została uznana za zbędną w języku o filozofii jaką reprezentuje Python
> 
>> Czy python zakłada dobrą wolę kodera? Słusznie.
> 
> Tak.
> 
>> C++ zakłada, że języka używa wykształcony koder, a nie gamoń.
> 
> C++ zakłada, że koder zna wszystkie pułapki.

NIE. To co Pokazał Pan F. nie jest w duchu C++. Jedynym częstym błędem
popełnianym w C/C++ to jest ufność, że znamy długość tablicy.

To jest jedyny naturalny błąd. Reszta błędów wynika albo z syfiastego stylu
kodowania np. szkoła Pana F., albo niedouczenia n00by używają char *
zamiast stringa. Podkreślam n00by, bo w tych przypadkach użycie char *
wynika nie z celowego sposobu kodowania, ale z faktu, że ktoś kiedyś kupił
książkę do C coś przeczytał, nie przeczytał, że C ma specjalne utilki do
pracy na char * i teraz robi w kodzie dziwy nad dziwami.

Kolejny błąd n00by to jest bałaganiarstwo w rzutowaniach. Raz używa typu
size_t, drugi raz int, innym razem long, a jeszcze innym unsigned short.

A błędy pokazywane przez Pana F nie pochodzą z kursu dla n00bów, to są
bardzo wysublimowane i spreparowane przykładziki.

> MPL to jest nadużycie przypadkowej Turing-completeness szablonów. Jest
> więc dziwne w użyciu a rzucane błędy kompilatora są "zabawne". No i
> zobaczyć build aplikacji trwający 3 dni -- bezcenne :)

Prosiłem o przykład. 

Podałeś, że 3 linie kompilują się 1 dzień, teraz mówisz o trzech dniach,
rozumiem, że mowa o 9 liniach. Jednak nie pokazałeś ich.
 
>>>Ale nie wszędzie kod najbardziej oczywisty jest kodem niebezpiecznym i
>>>niestylowym. To jest domena C++.
>> 
>> Zapewne. To niech lewary nie piszą w C++! Nie wszyscy maja maturę, nie
>> wszyscy kończą studia, nie wszyscy muszą pisać w C++.
>> Nikomu nie każe pisać w C++.
> 
> Ale przez te wszystkie nieoczywiste drogi, nawet nie-lewary popełniają,
> często bardzo poważne a zarazem trudne do znalezienia, błędy.

Zgadza się. Chociaż dokładnie to samo czuję pisząc w Pythonie (zapewne nie
spełniam poprzednika implikacji -- jestem PyLewar :-) )

Ot takie "specjalistyczne" sprawy związane z użyciem range vs. xrange.
Używając range szybko giniesz. Jest adnotacja, że by używać xrange. To samo
jest w C++. Czegoś używasz, bo wydaje się być naturalne, ale adnotacja w
książce wskazuje jaka powinna być droga.
 
>>>>Jeśli gdzieś są takie zwyczaje to
>>>>kończy się to na posiadaniu GC.
>>>
>>>I dobrze. GC znane jest od ponad 40 lat.
>> 
>> To nie jest odpowiedź na moje pytanie.
> 
> Problem własności rozwiązauje się właśnie za pomocą GC, lub reference
> countingu.

No więc w C++ będziesz miał smart_ptr, na razie są one w boost (i nie tylko
np. g++ ma już w sobie mocną wersję tr1).

>>>>To jest właśnie poziom haków Pana F.
>>>
>>>Nie, pan F. pokazuje rzeczywiste przypadki rzeczywistych kardynalnych
>>>błędów projektu samego języka, a to jest pokazanie nadużycia mechanizmu
>>>skąd inąd przydatnego.
>> 
>> Ach tak. A może skądinąd rzutowania rodem z C też są czasem przydatne?
> 
> Rzutpowania rodem z C nic ciekawego nie wnoszą.

Właśnie to jest ustalane w innym wątku. Mnie osobiście np. niejawne
konwersje denerwują, ale to jest domena kompilatora, aby rzucał
ostrzeżenia/błędy przy ewidentnie niewłaściwych rzutowaniach.

A czy w noszą, czy nie. To nie wiem. np. przesyłanie danych binarnych, tak
właśnie robisz. 

Bardzo mi się podoba implementacja tego typu rzutowań w Pythonie (moduł
fpconst). Tam jest typowe rodem z C wpakowywanie danych binarnych.
I nie mówię tego z przekąsem, bo moduł właśnie dzięki takiemu sposobowi
podejścia do kodowania jest prosto napisany i działa bardzo dobrze.
 
>>>>Zrobić coś nie całkiem tak, jak to się powinno robić, a potem gadać o
>>>>wadach.
>>>
>>>Co jest niecałkiem tak? UB, gdy masz głupi, prosty błąd użycia iteratora?
>> 
>> Wskaźnik to nie iterator. Tam przede wszystkim pojawia się paskudne
>> rzutowanie na bar.
> 
> Zapomniałeś o którym slajdzie pisałeś.

Cały czas piszę o 47. Ten slajd jest dla mnie szczytem hakerstwa (w sensie
lokalnego maksimum w obrębie slajdów Pana F.).
 
>>>Przykazywany jest wskaźnik na obiekt klasy pochodnej do funkcji
>>>oczekującej wskaźnika na obiekt klasy bazowej -- to jest *standardowe*
>>>użycie polimorfizmu. To, że funkcja oczekuje przekazania tablicy, tylko
>>>przygłupi, kulawy język nie miesza tablice ze wskaźnikami to jest to co
>>>jest.
>> 
>> To jest spadek z C.
> 
> skoro tak, to należało wprowadzić odpowiednie dynamiczne mechanizmy
> pilnowania porządku. A nie zbyć sprawę UBekiem.

Tego nie potrafię ocenić z punktu widzenia języka, który powstał w
latach '80, wtedy języki w ogóle oferowały mnóstwo ficzerów, w
szczególności Python miał stabilną wersję i C++ miał dobry wzorzec
do "skopiowania". 
 
> 1. Wektor oznacza adresowanie pośrenie, tablica niekoniecznie (albo w
> najgorszym przypadku wzgłedem stosu) -- procesory OOO obsługują tablice
> nieco szybciej.

OK. Ale nie w kontekście tego przykładu o którym pisze Pan F.

> 2. Jeśli weźmiesz mechanizmy dynamiczne, to tu masz kolejne, poważne
> spowolnienie, w dodatku algorytm zmniejszania rozmiaru jest arbitralny

A tablice to sobie możesz zmniejsza?

> (a co jest dobre do wszystkiego nie jest dobre w niczym).

Rozumiem, że mówisz o liście w Pythonie.

> Jak w Śmieciuchu zastąpiłem vector włąsną klasą to miałem zysk wydajności
> ok 30%.

Rozumiem. A w Pythonie też zastępujesz listę swoim wydajniejeszym kodem? Czy
może jest tak, że język nie ułatwia takich manewrów i lepiej nie
kombinować?

> Przykładziki pokazują problemy a nie styl kodowania mający na celu te
> problem obchodzić.

Nie. Przykładzik pokazuje kod, którego nigdy żaden n00by nie napisze.
To są hakerskie triki. Jeszcze raz podkreślam przykład na stronie 47 jest
extra dziwny. Żaden n00by w C++ tak kodu nie napisze -- pomijam n00by C
piszący w C++.
 
>>>Mamy język w którym są tablice, ale nie można ich używać, tylko jakiś
>>>cięzkich typów bibliotecznych, bo język jest spieprzony. To są Jaja na
>>>Resorach(tm).
>> 
>> Tak. Jaja na resorach. Zrób sobie statystykę ile ludzi używa surowych
>> tablic w innych językach?
> 
> W tych dobrych? Tylko perwerci nie używają.

A jaką to niby tablice ma Python? Ma bardzo zaawansowaną listę/deque.
Java ma tablice C# ma tablice i tam ludzie i tak wolą kontenery. W J
chociażby dlatego, że interfejsy kontenerów są wspólne.
 
> A od kiedy uważam J za dobry język? Toż to przerośnięte, ciężkie krówsko,
> typowy overdesign.

Ach! Dawno nie słyszałem takiego określenia. Poproszę jeszcze o jakiś
przymiot na C# i może jakiś na Haskella. 

Będę miał kolekcję pejoratywów na języki kompilowalne :-D -- do użycia w
następnych flejmach.
 
>> No to mnie pouczyłeś. Np. takie numpy jest napisane oczywiście w
>> Pythonie ;-).
> 
> Chodzi o to, że Python nie cierpi tak jak C++ z powodu śmieci z C.

Cierpi, czy nie cierpi to jest kwestia tego jak elegancko śmieci są upchane
pod dywan.

>>>Kod w C często jest kodem w C++.
>> 
>> To jest wina edukacji i legacy people.
> 
> Ależ skąd. Wiele programów w C to programy zarazem w C++.

Rozumiem. Ale jak piszesz od początku w C++, to kod jest mocno inny niż w
typowym C.
 
>>>>>>Mi to w ogóle ten kod nie działa, a jak go poprawiłem to mi działa
>>>>>>dobrze.
>>>>>
>>>>>Taaaak??!?!?!? O, to ciekawe!

Jeszcze raz napiszę. Kod pierwotnie poprawiłem przy użyciu bar** i
polimorfizmu dynamicznego.

Później użyłem jednego szablonu i też kod działa, przy niskim poziomie
dynamizmu.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267728
Author: Marcin ‘Qrczak’ Kowalczyk
Date: Tue, 13 Nov 2007 00:00
28 lines
2599 bytes
Dnia 12-11-2007, Pn o godzinie 22:33 +0100, Seweryn Habdank-Wojewódzki
pisze:

> Tak nawiązując do obu postów (Sebastiana i Piotra), ciekawy jestem jakie
> mądrości siedzą w kontenerach Pythona. Może nic już nie można patentować,
> bo wszystko opatentowane jest w Py3k.

Kontenery Pythona nie mają niezwykłych sztuczek, a miejscami bywały
realizowane wręcz nieporadnie (co bywa z czasem usprawniane).

Python ma fajny algorytm sortowania (merge sort z dopalaniem, które
zaczyna robić coraz dłuższe skoki, kiedy w łączeniu wciąż wygrywa ta
sama podtablica) i fajny algorytm rozwiązywania kolizji w tablicach
haszujących (pożyczyłem go w Kogucie). Autorem jednego i drugiego jest
Tim Peters.

Python jest realizowany dość solidnie (wydaje mi się, że łatwo im
panować nad stabilnością kodu nawet przy szybkim i rozproszonym
rozwoju), ale zwykle bez odkrywczych pomysłów ani sztuczek.
W szczególności odśmiecanie, współbieżność i maszyna wirtualna chyba
nie mają nic ciekawego.

Inna sprawa, że dla mnie patentowanie algorytmów jest evil.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: Ciemna strona C++
#267717
Author: Jedrzej Dudkiewicz
Date: Tue, 13 Nov 2007 06:51
37 lines
2632 bytes
Sebastian Kaliszewski wrote:
> Jedrzej Dudkiewicz wrote:
>>> Przykazywany jest wskaźnik na obiekt klasy pochodnej do funkcji 
>>> oczekującej wskaźnika na obiekt klasy bazowej -- to jest 
>>> *standardowe* użycie polimorfizmu. To, że funkcja oczekuje 
>>> przekazania tablicy, tylko przygłupi, kulawy język nie miesza tablice 
>>> ze wskaźnikami to jest to co jest.
>>
>> Wydaje mi się, że o ile przykład pokazuje prawdziwy problem, to sam 
>> jest idiotyczny, tzn. strasznie wydumany. W C++, nawet gdyby tablice 
>> były obsługiwane prawidłowo, tj. nie byłoby rzutowania (niejawnego) 
>> wskaźnika na tablicę, to ten przykład chyba byłby ciągle marny:
>>
>> class A {};
>> class B : public A {
>> public:
>>     void do_me() { };
>> };
>>
>> B tablica[3];
>>
>> void fun(A tablica[])
>> {
>>     tablica[0].do_me(); // <- co z tym?
>> }
> 
> To się nie skompiluje z dwu powodów:
[...]
> 2. Choć A jest nadtypem B, to w poprawionym C++ tablica A nie jest 
> nadtypem tablicy B. Podobnei jak i dziś A** nie jest żadnym nadtypem **B.

Napisałeś, że to jest "*standardowe* użycie polimorfizmu" - a mi to w 
żadnym wypadku nie wygląda na standardowe użycie. Powtórzę raz jeszcze, 
że rozumiem przedstawiony problem, ale chodzi mi też o to, że przykład 
jest raczej do dupy.

JD
Re: Ciemna strona C++
#267729
Author: Maciej Sobczak
Date: Tue, 13 Nov 2007 14:00
11 lines
2050 bytes
On 13 Lis, 01:00, Marcin 'Qrczak' Kowalczyk <qrc...@knm.org.pl> wrote:

> Python [...]

> W szczególności [...] współbieżność

Współbieżność? Chodzi Ci o to, że można uruchomić równocześnie dwa
programy Pythona w osobnych procesach? :-)

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com
Re: Ciemna strona C++
#267698
Author: Sebastian Kaliszewski
Date: Wed, 14 Nov 2007 12:52
14 lines
1830 bytes
Seweryn Habdank-Wojewódzki wrote:
> Ale wracając do zadania, w innym miejscu tego wątku podałem rozwiązanie tego
> zadania utrzymując konwencję tablic i całego ich spadku. 

W dobrym języku problemu po prostu nie ma. Bo tablica to tablica a wskaźnik 
to wskaźnik

> Już nie ma żadnych problemów, a Pana F. nadal uważam za dywersanta i
> mąciwodę. 

Bo wytyka oczywistę błedy projektu języka :)

pzdr
\SK
Re: Ciemna strona C++
#267746
Author: Sebastian Kaliszewski
Date: Wed, 14 Nov 2007 14:36
320 lines
14110 bytes
Seweryn Habdank-Wojewódzki wrote:
>>>Czemu zawsze kłócimy się o to samo?
>>
>>Fatum? ;)
> 
> 
> No to mamy pecha :-D.
>  
> 
>>>W Pythonie są jedyne słuszne rozwiązania np. jedyna słuszna lista i
>>>nie płaczesz?
>>
>>W Pythonie mam rozwiązania bardziej elastyczne.
> 
> A jaka niby elastyczność jest zaimplementowana w Pythonowej liście?

Taka, że możesz ją podstawić czymkolwiek co "kwacze tak jak lista" i będzie 
dobrze. W Pythonie masz pełno "use any file-like object here and you'll be 
fine, use any iterable collection there, etc).

W C++ jest zaś tak, że choć zrobisz sobie
#if(sizeof(unsigned int) >= 4)
  typedef
    std::basic_string<unsigned int, my_unicode_char_traits<unsigned int> >
    ustring;
#else
  typedef
    std::basic_string<unsigned long, my_unicode_char_traits<unsigned long> >
    ustring;
#endif

To po całym chrzanieniu się w zrobieniu traitsów, localesów, itd, tego 
stringa, który niezależnie od platformy trzyma punkty kodowe unicode w 
jednym znaku, nie użyjesz nigdzie, poza wypisywaniem i czytaneim ze 
strumieni, gdzie biblioteka standardowa standardowo oczekuje stringa.

A wystarczyłoby, żeby biblioteka tam gdzie oczekuje napisu zamiast czekać na 
const char* czy const std::string& czekała na const std::string_like&, gdzie 
std::string_like jest specjalnym typem na który wszystko co użytkownik chce 
traktować tak jak string było konwertowalne (użytkonik pisze w swojej klasie 
operator const string_like&), i z czego biblioteka wyciągała to co jej 
potrzebne. Sam string_like nie udostępniałby nic poza konwersją i jej 
okolicami, tak żeby nikt nie nadużył go do czegoś innego.

Inna rzecz to to, że rozmaite kustomizacje są starsznie ciężkie. Przykład 
takiego Micrsoft-like designu to całe iostream. Proste użycie -- OK, ale 
zrobienie czegoś własnego to kupa pisania, w tym np. łatwa do zrobienia źle 
i trudna do weryfikacji obsługa locali czy choćby samego zarządzania buforem 
-- choć 90% implementacji użytkownika zamierzałoby zrobić to tak samo 
(zamierzało, bo w realizacji będzie kupa bugów) to projektant całości nie 
wpadł na ten pomysł i tych błędogennych i niejasnych (i ohydnie, kryptycznie 
ponazywanych co już samo w sobie o czymś świadczy) elementów w żaden sposób 
nie wydzielił. W sensownie zaprojektowanej bibliotece miałbyś coś jak 
filelike_stream_bufer gdzie użytkownik miałby przeciążyć dwie chronione 
metody wirtualne -- read i write, mające interfejs jak funkcje o tych samych 
lub podobnych nazwach w 99.9% używanych systemów.


>>>A w ogóle pokaż mi co w Pythonie jest tym Testamentem? W
>>>itertoolsach są różne rzeczy ale testamentu nie widzę, sama lista też nie
>>>ma testamentu?
>>
>>W Pythonie iterator zna blisko obiekt iterowany i nie ma invalidacji
>>iteratorów. W Pythonie nie ma też problemu z przedwczesną śmiercią obiektu
>>iterowanego (dzięki GC).
> 
> 
> Przedwczesną, co to niby znaczy? Jak masz kontener i zanim związany
> iterator, to możesz tak jak w metodzie erase dla listy, zwrócić wskaźnik na
> następny element.
> 
> Natomiast *dokładnie* to co zrobiłeś w testamencie nie widzę w Pythonie, ale
> pewnie słabo patrzę.
>  
> 
>>Coś mi się zdaje, że zapomniałeś o której stornie pisałeś.
> 
> Cały czas pisze o 47.

Ale w tym na co ja odpowiadałem pisałeś o zupełnie inny slajdzie. Straciłeś 
tracking.


>>Włąmy to są przede wszystkim na domowe pecety, chodzące pod kontrolą softu
>>pewnego dużego producenta pisanego głównie w C i C++.
> 
> Rozumiem że mówisz o UNIX np: Linux, Solaris, AIX czy HP-UX prawda? ;-)

Źle rozumiesz ;)


>>>C++ zakłada, że języka używa wykształcony koder, a nie gamoń.
>>
>>C++ zakłada, że koder zna wszystkie pułapki.
> 
> 
> NIE. To co Pokazał Pan F. nie jest w duchu C++.

O duchu też mówił. Że się zmienił.

> To jest jedyny naturalny błąd. Reszta błędów wynika albo z syfiastego stylu
> kodowania np. szkoła Pana F.

Wynika z naturalnego stylu kodowania w C++. Z używania podstawowych ficzerów 
języka w naturalny sposób dla jakiego zostały oryginalnie (nie)pomyślane. 
Nowy styl w żadym wypadku nie jest naturalny dla języka. Jest naturalny dla 
gości którzy się wielokrotnie sparzyli i dziś kombinują naokoło.

>, albo niedouczenia n00by używają char *
> zamiast stringa.

Taaaak. Zwłaszcza że w samej bibliotece standardowej w wielu miejscach nie 
da się nie użyć char*. I że literały napisowe to jest takie nieco zwichnięte 
const char*.

> Podkreślam n00by, bo w tych przypadkach użycie char *
> wynika nie z celowego sposobu kodowania, ale z faktu, że ktoś kiedyś kupił
> książkę do C coś przeczytał, nie przeczytał, że C ma specjalne utilki do
> pracy na char * i teraz robi w kodzie dziwy nad dziwami.

No właśnie. Nienaturalny styl, zrobiony przez poparzonych językiem.


> Kolejny błąd n00by to jest bałaganiarstwo w rzutowaniach. Raz używa typu
> size_t, drugi raz int, innym razem long, a jeszcze innym unsigned short.

A żeby było czysto to powinien użyć std::jakiś_tam_container<jakiś tam typm, 
jakiś tam alokator>::size_type (szkoda, że nie dłużej)

> A błędy pokazywane przez Pana F nie pochodzą z kursu dla n00bów, to są
> bardzo wysublimowane i spreparowane przykładziki.

To są krótkie przykłądy pokazujące rzeczywioste, poważne, problemy

>>>>Ale nie wszędzie kod najbardziej oczywisty jest kodem niebezpiecznym i
>>>>niestylowym. To jest domena C++.
>>>
>>>Zapewne. To niech lewary nie piszą w C++! Nie wszyscy maja maturę, nie
>>>wszyscy kończą studia, nie wszyscy muszą pisać w C++.
>>>Nikomu nie każe pisać w C++.
>>
>>Ale przez te wszystkie nieoczywiste drogi, nawet nie-lewary popełniają,
>>często bardzo poważne a zarazem trudne do znalezienia, błędy.
> 
> Zgadza się. Chociaż dokładnie to samo czuję pisząc w Pythonie (zapewne nie
> spełniam poprzednika implikacji -- jestem PyLewar :-) )
> 
> Ot takie "specjalistyczne" sprawy związane z użyciem range vs. xrange.
> Używając range szybko giniesz.

Nie. Najwyżej masz wooolny kod.

> Jest adnotacja, że by używać xrange. To samo
> jest w C++. Czegoś używasz, bo wydaje się być naturalne, ale adnotacja w
> książce wskazuje jaka powinna być droga.

W przypadku range i xrange obie przenajmniej są funkcjami, ich podstaowwe 
użycie jest takie samo a dokumentacja jednego i drugiego leży obok.


>>>>>Jeśli gdzieś są takie zwyczaje to
>>>>>kończy się to na posiadaniu GC.
>>>>
>>>>I dobrze. GC znane jest od ponad 40 lat.
>>>
>>>To nie jest odpowiedź na moje pytanie.
>>
>>Problem własności rozwiązauje się właśnie za pomocą GC, lub reference
>>countingu.
> 
> No więc w C++ będziesz miał smart_ptr, na razie są one w boost (i nie tylko
> np. g++ ma już w sobie mocną wersję tr1).

Tyle że wbrew zasadzie you don't pay for what you don't use, w każdym użyciu 
zapłacę za sychronizację wątkową choć 95% wskazywanych obiektów nigdy 
pomiędzy wątkami nie będzie przekazywane. A różnica w wydajności jest 
znaczna -- mniej więcej 2 razy.


>>>>>To jest właśnie poziom haków Pana F.
>>>>
>>>>Nie, pan F. pokazuje rzeczywiste przypadki rzeczywistych kardynalnych
>>>>błędów projektu samego języka, a to jest pokazanie nadużycia mechanizmu
>>>>skąd inąd przydatnego.
>>>
>>>Ach tak. A może skądinąd rzutowania rodem z C też są czasem przydatne?
>>
>>Rzutpowania rodem z C nic ciekawego nie wnoszą.
> 
> Właśnie to jest ustalane w innym wątku. Mnie osobiście np. niejawne
> konwersje denerwują, ale to jest domena kompilatora, aby rzucał
> ostrzeżenia/błędy przy ewidentnie niewłaściwych rzutowaniach.

Co to znaczy ewidentnie niewłaściwe? W C++ sprawa jest poważnie zagmatwana, 
bo poza niejawnymi rzutowaniami masz jeszcze coś takiego jak promocja typów 
(też dziedzictwo z C, ale czy nie można było tego zostawić tylko dla extern 
"C"?).

>>>>>Zrobić coś nie całkiem tak, jak to się powinno robić, a potem gadać o
>>>>>wadach.
>>>>
>>>>Co jest niecałkiem tak? UB, gdy masz głupi, prosty błąd użycia iteratora?
>>>
>>>Wskaźnik to nie iterator. Tam przede wszystkim pojawia się paskudne
>>>rzutowanie na bar.
>>
>>Zapomniałeś o którym slajdzie pisałeś.
> 
> Cały czas piszę o 47. Ten slajd jest dla mnie szczytem hakerstwa (w sensie
> lokalnego maksimum w obrębie slajdów Pana F.).
>  

j.w. Ustosunkowywałem się do Twojej wywiedzi dotyczącej zupełnie innego slajdu.


>>>>Przykazywany jest wskaźnik na obiekt klasy pochodnej do funkcji
>>>>oczekującej wskaźnika na obiekt klasy bazowej -- to jest *standardowe*
>>>>użycie polimorfizmu. To, że funkcja oczekuje przekazania tablicy, tylko
>>>>przygłupi, kulawy język nie miesza tablice ze wskaźnikami to jest to co
>>>>jest.
>>>
>>>To jest spadek z C.
>>
>>skoro tak, to należało wprowadzić odpowiednie dynamiczne mechanizmy
>>pilnowania porządku. A nie zbyć sprawę UBekiem.
> 
> Tego nie potrafię ocenić z punktu widzenia języka, który powstał w
> latach '80, wtedy języki w ogóle oferowały mnóstwo ficzerów, w
> szczególności Python miał stabilną wersję i C++ miał dobry wzorzec
> do "skopiowania". 

Akurat dynamicznych rozwiązań wtedy było duuużo -- wszelkie Lispy i 
Smalltalki były u szczytu.


>>2. Jeśli weźmiesz mechanizmy dynamiczne, to tu masz kolejne, poważne
>>spowolnienie, w dodatku algorytm zmniejszania rozmiaru jest arbitralny
> 
> A tablice to sobie możesz zmniejsza?

Tablica jest lżejsza. Natomiast w wektorze zmiany rozmiarów są arbitralne. 
Przy dużych danych są też parszywie powoooolne (co powiesz na zamieranie 
programu na kilka senund sic(!) -- zupełnie jak wczesne GC z Javy 1.0) -- i 
szybkie nie będą, ale przydałąby się możliwość trochę lepszego sterowania 
niż .reserve().


>>(a co jest dobre do wszystkiego nie jest dobre w niczym).
> 
> Rozumiem, że mówisz o liście w Pythonie.

W Pythnie zwykle nie wymagam skrajnej wydajności. Na użycie C++ musi być 
jakieś uzasadnienie.


>>Jak w Śmieciuchu zastąpiłem vector włąsną klasą to miałem zysk wydajności
>>ok 30%.
> 
> Rozumiem. A w Pythonie też zastępujesz listę swoim wydajniejeszym kodem? Czy
> może jest tak, że język nie ułatwia takich manewrów i lepiej nie
> kombinować?

Język specjalnie nie utrudnia, ale specyfika jesgo jest taka, że żadziej 
potrzebuję.


>>Przykładziki pokazują problemy a nie styl kodowania mający na celu te
>>problem obchodzić.
> 
> Nie. Przykładzik pokazuje kod, którego nigdy żaden n00by nie napisze.
> To są hakerskie triki. Jeszcze raz podkreślam przykład na stronie 47 jest
> extra dziwny. Żaden n00by w C++ tak kodu nie napisze -- pomijam n00by C
> piszący w C++.

Problemem nie są nooby robiące program na zaliczenie. Ale ludzie 
doświadczeni, którzy dostali nowe wyzwanie -- nauczenie się C++.


>>A od kiedy uważam J za dobry język? Toż to przerośnięte, ciężkie krówsko,
>>typowy overdesign.
> 
> 
> Ach! Dawno nie słyszałem takiego określenia. Poproszę jeszcze o jakiś
> przymiot na C# i może jakiś na Haskella. 

C# to krówsko nieco w stosunku do J poprawione, ale zato nie dające wygonić 
się poza oborę MS.

A Hakell? Tego, że tak powiem, słabo znam. Może: "Napisany przez zboczeńców 
dla zboczeńców" ;)
Mam tu na myśli pozytywne znaczenie, nacechowane podziwem. Tak jak podziwiam 
gości którzy myślą drzewkami i dla nich lispowe S-expressions są de best. 
Ale i to i to, tak czy siak, słabo mapuje się na umysł przeciętnego 
programmeresa. Łagodne podejście funkcyjne jest fajne, ale taka czystość 
jaką reprezentuje Haskell jest dla mnie na dłuższą metę nie do zniesienia. z 
gruntu stanowe IO po prostu ma inną impedancję niż z gruntu bezstanowe 
programowanie funkcyjne. Monady to jest wybieg dla dopasowania impedancji, 
ale dla mnie to jest właśnie, wybieg.


> Będę miał kolekcję pejoratywów na języki kompilowalne :-D -- do użycia w
> następnych flejmach.

Proszę bardzo :)


>>>No to mnie pouczyłeś. Np. takie numpy jest napisane oczywiście w
>>>Pythonie ;-).
>>
>>Chodzi o to, że Python nie cierpi tak jak C++ z powodu śmieci z C.
> 
> Cierpi, czy nie cierpi to jest kwestia tego jak elegancko śmieci są upchane
> pod dywan.

Raczej czy mamy klapę od silnika, aby było ciszej i jak olej pocieknie to 
żeby został pod klapą.


pzdr
\SK
Re: Ciemna strona C++
#267747
Author: Seweryn Habdank-Wojewódzki
Date: Wed, 14 Nov 2007 19:42
245 lines
12161 bytes
Witam

Sebastian Kaliszewski wrote:


>>>>W Pythonie są jedyne słuszne rozwiązania np. jedyna słuszna lista i
>>>>nie płaczesz?
>>>
>>>W Pythonie mam rozwiązania bardziej elastyczne.
>> 
>> A jaka niby elastyczność jest zaimplementowana w Pythonowej liście?
> 
> Taka, że możesz ją podstawić czymkolwiek co "kwacze tak jak lista" i
> będzie dobrze.

To jest elastyczność algorytmów, tudzież kodu pracującego na liście a NIE
listy. Sama lista jest zamknięta!

> W Pythonie masz pełno "use any file-like object here and 
> you'll be fine, use any iterable collection there, etc).

Tak, wiem, ale to nie są ficzery tych kawałków języka, tylko samego języka,
generalnie komponenty języka Python nie są
wytyczalne/kustomizowalne/zmienialne.

Pokaż mi jak pięknie Python obsłuży kodowanie np. maziovii lub UTF-16? Nie
mówię, że w c++ to jest proste, ale może Python to potrafi to i ugryzie
takie kodowanie. Albo kiedy masz bazę danych taką surową, do której ciężko
o frejmłork, to wiedząc, że View będzie pracować na 20 000 danych jak
zapodajesz kontenerowi, że teraz akurat bedziesz chciał pracować na 20 000
danych dla View, ale algorytm dataminingowy potrzebuje 250 000 i ten
kontener ma być przygotowany również na to.
 
> To po całym chrzanieniu się w zrobieniu traitsów, localesów, itd, tego
> stringa, który niezależnie od platformy trzyma punkty kodowe unicode w
> jednym znaku, nie użyjesz nigdzie, poza wypisywaniem i czytaneim ze
> strumieni, gdzie biblioteka standardowa standardowo oczekuje stringa.

Super masz 100% racji, jeden bidny string po pierwsze nie jest kontenerem
jako takim. Lista pythonowa, też nie jest stringiem.

Kiedy zrobisz vector "dziwnych" znaków, to to zadziała i to super.
 
>>>Coś mi się zdaje, że zapomniałeś o której stornie pisałeś.
>> 
>> Cały czas pisze o 47.
> 
> Ale w tym na co ja odpowiadałem pisałeś o zupełnie inny slajdzie.
> Straciłeś tracking.

Nie. Cały czas piszę o tym slajdzie. Tylko raz skomentowałem 3.
 
>>>Włąmy to są przede wszystkim na domowe pecety, chodzące pod kontrolą
>>>softu pewnego dużego producenta pisanego głównie w C i C++.
>> 
>> Rozumiem że mówisz o UNIX np: Linux, Solaris, AIX czy HP-UX prawda? ;-)
> 
> Źle rozumiesz ;)

To znaczy, że dobrze rozumiem, że to nie jest wina C++, tylko prywatnych
spraw firmy o której myślimy i która większość softu na skrobnięte w C :-D.
 
>> Ot takie "specjalistyczne" sprawy związane z użyciem range vs. xrange.
>> Używając range szybko giniesz.
> 
> Nie. Najwyżej masz wooolny kod.

Przede wszystkim, co przy range miałem to "Out of memory", a nie wolny kod.
I to przy wartościach, które przy xrange są normalne -- naszczęście
nauczyłem się, że nowy styl Pythona sugeruje użycie xrange i tak też robię
stosuję trick w postaci xrange.
 
>> Jest adnotacja, że by używać xrange. To samo
>> jest w C++. Czegoś używasz, bo wydaje się być naturalne, ale adnotacja w
>> książce wskazuje jaka powinna być droga.
> 
> W przypadku range i xrange obie przenajmniej są funkcjami, ich podstaowwe
> użycie jest takie samo a dokumentacja jednego i drugiego leży obok.

Hmm... może i leży. Josuttis u mnie leży na półce powyżej monitora.
 
>> No więc w C++ będziesz miał smart_ptr, na razie są one w boost (i nie
>> tylko np. g++ ma już w sobie mocną wersję tr1).
> 
> Tyle że wbrew zasadzie you don't pay for what you don't use, w każdym
> użyciu zapłacę za sychronizację wątkową choć 95% wskazywanych obiektów
> nigdy pomiędzy wątkami nie będzie przekazywane.

Jak masz taki projekt to tak.

> A różnica w wydajności jest znaczna -- mniej więcej 2 razy.

Pokaż mi gdzie masz wszystko o czym piszesz i wydajność większą niż w C++.
 
> Co to znaczy ewidentnie niewłaściwe? W C++ sprawa jest poważnie
> zagmatwana, bo poza niejawnymi rzutowaniami masz jeszcze coś takiego jak
> promocja typów (też dziedzictwo z C, ale czy nie można było tego zostawić
> tylko dla extern "C"?).

Tego nie wiem. Traktuję to jako spadek historyczny. Na pewno kiedy powstawał
C++ tak było lepiej. To, że mi to nie odpowiada nie oznacza, że mam rację,
bo mam tylko swój punkt widzenia i zapewne nie uwzględniłem wielu
czynników.
 
>> Tego nie potrafię ocenić z punktu widzenia języka, który powstał w
>> latach '80, wtedy języki w ogóle oferowały mnóstwo ficzerów, w
>> szczególności Python miał stabilną wersję i C++ miał dobry wzorzec
>> do "skopiowania".
> 
> Akurat dynamicznych rozwiązań wtedy było duuużo -- wszelkie Lispy i
> Smalltalki były u szczytu.

Smalltalk może był u szczytu i może napisano w nim tak wiele softu, że teraz
uginamy się pod dziedzictwem tego języka -- w szczególności projektanci
Javy to smaltalkowcy, którzy nie poprawili umierającego języka tylko
zrobili lepsze C++ -- takie ono jest lepsze, że sam mówisz o nim źle.

A Lisp, no po prostu gigant softu król wyznaczający szosy dla maluczkich.
Jak widać mamy w tym języku popisane systemy operacyjne, aplikacje
multimedialne, GUI, łepsajty, aplikacje bankowe, gry, ... itd.
Słowem Gigant.

>>>2. Jeśli weźmiesz mechanizmy dynamiczne, to tu masz kolejne, poważne
>>>spowolnienie, w dodatku algorytm zmniejszania rozmiaru jest arbitralny
>> 
>> A tablice to sobie możesz zmniejsza?
> 
> Tablica jest lżejsza. Natomiast w wektorze zmiany rozmiarów są arbitralne.
> Przy dużych danych są też parszywie powoooolne (co powiesz na zamieranie
> programu na kilka senund sic(!) -- zupełnie jak wczesne GC z Javy 1.0) --
> i szybkie nie będą, ale przydałąby się możliwość trochę lepszego
> sterowania niż .reserve().

Mnie to wystarczy. Tak jak Piotr przewiduję liczbę elementów osadzanych w
kontenerze i o stosowną liczbę go powiększam. Lepszym rozwiązaniem jest
napisanie alokatora, ale tylko raz tak poważnie podszedłem do zadania więc
nie mam wielkiego doświadczenia w pisaniu alokatorów.

>>>(a co jest dobre do wszystkiego nie jest dobre w niczym).
>> 
>> Rozumiem, że mówisz o liście w Pythonie.
> 
> W Pythnie zwykle nie wymagam skrajnej wydajności. Na użycie C++ musi być
> jakieś uzasadnienie.

O widzisz i tu sam się ugryzłeś w ogon :-D. Ten język jest niebezpieczny, bo
nie traci czasu na zabezpieczenia niebezpiecznych rzeczy. Jeśli chcesz je
zabezpieczyć robisz to sam i według swojego uznania eliminujesz
niebezpieczeństwa i używasz sposobów adekwatnych do sytuacji. 
Np. po co w aplikacji jednowątkowej mieć synchronizację wątków? 
Albo mając aplikację wielowątkową widząc gdzie się one spotykają
synchronizujesz dokładnie to co jest wspólne i w sposób najbardziej
odpowiedni. Jeśli aplikacja jest "event driven" to używasz monitorów, jeśli
np. zmienna jest zmieniana "na zmianę" przez kolejne wątki, to może lepiej
użyć mutexa, nic na siłę, robisz co uważasz za stosowne. 
I tak np. piszę aplikacje przede wszystkim wieloprocesowe i ostatnio
rozproszone, żadne języki wysokiego rzędu nie oferują mi tego co
potrzebuję. Nauka surowego C++ od zera pozwala mi przenieść myślenie z
wątków na procesy oraz z lokalnych problemów na rozproszone (np.
rozproszone przydzielanie zasobów z pokoleniowym zliczaniem referencji).

>>>Jak w Śmieciuchu zastąpiłem vector włąsną klasą to miałem zysk wydajności
>>>ok 30%.
>> 
>> Rozumiem. A w Pythonie też zastępujesz listę swoim wydajniejeszym kodem?
>> Czy może jest tak, że język nie ułatwia takich manewrów i lepiej nie
>> kombinować?
> 
> Język specjalnie nie utrudnia, ale specyfika jesgo jest taka, że żadziej
> potrzebuję.

No więc jak Py Cię rozleniwia, to zdecydowanie rozumiem, czemu narzekasz na
C++ który wymaga pracowitości.

>>>Przykładziki pokazują problemy a nie styl kodowania mający na celu te
>>>problem obchodzić.
>> 
>> Nie. Przykładzik pokazuje kod, którego nigdy żaden n00by nie napisze.
>> To są hakerskie triki. Jeszcze raz podkreślam przykład na stronie 47 jest
>> extra dziwny. Żaden n00by w C++ tak kodu nie napisze -- pomijam n00by C
>> piszący w C++.
> 
> Problemem nie są nooby robiące program na zaliczenie. Ale ludzie
> doświadczeni, którzy dostali nowe wyzwanie -- nauczenie się C++.

Doświadczeni, czy Legacy people(tm)? Jak mnie nauka Haskella idzie opornie,
to nie narzekam, że język jest do bani.
 
>>>A od kiedy uważam J za dobry język? Toż to przerośnięte, ciężkie krówsko,
>>>typowy overdesign.
>> 
>> 
>> Ach! Dawno nie słyszałem takiego określenia. Poproszę jeszcze o jakiś
>> przymiot na C# i może jakiś na Haskella.
> 
> C# to krówsko nieco w stosunku do J poprawione, ale zato nie dające
> wygonić się poza oborę MS.
> 
> A Hakell? Tego, że tak powiem, słabo znam. Może: "Napisany przez
> zboczeńców dla zboczeńców" ;)

Uh! Toś przywalił.

> Mam tu na myśli pozytywne znaczenie, nacechowane podziwem. Tak jak
> podziwiam gości którzy myślą drzewkami i dla nich lispowe S-expressions są
> de best. 

Szkoda, że tak nie piszesz o Spiricie i MPL.

>>>>No to mnie pouczyłeś. Np. takie numpy jest napisane oczywiście w
>>>>Pythonie ;-).
>>>
>>>Chodzi o to, że Python nie cierpi tak jak C++ z powodu śmieci z C.
>> 
>> Cierpi, czy nie cierpi to jest kwestia tego jak elegancko śmieci są
>> upchane pod dywan.
> 
> Raczej czy mamy klapę od silnika, aby było ciszej i jak olej pocieknie to
> żeby został pod klapą.

Widzisz mnie to nie rajcuje, że jak olej cieknie to zostaje pod klapą. Dla
mnie pod klapą ma być równie czyściutko jak na klapie. W szczególności, że
jak tak każdy zacznie olewać kiedy mu cieknie, byle nie na szybę, to
będziemy jeździć na drogach posmarowanych olejem, a od tego do wypadków na
szeroką skalę jest tylko krok.

Widzisz rozumiem, że dziś opłaca się kupić serwer i umieścić na nim jedną
aplikację i jeśli coś cieknie, to cieknie tej jednej aplikacji, ale zdarza
się, że tak strasznie pocieknie, że aplikacja nie ma oleju i silnik się
zatrze.

A bardziej softwareowo to np. UB przy niedeterminizmie panującym w
aplikacjach wieloprocesowych i wielowątkowych to jest jak cios boksera wagi
piórkowej w stosunku do ciosu boksera wagi ciężkiej. Wolę mieć postawioną
czujność od początku, aby być czujnym tam gdzie trzeba. Nie ma takiej
osoby, która nie mając pojęcia o problemach na takim czy innym poziomie,
ale trudnych potrafi rozwiązać nowy problem jeszcze trudniejszy. 
Czy kupujący zaliczenia studenci potrafią potem w pracy coś wykonać sami? 
Na pewno potrafią kupić sami.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267748
Author: Wojciech Muła
Date: Wed, 14 Nov 2007 20:09
9 lines
1638 bytes
Seweryn Habdank-Wojewódzki wrote:
> Pokaż mi jak pięknie Python obsłuży kodowanie np. maziovii lub UTF-16?

Do mazovii trzeba stworzyć po prostu nowy codec, zdaje się
na pl.comp.lang.python ktoś parę miesięcy temu podsyłał.

UTF-16 jest wbudowany; wygląda na to, że UTF-7 ani UTF-32 nie.

w.
Re: Ciemna strona C++
#267749
Author: Seweryn Habdank-Wojewódzki
Date: Wed, 14 Nov 2007 20:16
20 lines
1839 bytes
Witam

Wojciech Muła wrote:

> Seweryn Habdank-Wojewódzki wrote:
>> Pokaż mi jak pięknie Python obsłuży kodowanie np. maziovii lub UTF-16?
> 
> Do mazovii trzeba stworzyć po prostu nowy codec, zdaje się
> na pl.comp.lang.python ktoś parę miesięcy temu podsyłał.
> 
> UTF-16 jest wbudowany; wygląda na to, że UTF-7 ani UTF-32 nie.

Krótko mówiąc nie wszystko jest gotowe i czasami też coś należy "from
scratch".

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267750
Author: Wojciech Muła
Date: Wed, 14 Nov 2007 20:39
16 lines
1986 bytes
Seweryn Habdank-Wojewódzki wrote:
>> Seweryn Habdank-Wojewódzki wrote:
>>> Pokaż mi jak pięknie Python obsłuży kodowanie np. maziovii lub UTF-16?
>> 
>> Do mazovii trzeba stworzyć po prostu nowy codec, zdaje się
>> na pl.comp.lang.python ktoś parę miesięcy temu podsyłał.
>> 
>> UTF-16 jest wbudowany; wygląda na to, że UTF-7 ani UTF-32 nie.
>
> Krótko mówiąc nie wszystko jest gotowe i czasami też coś należy "from
> scratch".

Kodowania Mazovia zdechło >10 lat temu, a te egoztyczne
UTF-y --- fakt, byłoby miło, gdyby były.

w.
Re: Ciemna strona C++
#267730
Author: Marcin ‘Qrczak’ Kowalczyk
Date: Wed, 14 Nov 2007 22:13
19 lines
2204 bytes
Dnia 13-11-2007, Wt o godzinie 06:00 -0800, Maciej Sobczak pisze:

> > Python [...]
> 
> > W szczególności [...] współbieżność
> 
> Współbieżność? Chodzi Ci o to, że można uruchomić równocześnie dwa
> programy Pythona w osobnych procesach? :-)

Python ma biedne wątki, ale ma. Rozróżniaj współbieżność / concurrency
(kilka przepływów sterowania, z których więcej niż 1 się zaczyna zanim
któryś się skończy) od równoległości / parallelism (równoczesne
wykonywanie instrukcji kodu maszynowego wielu przepływów sterowania).
Drugie pojęcie jest podzbiorem pierwszego.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: Ciemna strona C++
#267699
Author: Seweryn Habdank-Wojewódzki
Date: Thu, 15 Nov 2007 13:04
47 lines
3720 bytes
Witam

Sebastian Kaliszewski wrote:

> Seweryn Habdank-Wojewódzki wrote:
>> Ale wracając do zadania, w innym miejscu tego wątku podałem rozwiązanie
>> tego zadania utrzymując konwencję tablic i całego ich spadku.
> 
> W dobrym języku problemu po prostu nie ma. Bo tablica to tablica a
> wskaźnik to wskaźnik

Nie kapuję. Narazie obserwuję, że języki generalnie chowają to wszystko do
jednego wora jedni mówią o referencjach (mając na myśli wskaźniki) inni o
magii (mając na myśli wskaźniki). Tablice, cóż działają jak jak kontenery
wysokiego rzędu, albo zgoła w takich językach nie ma tablic.
 
>> Już nie ma żadnych problemów, a Pana F. nadal uważam za dywersanta i
>> mąciwodę.
> 
> Bo wytyka oczywistę błedy projektu języka :)

Błędy może są oczywiste (dla mnie nie), ale to co jest dla mnie oczywiste,
to bardzo dziwna konstrukcja przykładów, daleko odbiegająca od standardów
pisania programów w C++. Tymbardziej, że jak widzisz np. dołożenie jednej
linii do przykładu na slajdzie 47 leczy go całkowicie. A błąd wynika, z
faktu, że statycznie Pan F. przekazuje tablicę obiektów foo, a pobiera
wskaźnik do obiektów bar -- tam wykonuje ordynarne rzutowanie. Tymbardziej,
że po dodaniu szablonowego parametru program działa poprawnie, czyli
kompilator dobrze wie jakiego typu jest przekazywana tablica. Jednak
pomimo, że kompilator to wie, Pan F. wymusza rzutowanie, to jest błąd Pana
F. W żadnym języku z mi znanych takie coś nie przechodzi. W Javie nie ma
innego polimorfizmu jak dynamiczny, w C# również. Python (to w ogóle jest
język dynamiczny). Tak więc nadal podtrzymuję tezę, że nawet jeśli to jest
błąd języka, to przykład jest daleki od poprawności zarówno podwzględem
stylu pisania, jak i użytych technik. Co więcej przykład ten w sumie
jeszcze bardziej przekonuje mnie, że kompilatory powinny mieć silny system
ostrzegania, kiedy user wykonuje niejawne rzutowanie. Prawdę mówiąc nie
testowałem, ale ciekawy jestem jak ten przykład zachowałby się przy
zastosowaniu explicit_t<>. Spodziewam się jednak, że obrzuciłby Pana F.
błotem -- oczywiście miałby Pan F. kolejny przykład na długość błędów np.
wypisywane przez gcc.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267700
Author: Paweł Kierski
Date: Thu, 15 Nov 2007 13:13
23 lines
2605 bytes
Seweryn Habdank-Wojewódzki w wiadomości <fhhfae$bj$1@news.vectranet.pl> pisze:
[...]
> Prawdę mówiąc nie
> testowałem, ale ciekawy jestem jak ten przykład zachowałby się przy
> zastosowaniu explicit_t<>. Spodziewam się jednak, że obrzuciłby Pana F.
> błotem -- oczywiście miałby Pan F. kolejny przykład na długość błędów np.
> wypisywane przez gcc.

  Akurat explicit_t nie daje zbyt długiego błędu. Za to narzekanie
byłoby, że błąd "nie na temat", bo mówi o niemożności dostępu do
konstruktora prywatnego, a błąd polega na łamaniu zakazu rzutowania...

  Co do błędów, ich długości itp. to po kliku doświadczeniach
nauczyłem się jednego: Komunikaty są być może długie i słabo czytelne
(w granicy - nieczytelne dla człowieka). Ale _zawsze_ są prawdziwe,
czasem tylko są odpowiedzią na pytanie inne, niż "Co właściwie źle
napisałem?".

-- 
    Paweł Kierski
    news@pkierski.net
    dodaj "[nomorespam]" w temacie jeśli piszesz z domeny innej niż .pl,
    albo koniecznie chcesz obejść moje filtry 8-)
Re: Ciemna strona C++
#267731
Author: Sebastian Kaliszewski
Date: Thu, 15 Nov 2007 14:52
32 lines
3228 bytes
Marcin ‘Qrczak’ Kowalczyk wrote:
>>>Python [...]
>>
>>>W szczególności [...] współbieżność
>>
>>Współbieżność? Chodzi Ci o to, że można uruchomić równocześnie dwa
>>programy Pythona w osobnych procesach? :-)
> 
> 
> Python ma biedne wątki, ale ma. Rozróżniaj współbieżność / concurrency
> (kilka przepływów sterowania, z których więcej niż 1 się zaczyna zanim
> któryś się skończy) od równoległości / parallelism (równoczesne
> wykonywanie instrukcji kodu maszynowego wielu przepływów sterowania).
> Drugie pojęcie jest podzbiorem pierwszego.

Tak przy okazji... Coraz mocniej dochodzę do wniosku, że wątki do realizacji 
równoległości nadają się marnie, a przy nierównoległym concurrency lepsze 
byłoby coś, co nigdy nie jest równoległe. Dlaczego?
Wątki w tej postaci w jakiej zwykle występują oznaczają złamanie zasady "You 
don't pay for what you don't use". Bo przy każdej alokacji i zwalnianiu 
muisz mieć conajmniej dostęp do TLS. Standardowy (w C++(0/1)x, dziś tr1) 
shared_ptr musi być synchronizowany. A Zwykle 95% obiektów nigdy między 
wątkami nie będzie przekazywanych. A ta synchronizacja kosztuje i to 
kosztuje dużo. Sporo do myślenia dała mi kiedyś wypowiedź gościa z jakiegoś 
brytyjskiego centrum superkompuetrowego, który stwoerdził, że przez 10 lat 
pracy nie widział ani jednego programu wielowątkowego. Równoległe 
rozwiązania wieloprocesowe, gdzie komunikacja między kontekstami 
przetwarzania jest ściśle wydzielona i gdzie jest zarządzanie całością jest 
sensownie realizowalne, są po prostu szybsze (i to o kilkadziesiąt procent).

pzdr
\SK
Re: Ciemna strona C++
#267733
Author: H5N1
Date: Thu, 15 Nov 2007 16:17
14 lines
2300 bytes
Sebastian Kaliszewski napisał(a):

> Sporo do myślenia dała mi 
> kiedyś wypowiedź gościa z jakiegoś brytyjskiego centrum 
> superkompuetrowego, który stwoerdził, że przez 10 lat pracy nie widział 
> ani jednego programu wielowątkowego. Równoległe rozwiązania 
> wieloprocesowe, gdzie komunikacja między kontekstami przetwarzania jest 
> ściśle wydzielona i gdzie jest zarządzanie całością jest sensownie 
> realizowalne, są po prostu szybsze (i to o kilkadziesiąt procent).
Super, jeśli możesz zdefinować i odpalić statyczną pulę procesów, 
najlepiej każdy na osobnym procesorze. Ale jeśli musisz je opalać np. na 
żądanie klientów to okazuje się, że koszt utworzenia nowego procesu jest 
masakryczny. A jak liczba równoległych zadań idzie w setki, albo tysiące 
to z kosztami przełączania kontekstu też trzeba się liczyć.
Re: Ciemna strona C++
#267738
Author: Maciej Piechotka
Date: Thu, 15 Nov 2007 17:58
60 lines
4009 bytes
On Thu, 15 Nov 2007 17:17:00 +0100, H5N1 wrote:

> Sebastian Kaliszewski napisał(a):
> 
>> Sporo do myślenia dała mi
>> kiedyś wypowiedź gościa z jakiegoś brytyjskiego centrum
>> superkompuetrowego, który stwoerdził, że przez 10 lat pracy nie widział
>> ani jednego programu wielowątkowego. Równoległe rozwiązania
>> wieloprocesowe, gdzie komunikacja między kontekstami przetwarzania jest
>> ściśle wydzielona i gdzie jest zarządzanie całością jest sensownie
>> realizowalne, są po prostu szybsze (i to o kilkadziesiąt procent).
> Super, jeśli możesz zdefinować i odpalić statyczną pulę procesów,
> najlepiej każdy na osobnym procesorze. Ale jeśli musisz je opalać np. na
> żądanie klientów to okazuje się, że koszt utworzenia nowego procesu jest
> masakryczny. A jak liczba równoległych zadań idzie w setki, albo tysiące
> to z kosztami przełączania kontekstu też trzeba się liczyć.

Nie jest to może najlepszy test (za prosty program do odpalania) ale Linux 
na P M 1.5 GHz (1 rdzeń), 512 MiB Ramu (większość zajęta przez Gnome ;) ) 
potrafi odpalić ich ponad 100000 na sekundę (wynik podał 13107 ale 
zapomniałem funkcji podającej dokładny czas) - taki prosty benchmark.

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

#define PER_LOOP 0xffff

int main() {
        time_t begin, end;
        int status;
        while(1) {
                time(&begin);
                for(int i = PER_LOOP; i; --i) {
                        switch(fork()) {
                        case -1:
                                fprintf(stderr, "Error on creating child
\n");
                                exit(1);
                        case 0:
                                exit(0);
                        default:
                                wait(&status); //Inaczej za szybko tworzy
                        }
                }
                time(&end);
                time_t diff = end - begin;
                fprintf(stdout, "%d in %d -> %f pps\n",
                        PER_LOOP, diff, ((double)PER_LOOP)/(diff));
        }
}

Pozdrawiam
-- 
I've probably left my head... somewhere. Please wait untill I find it.
Homepage (pl_PL): http://uzytkownik.jogger.pl/
(GNU/)Linux User: #425935 (see http://counter.li.org/)
Re: Ciemna strona C++
#267739
Author: Sebastian Kaliszewski
Date: Thu, 15 Nov 2007 18:18
38 lines
3940 bytes
H5N1 wrote:
>> Sporo do myślenia dała mi kiedyś wypowiedź gościa z jakiegoś 
>> brytyjskiego centrum superkompuetrowego, który stwoerdził, że przez 10 
>> lat pracy nie widział ani jednego programu wielowątkowego. Równoległe 
>> rozwiązania wieloprocesowe, gdzie komunikacja między kontekstami 
>> przetwarzania jest ściśle wydzielona i gdzie jest zarządzanie całością 
>> jest sensownie realizowalne, są po prostu szybsze (i to o 
>> kilkadziesiąt procent).
> 
> Super, jeśli możesz zdefinować i odpalić statyczną pulę procesów, 
> najlepiej każdy na osobnym procesorze. Ale jeśli musisz je opalać np. na 
> żądanie klientów to okazuje się, że koszt utworzenia nowego procesu jest 
> masakryczny. A jak liczba równoległych zadań idzie w setki, albo tysiące 
> to z kosztami przełączania kontekstu też trzeba się liczyć.

Nie odróżniasz współbieżności od równoległości. Takie rzeczy to się robi gdy 
masz współbieżność (concurrency) bez równoległości (paralellism). Trzymanie 
kontekstu klienta w wątku? Proszę bardzo -- tylko po co do tego 
równoległość. Taki wątek albo śpi czekając na klienta lub na dysk/sieć, albo 
(bardzo krótko) wykonuje zlecenie klienta i po co ma się plątać z innymi? W 
dobrze zaprojektowanym systemie wątków to działa i to ładnie -- można na 
zupełnie zwykłej maszynie mieć np. 100000 wątków bez żadnej zadyszki i bez 
100GB RAM -- bo każdy wątek to tylko tyle ile potrzeba dla zapamiętania jego 
stanu. Tak działa np. Erlang -- język w którym oprogramowano trochę central 
Ericsona -- central obsługujących duuużo połączeń.

BTW. koszt odpalania procesu jest "maskaryczny" tylko na pewnym popularnym 
systemie operacyjnym zaprojektowanym akurat w trakcie rozkwitu mody na wątki 
jako panaceum na wszystko. Ale i tak takich procesów w systemie 
zaprojektowanym dla jakiejkolwiek wydajności nie tworzy się dla każdego 
zlecenia tylko procesy w których obsługa sesji klienta się zakończyła mogą 
być użyte ponownie (wracają do puli procesów wolnych). Ponadto procesy 
tworzy się "na zapas" (przyzwoite systemy mają konfigurowalną taką wartość 
jak liczba wolnych procesów). Tak działa wiel, nawet bardzo dużych systemów. 
I to działa wydajnie.

pzdr
\SK
Re: Ciemna strona C++
#267740
Author: Marcin ‘Qrczak’ Kowalczyk
Date: Thu, 15 Nov 2007 19:07
29 lines
3217 bytes
Dnia 15-11-2007, Cz o godzinie 19:18 +0100, Sebastian Kaliszewski pisze:

> Trzymanie kontekstu klienta w wątku? Proszę bardzo -- tylko po co do tego
> równoległość. Taki wątek albo śpi czekając na klienta lub na dysk/sieć, albo
> (bardzo krótko) wykonuje zlecenie klienta i po co ma się plątać z innymi?
> W dobrze zaprojektowanym systemie wątków to działa i to ładnie -- można na
> zupełnie zwykłej maszynie mieć np. 100000 wątków bez żadnej zadyszki i bez
> 100GB RAM -- bo każdy wątek to tylko tyle ile potrzeba dla zapamiętania jego
> stanu. Tak działa np. Erlang -- język w którym oprogramowano trochę central
> Ericsona -- central obsługujących duuużo połączeń.

Na wieloprocesorowej maszynie lepiej jest, kiedy tych wątków systemowych
jest kilka; rzędu liczby procesorów.

Mało jest rantajmów, które działają w ten sposób. Słyszałem tylko
o dwóch: nowy Erlang i nie za stary Glasgow Haskell Compiler.

Przy czym semantyka wątków Erlanga jest bardziej podobna do semantyki
tradycyjnych procesów niż wątków (nie ma współdzielenia pamięci, każdy
wątek/proces ma osobny odśmiecacz), więc w jego przypadku już wcześniej
uruchomienie kilku maszyn wirtualnych na jednym systemie dawało podobny
efekt. Być może trudniej było zapanować nad podziałem pracy między nie,
tzn. trzeba było robić to ręcznie, a teraz dzieje się to automatycznie,
ale tutaj zgaduję i nie jestem pewien.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: Ciemna strona C++
#267741
Author: Piotr Wyderski
Date: Sat, 17 Nov 2007 13:24
69 lines
5321 bytes
Sebastian Kaliszewski wrote:

> Tak przy okazji... Coraz mocniej dochodzę do wniosku,
> że wątki do realizacji równoległości nadają się marnie

Nie Ty jeden... ;-) Wątki (jądrowe) to dla mnie zaledwie interfejs
umożliwiający dostanie się do procesorów systemowych (bo jakoś
trzeba), więc zdumiewa mnie takie upowszechnienie się tego modelu.
Genralnie preferuję model puli zadań (task -- nieprzerywalne,
wykona się albo do końca, albo wcale) w trybach work sharing
i work stealing do symulowania przetwarzania strumieniowego.

> Bo przy każdej alokacji i zwalnianiu muisz mieć conajmniej dostęp do TLS.

To akurat nie jest problemem, dostęp do TLS _da_ się zrobić tak, że
będzie superwydajny. Jeśli jest odpowiednie wsparcie sprzętowe
i programowe na poziomie ABI, to nie ma powodu, by TLSy były
wolniejsze niż zwykła pamięć. Np. na IA-32 pod Windows do realizacji
TLSów służy rejestr segmentowy fs. Niestety oficjalnie nie wolno
(mharharhar...) bezpośrednio pisać do tego segmentu i trzeba używać
dość powolnych funkcji z WinAPI. Znacznie gorzej jest na systemach
uniksowych, gdzie TLSy bywają bardzo powolne. No ale jest kilka
pomysłów na ich znaczne przyspieszenie...

> Standardowy (w C++(0/1)x, dziś tr1) shared_ptr musi być synchronizowany.

Musi, ale to za mało! :-) On się w zasadzie nadaje tylko do obiektów
read-only, bo gdy następuje modyfikacja dzielonej zawartości, to nie
ma żadnego mechanizmu wymuszenia spójności obrazów pamięci i coś,
co bezbłędnie zadziała na IA-32 wygeneruje heisenbug na PowerPC.
Niestety dobre zrozumienie tych niuansów nie jest zbyt powszechne,
a będzie jeszcze gorzej, bo programowanie wielowątkowe się
upowszechnia, a modele spójności rozluźniają. Już chyba czas zacząć
pytać "GDZIE SĄ BARIERY???", bo inaczej się skończy megakatastrofą. :-)

> A Zwykle 95% obiektów nigdy między wątkami nie będzie przekazywanych.

Dlatego lubię JITy. Tam się do pewnego stopnia da automatycznie
dowodzić pewnych własności obiektów i generować domeny
synchronizacji.

> A ta synchronizacja kosztuje i to kosztuje dużo.

Bardzo dużo. Operacje atomowe są około stukrotnie (!) wolniejsze niż
zwykłe, więc jeśli są często używane, to wydajność może nieźle siąść.
To i tak znacznie lepiej niż klasychne podejście z lockowaniem, które
się nie skaluje powyżej kilku rdzeni, ale mimo tego nie jest dobrze.
Dlatego wolę work stealing niż work sharing, mimo znacznie większej
komplikacji kolejki zadań -- mogę wówczas wykonać nawet kilkaset
milionów prostych tasków na sekundę, a nie zaledwie ~10 milionów
w trybie sharing. Im bardziej złożone zadania, tym narzut na kolejkę
jest mniejszy, ale ja lubie drobnoziarniste podziały.

> Równoległe rozwiązania wieloprocesowe, gdzie komunikacja między 
> kontekstami przetwarzania jest ściśle wydzielona i gdzie jest zarządzanie 
> całością jest sensownie realizowalne, są po prostu szybsze (i to o 
> kilkadziesiąt procent).

Ja tam wolę trzymać wszytsko w jednej przestrzeni adresowej, a więc
efektywnie w jednym procesie, ale zasadniczo nie programuję wielowątkowo
w standardowo rozumiany sposób -- wolę podejście oparte na przesyłaniu
komunikatów, wzbogacone potężnymi zaletami pamięci dzielonej, co
efektywnie odtwarza pewną klasę strukur strumieniowych -- tylko, że ja
jestem "dziwny", bo podejście data-flow przyjąłem za swoje "od pierwszego
wejrzenia" i nic dla mnie nie znaczy jego porażka w latach 70-tych. :-)
No i przede wszystkim te niedoceniane powszechnie SIMDy...

    Pozdrawiam
    Piotr Wyderski
Re: Ciemna strona C++
#267744
Author: Marcin ‘Qrczak’ Kowalczyk
Date: Sat, 17 Nov 2007 15:14
25 lines
2279 bytes
Dnia 17-11-2007, So o godzinie 14:24 +0100, Piotr Wyderski pisze:

> Np. na IA-32 pod Windows do realizacji
> TLSów służy rejestr segmentowy fs. Niestety oficjalnie nie wolno
> (mharharhar...) bezpośrednio pisać do tego segmentu i trzeba używać
> dość powolnych funkcji z WinAPI. Znacznie gorzej jest na systemach
> uniksowych, gdzie TLSy bywają bardzo powolne.

Pod Linuxem na IA-32 są szybkie (NPTL).

__thread int x;
int test(void) {
   return ++x;
}

test:
        movl    %gs:x@NTPOFF, %eax
        incl    %eax
        movl    %eax, %gs:x@NTPOFF
        ret

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: Ciemna strona C++
#267742
Author: Maciej Sobczak
Date: Sat, 17 Nov 2007 22:42
31 lines
2920 bytes
On 17 Lis, 14:24, "Piotr Wyderski" <wyder...@mothers.against.spam-
ii.uni.wroc.pl> wrote:

> > Standardowy (w C++(0/1)x, dziś tr1) shared_ptr musi być synchronizowany.
>
> Musi, ale to za mało!

Nie musi.

Tzn. jeśli tak napiszą w standardzie, to wtedy musi z definicji.
Natomiast nie muszą tego napisać.

Oczywiście dostawcy bibliotek i tak będą to robić, żeby się szerokie
masy nie stresowały.

Ale zawsze będą też ludzie, którzy na tym niepotrzebnie stracą.
Sam jakiś czas temu narzekałeś, że strumienie w MSVC++ muteksują się
"jak poparzone" (pamiętam to sformułowanie). I podobnie, jest to
wyłącznie nadgorliwość autora implementacji a nie wymóg.

> On się w zasadzie nadaje tylko do obiektów
> read-only, bo gdy następuje modyfikacja dzielonej zawartości, to nie
> ma żadnego mechanizmu wymuszenia spójności obrazów pamięci

Właśnie dlatego własna synchronizacja wskaźnika to rozwiązanie złego
problemu.
Problem istnieje w innym zakresie i na innym poziomie - i na innym
poziomie powinien być rozwiązywany.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com
Re: Ciemna strona C++
#267743
Author: Piotr Wyderski
Date: Sat, 17 Nov 2007 23:51
49 lines
3735 bytes
Maciej Sobczak wrote:

> Nie musi.
>
> Tzn. jeśli tak napiszą w standardzie, to wtedy musi z definicji.
> Natomiast nie muszą tego napisać.

Jasne, ale mnie zapisy standardu interesują w niewielkim stopniu
(w myśl ogólnej zasady, że jeśli tylko Komitet będzie miał okazję
wprowadzić nowe UB, to jej nie zmarnuje), a za wiążący uznaję
stan faktyczny, wynikający ze zwyczajów implementacyjnych
w wiodących kompilatorach. A w boost synchronizuje -- wiem,
bo im sam napisałem wariant na UltraSparca.

> Oczywiście dostawcy bibliotek i tak będą to robić,
> żeby się szerokie masy nie stresowały.

Masy to się dopiero zaczną stresować, jak się nadzieją
na zagadnienia związane ze spójnością pamięci, będzie
płacz i zgrzytanie zębów...

> Ale zawsze będą też ludzie, którzy na tym niepotrzebnie stracą.

Dlatego można sobie wybrać wariant jednowątkowy w kompilacji.
A jeśli _wiesz_, że użycie zawsze jest bezpieczne ze względu na
wątki, to intrusive_ptr możesz oprzeć na zwykłym, nieatomowym
incie i będzie śmigać.

> Sam jakiś czas temu narzekałeś, że strumienie w MSVC++
> muteksują się "jak poparzone"

Bo w 2003 to prawda. Nie wiem jeszcze, jak jest w 2005,
ale wielkich nadziei sobie nie robię.

> Właśnie dlatego własna synchronizacja wskaźnika to rozwiązanie złego
> problemu. Problem istnieje w innym zakresie i na innym poziomie - i na
> innym poziomie powinien być rozwiązywany.

No ale synchronizacja grupowa to jest bardzo śliska sprawa, łatwo tam
sobie zrobić krzywdę. To prawie podchodzi po lock-free, więc siłą rzeczy
nie może się stać techniką ogólną, bo jest za trudne i słabo pielęgnowalne
-- to ten rodzaj kodu, który się pisze, testuje i zatapia w szkle, by go 
żaden
majsterklepka bez *naprawdę* poważnych powodów nie ruszał. Moim
zdaniem to jest technika zarezerwowana dla automatów. Kawałek fajnej
teorii, nawiasem mówiąc.

    Pozdrawiam
    Piotr Wyderski
Re: Ciemna strona C++
#267701
Author: Sebastian Kaliszewski
Date: Wed, 21 Nov 2007 17:27
69 lines
4062 bytes
Seweryn Habdank-Wojewódzki wrote:
>>>Ale wracając do zadania, w innym miejscu tego wątku podałem rozwiązanie
>>>tego zadania utrzymując konwencję tablic i całego ich spadku.
>>
>>W dobrym języku problemu po prostu nie ma. Bo tablica to tablica a
>>wskaźnik to wskaźnik
> 
> Nie kapuję. Narazie obserwuję, że języki generalnie chowają to wszystko do
> jednego wora jedni mówią o referencjach (mając na myśli wskaźniki) inni o
> magii (mając na myśli wskaźniki). Tablice, cóż działają jak jak kontenery
> wysokiego rzędu, albo zgoła w takich językach nie ma tablic.

Bo tablica jest kontenerem, typem złożonym. Wskaźnik nie. Tak masz w Adzie, 
Javie, Pascalu, C# itd.


>>>Już nie ma żadnych problemów, a Pana F. nadal uważam za dywersanta i
>>>mąciwodę.
>>
>>Bo wytyka oczywistę błedy projektu języka :)
> 
> Błędy może są oczywiste (dla mnie nie), ale to co jest dla mnie oczywiste,
> to bardzo dziwna konstrukcja przykładów, daleko odbiegająca od standardów
> pisania programów w C++. Tymbardziej, że jak widzisz np. dołożenie jednej
> linii do przykładu na slajdzie 47 leczy go całkowicie.

Leczy z czego? To jest przykłąd pułapki języka. MAsz dwie funkcje pisane 
przez niezalężnych proigramistów, w różnych modułach. Jedna oczekuje na 
polimorficzny wskaźnik do obiektu, inna na tablicę -- połączenie jednego z 
drugim do UBecja.

> A błąd wynika, z
> faktu, że statycznie Pan F. przekazuje tablicę obiektów foo,

Nie.

> a pobiera
> wskaźnik do obiektów bar -- tam wykonuje ordynarne rzutowanie.

Nie wykonuje żadnego rzutowania. W C++ do zwykłej funkcji *nie można* 
przekazać tablicy. Statycznie przekazuje wskaźnik i to jest tego efekt.


> Tymbardziej,
> że po dodaniu szablonowego parametru program działa poprawnie, czyli
> kompilator dobrze wie jakiego typu jest przekazywana tablica.

Wie tylko czasem. Ren trick z szablonem ma jedną zasadniczą wadę -- można 
przekazać tylko i wyłącznie tablicę której rozmiar jest znany (co C++ stara 
się maksymalnie utrudnić) i dla każdego rozmiaru tablicy jest osobna 
instancja szablonu (czyli niesamowite marnotrastwo). Czyli to jest mało 
użyteczny trick.


> Jednak
> pomimo, że kompilator to wie, Pan F. wymusza rzutowanie, to jest błąd Pana
> F.

Język pomyślany jest tak, żeby w większości praktycznych sytuacji kompilator 
nie wiedział.

> W żadnym języku z mi znanych takie coś nie przechodzi.

Jakto? Przechodzi w C i w C++.

[...]

pzdr
\SK
Re: Ciemna strona C++
#267702
Author: Seweryn Habdank-Wojewódzki
Date: Wed, 21 Nov 2007 19:43
103 lines
4889 bytes
Witam

Sebastian Kaliszewski wrote:

>> A błąd wynika, z
>> faktu, że statycznie Pan F. przekazuje tablicę obiektów foo,
> 
> Nie.

A tak. Proszę wróć do tego slajdu i zobacz co kolo robi.
 
>> a pobiera
>> wskaźnik do obiektów bar -- tam wykonuje ordynarne rzutowanie.
> 
> Nie wykonuje żadnego rzutowania. W C++ do zwykłej funkcji *nie można*
> przekazać tablicy. Statycznie przekazuje wskaźnik i to jest tego efekt.

Oh i ah, jaki on wielki. 

A mnie się udało to zrobić poprawnie, bo jestem tylko zwykły zjadacz chleba
i wolę cieszyć się pozytywami ;-P.

Pytanie kontrolne:

Czemu w Javie, C#, C i C++ są "ichnie" GUI, a np. taki Python nie ma
swojego? Jak jest taki wielki to niech ma. 

Już widzę prędkość światła, odświeżanie okienek 50 fps. Themesy, ikony 3D,
zbiór emotek dla end-users równie obszerny jak utf, 3D menu, okienka
rzucają cienie, wszystko jest elegancko konfigurowalne z poziomu
prawdziwego Pythona. 

Szkoda tylko, że psyco ma kłopoty z 64-bit :-(, bo może istniałby cień
szansy, aby Py miał swoje własne GUI.
 
>> Tymbardziej,
>> że po dodaniu szablonowego parametru program działa poprawnie, czyli
>> kompilator dobrze wie jakiego typu jest przekazywana tablica.
> 
> Wie tylko czasem. Ren trick z szablonem ma jedną zasadniczą wadę -- można
> przekazać tylko i wyłącznie tablicę której rozmiar jest znany (co C++
> stara się maksymalnie utrudnić)

Bajka, ja przekazuję typ poprzez wskaźnik, tylko że umnie typ jest poprawnie
identyfikowany. Popracuj z tym kodem to zobaczysz jak działa. Tablica może
mieć zmienny rozmiar.

> i dla każdego rozmiaru tablicy jest osobna 
> instancja szablonu

Bzdura! Tam jest wskaźnik.

> (czyli niesamowite marnotrastwo). Czyli to jest mało 
> użyteczny trick.

To jest to, że nawet nie masz ochoty przeczytać uważnie co napisałem, co
podałem, bo tak jak Pan F. na siłę udowadniasz wady, zamiast szukać zalet.

Wiesz. Ostatnio jeden człowiek powiedział, że dziecinadą jest pisanie w
Asemblerze. Jak myślisz czy on ma rację?

No z punktu widzenia łepmajsterów -- łebmajsterkowiczów również -- to jest
dziecinada. 

Teraz sam sobie odpowiedz na pytanie czy to dziecinada. 

Jeśli to dziecinada, to żyjemy w całkiem innych światach, jeśli nie to oboje
wiemy, że zarówno na Asm, C i C++, Fertran jest miejsce w świecie.
A jeśli jest i ma sens je gdzieś używać, to należy je używać z
uwzględnieniem specyfiki i niebezpieczeństw.

Pytanie kontrolne. Jak w Pythonie wykorzystasz ficzery SSE3? A może Python
sam z siebie oferuje funkcje używające SSE3?
 
>> Jednak
>> pomimo, że kompilator to wie, Pan F. wymusza rzutowanie, to jest błąd
>> Pana F.
> 
> Język pomyślany jest tak, żeby w większości praktycznych sytuacji
> kompilator nie wiedział.

Czego? U mnie kompilator wie co za durne kawały płata Pan F, szablon
elegancko wpasowuje się w jego kretyński przykładzik i uwalnia go od
błędów.

>> W żadnym języku z mi znanych takie coś nie przechodzi.
> 
> Jakto? Przechodzi w C i w C++.

Dorzucam Asm.

Licytujesz się dalej? Może Fortran?

Poczytałeś o pakiecie fpconst dla Pythona? Zobaczyłeś tam "power"
rzutowania? Mnie bardzo cieszy takie cos jak tam pokazano, czy Ciebie też?

Pozdrawiam.

Ps. Chętnie wrócę do tematu kasowania metod w Pythonowych klasach.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267703
Author: Sebastian Kaliszewski
Date: Thu, 22 Nov 2007 15:19
83 lines
4361 bytes
Seweryn Habdank-Wojewódzki wrote:
>>>A błąd wynika, z
>>>faktu, że statycznie Pan F. przekazuje tablicę obiektów foo,
>>
>>Nie.
> 
> A tak. Proszę wróć do tego slajdu i zobacz co kolo robi.

A nie. Przekazuje wskaźnik do funkcji której interfejs oznacza że oczekuje 
na wskaźnik typu kompatybilnego.


>>>a pobiera
>>>wskaźnik do obiektów bar -- tam wykonuje ordynarne rzutowanie.
>>
>>Nie wykonuje żadnego rzutowania. W C++ do zwykłej funkcji *nie można*
>>przekazać tablicy. Statycznie przekazuje wskaźnik i to jest tego efekt.
> 
> Oh i ah, jaki on wielki. 
> 
> A mnie się udało to zrobić poprawnie, bo jestem tylko zwykły zjadacz chleba
> i wolę cieszyć się pozytywami ;-P.

zwykłej funkcji nie szablonu. Udało ci się przekazać tablicę o statycznie 
ustalonym rozmiarze. O rozmiarze którego język nigdzi epo drodze nie zgubił.


> Pytanie kontrolne:
> 
> Czemu w Javie, C#, C i C++ są "ichnie" GUI, a np. taki Python nie ma
> swojego? Jak jest taki wielki to niech ma. 

Python ma swoje. W standardowej dystrybucji.


>>>Tymbardziej,
>>>że po dodaniu szablonowego parametru program działa poprawnie, czyli
>>>kompilator dobrze wie jakiego typu jest przekazywana tablica.
>>
>>Wie tylko czasem. Ren trick z szablonem ma jedną zasadniczą wadę -- można
>>przekazać tylko i wyłącznie tablicę której rozmiar jest znany (co C++
>>stara się maksymalnie utrudnić)
> 
> Bajka, ja przekazuję typ poprzez wskaźnik, tylko że umnie typ jest poprawnie
> identyfikowany. Popracuj z tym kodem to zobaczysz jak działa. Tablica może
> mieć zmienny rozmiar.

Wtedy też jest do bani. Tracisz dynamiczny polimorfizm.

>>i dla każdego rozmiaru tablicy jest osobna 
>>instancja szablonu
> 
> Bzdura! Tam jest wskaźnik.

To nie ma OO. Dziecko wylane z kompielą.


>>>W żadnym języku z mi znanych takie coś nie przechodzi.
>>
>>Jakto? Przechodzi w C i w C++.
> 
> Dorzucam Asm.
> 
> Licytujesz się dalej? Może Fortran?

Nie.

Ps. Chętnie wrócę do tematu kasowania metod w Pythonowych klasach.


To jest język dynamiczny. Jak skasujesz potrzebną metodę, to dostaniesz 
wyjątekiem przy próbie jej użycia -- jak przy tysiącach innych sytuacji 
dynamicznych. To jest ficzer bardzo rzadko przydatny, ale też i rzadko 
używany i dla newbies przykryty -- grzebanie w __dict__ to zagadnienia dla 
zaawansowanych.
Kiedy może się przydać? Jak masz logicznie podzieloną aplikację na czas 
inicjalizacji (gdy np. wczytujesz pliki konfiguracyjne, inicjujesz obiekty 
mające życ do końca itd) i czas właściwego wykonania. Wówczas użycie 
niektórych metod wskazane w czasie inicjalizaji jest złym pomeysłem w czasie 
właściwego wykonania -- i można je wywalić.

pzdr
\SK
Re: Ciemna strona C++
#267704
Author: Seweryn Habdank-Wojewódzki
Date: Thu, 22 Nov 2007 19:59
112 lines
5391 bytes
Witam

Sebastian Kaliszewski wrote:

> Seweryn Habdank-Wojewódzki wrote:
>>>>A błąd wynika, z
>>>>faktu, że statycznie Pan F. przekazuje tablicę obiektów foo,
>>>
>>>Nie.
>> 
>> A tak. Proszę wróć do tego slajdu i zobacz co kolo robi.
> 
> A nie. Przekazuje wskaźnik do funkcji której interfejs oznacza że oczekuje
> na wskaźnik typu kompatybilnego.

Szkoda, że kompilator to interpretuje jako rzutowanie, a szablon to rozumie.
Zresztą zastosowanie szablonu nie wpływa na poprawność kodu, bo kod sam
generuje potrzebne funkcje, które i tak czy w wersji dynamicznej czy nie i
tak wyglądałyby tak samo. IMHO problem jest wydumany, bo rozwiązanie
okazuje się być proste i skuteczne.
 
>>>>a pobiera
>>>>wskaźnik do obiektów bar -- tam wykonuje ordynarne rzutowanie.
>>>
>>>Nie wykonuje żadnego rzutowania. W C++ do zwykłej funkcji *nie można*
>>>przekazać tablicy. Statycznie przekazuje wskaźnik i to jest tego efekt.
>> 
>> Oh i ah, jaki on wielki.
>> 
>> A mnie się udało to zrobić poprawnie, bo jestem tylko zwykły zjadacz
>> chleba i wolę cieszyć się pozytywami ;-P.
> 
> zwykłej funkcji nie szablonu. Udało ci się przekazać tablicę o statycznie
> ustalonym rozmiarze. 

Nie. Przekazałem statycznie rozwinięty wskaźnik. Chyba musze przypomnieć.

Zamiast czegoś takiego:

void test (A * arr)
{
    printf ("%d\n", sizeof(A));
    arr[0]->m();
    arr[1]->m();
    arr[2]->m();
}

Dałem tak:

template <typename T>
void test(T* arr)
{
    printf ("%d\n", sizeof(T));
    arr[0].m();
    arr[1].m();
    arr[2].m();
}

To działa prosto i skutecznie. No chyba, że masz kontrprzykład -- a masz
duże szanse na posiadanie takowego.

>> Pytanie kontrolne:
>> 
>> Czemu w Javie, C#, C i C++ są "ichnie" GUI, a np. taki Python nie ma
>> swojego? Jak jest taki wielki to niech ma.
> 
> Python ma swoje. W standardowej dystrybucji.

A jak się nazywa może mi powiesz, bo zazwyczaj to o czym słyszę to wszystko
jest obce. Czyżby ideał miał wady?
 
>> Bajka, ja przekazuję typ poprzez wskaźnik, tylko że umnie typ jest
>> poprawnie identyfikowany. Popracuj z tym kodem to zobaczysz jak działa.
>> Tablica może mieć zmienny rozmiar.
> 
> Wtedy też jest do bani. Tracisz dynamiczny polimorfizm.

Co proszę. Pokaż co tracę? Taki kod pokaż co faktycznie coś się dzieje
złego. Zresztą tam nie było polimorfizmu dynamicznego od samego początku.
Tam Pan F. statycznie utworzył obiekty typu foo.
 
> Ps. Chętnie wrócę do tematu kasowania metod w Pythonowych klasach.

Super. Wiedziałem, że mogę liczyć na Twoje wsparcie w tej kwestii. Bo mnie
nie przeszkadza, że python może kasować metody, bo moich C++'owych nie
skasuje, a jak user sobie jakieś wyświetlanie skasuje to jego-kulpa.
 
> To jest ficzer bardzo rzadko przydatny, ale też i rzadko 
> używany i dla newbies przykryty -- grzebanie w __dict__ to zagadnienia dla
> zaawansowanych.

No wiem. Metaklasy również i jest jeszcze perę spraw o których tylko
Py-magicy mogą rozprawiać ;-).

> Kiedy może się przydać? Jak masz logicznie podzieloną aplikację na czas
> inicjalizacji (gdy np. wczytujesz pliki konfiguracyjne, inicjujesz obiekty
> mające życ do końca itd) i czas właściwego wykonania. Wówczas użycie
> niektórych metod wskazane w czasie inicjalizaji jest złym pomeysłem w
> czasie właściwego wykonania -- i można je wywalić.

Ale super, miałem nadzieję, że potrafisz myśleć konstruktywnie, nawet nie
wiesz jak się cieszę, że potrafisz znajdować plusy tam gdzie można mówić o
minusach. 
W operze "Czarodziejski flet" Mozarta, też przemieniają zło w dobro :-D.
Chyba stajesz się pozytywnym bohaterem tego wątku. I tak samo jak
we "Flecie" dopiero w akcie drugim zło zamieniane jest dobro.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267705
Author: Maciej Sobczak
Date: Thu, 22 Nov 2007 21:46
76 lines
4620 bytes
On 22 Lis, 20:59, Seweryn Habdank-Wojewódzki <shw_m...@wp.pl> wrote:


> > Ps. Chętnie wrócę do tematu kasowania metod w Pythonowych klasach.

> > To jest ficzer bardzo rzadko przydatny, ale też i rzadko
> > używany i dla newbies przykryty -- grzebanie w __dict__ to zagadnienia dla
> > zaawansowanych.

> > Kiedy może się przydać? Jak masz logicznie podzieloną aplikację na czas
> > inicjalizacji (gdy np. wczytujesz pliki konfiguracyjne, inicjujesz obiekty
> > mające życ do końca itd) i czas właściwego wykonania. Wówczas użycie
> > niektórych metod wskazane w czasie inicjalizaji jest złym pomeysłem w
> > czasie właściwego wykonania -- i można je wywalić.
>
> Ale super, miałem nadzieję, że potrafisz myśleć konstruktywnie, nawet nie
> wiesz jak się cieszę, że potrafisz znajdować plusy tam gdzie można mówić o
> minusach.

Etam, Seweryn, dałeś się wkręcić. To jest Naciąganie Gaci Przez Głowę
(tm).

class ClassForNormalUse
{
public:
    void doThis();
    void doThat();
};

class ClassWithAdditionalFeaturesForInitialization : public
ClassForNormalUse
{
public:
    void readConfigFiles();
    void doSomethingSpecialAtTheBeginning();
};

ClassForNormalUse & getIt()
{
    static ClassWithAdditionalFeaturesForInitialization x;

    x.readConfigFiles();
    x.doSomethingSpecialAtTheBeginning();

    // ok, object is ready for normal use:
    return x;
}

// ...

ClassForNormalUse & x = getIt();

x.doThis();
x.doThat();
x.readConfigFiles(); // WTF? no such method (in compile-time!)


Nie trzeba kasować metod ze słownika, żeby podzielić funkcjonalność
czegoś na etapy.
Wieloetapowość można naturalnie wyrazić ze statycznym systemem typów
posługując się różnymi widokami na ten sam obiekt w różnych chwilach
jego życia. W powyższym przykładzie *jeden* obiekt ma *dwa* różne
widoki: jeden dostępny w funkcji factory a drugi dostępny dla klienta
(tu oczywiście nie chodzi o samą formę factory, bo można to
zorganizować dowolnie). Widok w factory ma większą funkcjonalność,
która nie jest dostępna w czasie używania obiektu przez klienta.
Żadna metoda nie została tu skasowana z żadnego słownika, po prostu
niepotrzebne metody nie istnieją w widoku, którego używa klient. To,
że te metody tam nie istenieją, jest statyczną cechą tego widoku.

I nie, nie trzeba tego opisywać jako "zagadnienie dla zaawansowanych",
bo już samo to określenie pokazuje, że kasowanie metod to zwykłe
Naciąganie Gaci Przez Głowę (tm).

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com
Re: Ciemna strona C++
#267706
Author: Seweryn Habdank-Wojewódzki
Date: Thu, 22 Nov 2007 23:33
51 lines
3675 bytes
Witam

Maciej Sobczak wrote:

> Etam, Seweryn, dałeś się wkręcić. To jest Naciąganie Gaci Przez Głowę
> (tm).

Może i to jest Naciąganie Gaci Przez Głowę (tm), ale chodzi mi o aspekt
psychologiczny. 

Sebastian już umie szukać pozytywów tam gdzie są negatywy. Teraz pozostaje
kwestia, aby to samo umiał zrobić w kontekście C++ -- trochę to czarno
widzę, ale tli się we mnie iskierka nadziei :-).

> Nie trzeba kasować metod ze słownika, żeby podzielić funkcjonalność
> czegoś na etapy.

Tak, ale tam było ciche założenie, że używamy Py i że user to paskudniaczek,
który ewentualnie będzie miał ochotę coś schrzanić (użyć metod zakazanych).
W C/C++/ASM w ogóle kompilacja potrafi schować tak dużo, że user bez
zacięcia do reverse-engineeringu nie zrobi nic. W Py to nie jest tak
oczywiste, jak usera zabezpieczyć przed nim samym.

Jak już mamy takie pogaduszki o językach, to jak takie coś wygląda w Adzie?

> Wieloetapowość można naturalnie wyrazić ze statycznym systemem typów
> posługując się różnymi widokami na ten sam obiekt w różnych chwilach
> jego życia. W powyższym przykładzie *jeden* obiekt ma *dwa* różne
> widoki: jeden dostępny w funkcji factory a drugi dostępny dla klienta
> (tu oczywiście nie chodzi o samą formę factory, bo można to
> zorganizować dowolnie). Widok w factory ma większą funkcjonalność,
> która nie jest dostępna w czasie używania obiektu przez klienta.
> Żadna metoda nie została tu skasowana z żadnego słownika, po prostu
> niepotrzebne metody nie istnieją w widoku, którego używa klient. To,
> że te metody tam nie istenieją, jest statyczną cechą tego widoku.

Rozumiem.
 
> I nie, nie trzeba tego opisywać jako "zagadnienie dla zaawansowanych",

Znaczy się, to jest jasne, że każdy bardziej dociekliwy n00by weźmie i
pokasuje różne metody, przy pierwszym zetknięciu się z taka możliwością.

> bo już samo to określenie pokazuje, że kasowanie metod to zwykłe
> Naciąganie Gaci Przez Głowę (tm).

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267713
Author: Sebastian Kaliszewski
Date: Fri, 23 Nov 2007 13:06
86 lines
4174 bytes
Seweryn Habdank-Wojewódzki wrote:
>>>>>A błąd wynika, z
>>>>>faktu, że statycznie Pan F. przekazuje tablicę obiektów foo,
>>>>
>>>>Nie.
>>>
>>>A tak. Proszę wróć do tego slajdu i zobacz co kolo robi.
>>
>>A nie. Przekazuje wskaźnik do funkcji której interfejs oznacza że oczekuje
>>na wskaźnik typu kompatybilnego.
> 
> 
> Szkoda, że kompilator to interpretuje jako rzutowanie, a szablon to rozumie.

Szablon dopasowuje się do statycznego typu zmiennej z miejsca konkretyzacji.

> Zresztą zastosowanie szablonu nie wpływa na poprawność kodu, bo kod sam
> generuje potrzebne funkcje, które i tak czy w wersji dynamicznej czy nie i
> tak wyglądałyby tak samo.

No właśnie nie.

> IMHO problem jest wydumany, bo rozwiązanie
> okazuje się być proste i skuteczne.

Jest tylko rozwiązaniem czego innego. Ten problem raczej lepiej rozwiązać tak:

void test (whatever_ptr<A> arr[])
{
  ...
}


> Nie. Przekazałem statycznie rozwinięty wskaźnik. 

I to jest źle, bo zmieniasz semantykę tego przekazania. I tylko odsuwasz 
problem. Kontrprzykłąd poniżej.

[...]
> To działa prosto i skutecznie. No chyba, że masz kontrprzykład -- a masz
> duże szanse na posiadanie takowego.

  A *arr = new B[10];
  test(arr);

  :)


>>>Pytanie kontrolne:
>>>
>>>Czemu w Javie, C#, C i C++ są "ichnie" GUI, a np. taki Python nie ma
>>>swojego? Jak jest taki wielki to niech ma.
>>
>>Python ma swoje. W standardowej dystrybucji.
> 
> 
> A jak się nazywa może mi powiesz, bo zazwyczaj to o czym słyszę to wszystko
> jest obce.

PyTk. Jest poniekąd obce, ale jest wbudowane. Taki paradoks.


> Czyżby ideał miał wady?

Ubogie. Normalnie używa się PyQt czy WxPythona.


>>>Bajka, ja przekazuję typ poprzez wskaźnik, tylko że umnie typ jest
>>>poprawnie identyfikowany. Popracuj z tym kodem to zobaczysz jak działa.
>>>Tablica może mieć zmienny rozmiar.
>>
>>Wtedy też jest do bani. Tracisz dynamiczny polimorfizm.
> 
> Co proszę. Pokaż co tracę? Taki kod pokaż co faktycznie coś się dzieje
> złego. Zresztą tam nie było polimorfizmu dynamicznego od samego początku.
> Tam Pan F. statycznie utworzył obiekty typu foo.

To jest przykład. Przekazania parametrów mają określoną semantykę, którą ty 
zmieniasz. Zresztą pokazałęm rozwiązanie poprawne, które w dodatku nie daje 
się tak łatwo oszukać jak zrobienie A* arr = new B[10];
Czemu takie coś przechodzi?!?? Nie ma prawa działać, ale przechodzi :)


[...]
pzdr
\SK
Re: Ciemna strona C++
#267707
Author: Maciej Sobczak
Date: Fri, 23 Nov 2007 13:23
39 lines
3870 bytes
On 23 Lis, 00:33, Seweryn Habdank-Wojewódzki <shw_m...@wp.pl> wrote:

> > Nie trzeba kasować metod ze słownika, żeby podzielić funkcjonalność
> > czegoś na etapy.
>
> Tak, ale tam było ciche założenie, że używamy Py i że user to paskudniaczek,
> który ewentualnie będzie miał ochotę coś schrzanić

Jeżeli to paskudniaczek, który będzie miał ochotę coś zchranić, to
język dynamiczny w rodzaju Py (gdzie nie ma nawet czegoś takiego jak
prywatność) da mu *wiele* okazji, żeby to zrobić.
Po co kasować metodę, skoro każdy może sobię ją potem samemu dodać?

Kiedyś z okna obserwowałem niewielki plac budowy (w Polsce).
Budowa zaczęła się od postawienia drewnianej bramy na brzegu placu.
Tylko bramy. Można ją było otwierać i zamykać i nawet jakaś ciężarówka
tamtędy przejechała z raz albo dwa (po uprzednim otwarciu bramy, w
wykonaniu pewnego pana w kufajce).
Płotu jednak wokół placu nie było. Była tylko ta brama na brzegu
placu.

Ot, takie właśnie "zabezpieczenie".

> Jak już mamy takie pogaduszki o językach, to jak takie coś wygląda w Adzie?

Co wygląda? Kasowanie metod? :-D
Ada jest językiem statycznym.
Przede wszystkim ma coś takiego jak prywatność. Ma też interfejsy a
koncepcje obiektowe zwykle implementuje się też z wykorzystaniem
pakietów.
Z projektowego punktu widzenia ten temat można rozwiązać dokładnie
tak, jak w C++ albo w Javie. Czyli albo inicjalizację obiektu robimy w
ukryciu przed klientem enkapsulując konstruktor bądź opierając się o
drobniejsze prywatne procedury, albo dzielimy interfejs obiektu na
dwa, odpowiednio do różnych etapów jego życia.
Nie ma tu nic specyficznego dla Ady.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com
Re: Ciemna strona C++
#267709
Author: Sebastian Kaliszewski
Date: Fri, 23 Nov 2007 16:42
39 lines
3252 bytes
Seweryn Habdank-Wojewódzki wrote:
>>Etam, Seweryn, dałeś się wkręcić. To jest Naciąganie Gaci Przez Głowę
>>(tm).
> 
> Może i to jest Naciąganie Gaci Przez Głowę (tm), ale chodzi mi o aspekt
> psychologiczny. 
> 
> Sebastian już umie szukać pozytywów tam gdzie są negatywy. Teraz pozostaje
> kwestia, aby to samo umiał zrobić w kontekście C++ -- trochę to czarno
> widzę, ale tli się we mnie iskierka nadziei :-).

Sebastian od dawna umie szukać pozytywów tam gdzie są negatywy. Ale 
Sebastian nie będzie "odbierał chleba" miejscowym piewcom półksiężyca z 
dwoma krzyżykami.


>>Nie trzeba kasować metod ze słownika, żeby podzielić funkcjonalność
>>czegoś na etapy.
> 
>>I nie, nie trzeba tego opisywać jako "zagadnienie dla zaawansowanych",
> 
> Znaczy się, to jest jasne, że każdy bardziej dociekliwy n00by weźmie i
> pokasuje różne metody, przy pierwszym zetknięciu się z taka możliwością.
> 
>>bo już samo to określenie pokazuje, że kasowanie metod to zwykłe
>>Naciąganie Gaci Przez Głowę (tm).


Kasowanie metod podobnie jak parę cech szablonów z C++ to jest efekt uboczny 
pewnych założeń dot. całego języka. Tyle że cóż... W przeciwieństwie do 
kasowania metod, czego zastosowania nie widziałem, łamańce bazujące na 
ubocznych cechach szablonów są stosowana o wiele za często.


BTW. kasowanie metod daje efekt istotnie różny niż przysłanianie, które jest 
mało pewne i niewygdne w użyciu przy nie zdegenerowanych hierarchiach klas.

pzdr
\SK
Re: Ciemna strona C++
#267712
Author: Sebastian Kaliszewski
Date: Fri, 23 Nov 2007 17:05
81 lines
4461 bytes
Maciej Sobczak wrote:
> Etam, Seweryn, dałeś się wkręcić. To jest Naciąganie Gaci Przez Głowę
> (tm).

Może i jest. A może nie... nie będę się kłócił.

> class ClassForNormalUse
> {
> public:
>     void doThis();
>     void doThat();
> };
> 
> class ClassWithAdditionalFeaturesForInitialization : public
> ClassForNormalUse
> {
> public:
>     void readConfigFiles();
>     void doSomethingSpecialAtTheBeginning();
> };
> 
> ClassForNormalUse & getIt()
> {
>     static ClassWithAdditionalFeaturesForInitialization x;
> 
>     x.readConfigFiles();
>     x.doSomethingSpecialAtTheBeginning();
> 
>     // ok, object is ready for normal use:
>     return x;
> }
> 
> // ...
> 
> ClassForNormalUse & x = getIt();
> 
> x.doThis();
> x.doThat();
> x.readConfigFiles(); // WTF? no such method (in compile-time!)
> 
> 
> Nie trzeba kasować metod ze słownika, żeby podzielić funkcjonalność
> czegoś na etapy.

Tylko, że ten podział, żeby być skutecznym, musi przebiegać po granicy 
wywoałania getIt(), co może być bardzo nienaturalne. Co gorsza getIt() można 
zawołać tysiące razy, również pod koniec działania programu. Nie masz tu 
żadnego nmechanizmu zabraniającego zastosowanie 
ClassWithAdditionalFeaturesForInitialization również w czasie absolutnie z 
inicjalizacją nie związanym.


Modyfikacja klasy przez usunięcie z niej metody zmienia typ. Czyli do pewnej 
chwili działania programu mamy jakiś typ, ale po tem jest już typ inny. I 
wszystkie (nawet tysiące) instancji typu pierwszego zostaje jednym 
pociągnięciem zamienionych w instancje typu drugiego (i np. stają się 
immutable).

Występowanie w programach zmiennych stałych, czyli obiektów które w czasie 
normalnego działania programu są stałymi, ale na jego początku muszą zostać 
zainicjowane na podstawie danych zewnętrznych.

> Wieloetapowość można naturalnie wyrazić ze statycznym systemem typów
> posługując się różnymi widokami na ten sam obiekt w różnych chwilach
> jego życia.

Ale musisz się zajmować każdym obiektem z osobna co jest uciążliwe. A tu 
mówimy o życiu całej aplikacji a nie jednego obiektu.

> I nie, nie trzeba tego opisywać jako "zagadnienie dla zaawansowanych",
> bo już samo to określenie pokazuje, że kasowanie metod to zwykłe
> Naciąganie Gaci Przez Głowę (tm).

To samo określenie nic nie pokazjue. Ale taka konstrukcja jest w Pythonie 
stosowana niezwykle rzadko. Zapewne dlatego, że dla normalnych ludzi 
wystarcza konwencja (np nazwa z samych wielkich liter oznacza stałą lub 
właśnie zmienną stałą). Wymuszanie czegoś takiego to pomysł bardziej 
ceplusplusiczny(tm) a nie pytoniczny.

pzdr
\SK
Re: Ciemna strona C++
#267708
Author: Seweryn Habdank-Wojewódzki
Date: Fri, 23 Nov 2007 20:26
46 lines
3074 bytes
Witam

Maciej Sobczak wrote:

> Kiedyś z okna obserwowałem niewielki plac budowy (w Polsce).
> Budowa zaczęła się od postawienia drewnianej bramy na brzegu placu.
> Tylko bramy. Można ją było otwierać i zamykać i nawet jakaś ciężarówka
> tamtędy przejechała z raz albo dwa (po uprzednim otwarciu bramy, w
> wykonaniu pewnego pana w kufajce).
> Płotu jednak wokół placu nie było. Była tylko ta brama na brzegu
> placu.
> 
> Ot, takie właśnie "zabezpieczenie".

:-D
 
>> Jak już mamy takie pogaduszki o językach, to jak takie coś wygląda w
>> Adzie?
> 
> Co wygląda? Kasowanie metod? :-D

Nie! Maciek bądźmy trochę poważni ;-). 
Raczej chciałem wiedzieć, jak projektowo zapewnia się takie np. widoki w
Adzie. Ale ...

> Ada jest językiem statycznym.

Wiem. Przepraszam nie precyzyjnie napisałem o co mi chodzi.

> Z projektowego punktu widzenia ten temat można rozwiązać dokładnie
> tak, jak w C++ albo w Javie. Czyli albo inicjalizację obiektu robimy w
> ukryciu przed klientem enkapsulując konstruktor bądź opierając się o
> drobniejsze prywatne procedury, albo dzielimy interfejs obiektu na
> dwa, odpowiednio do różnych etapów jego życia.
> Nie ma tu nic specyficznego dla Ady.

Myślałem, że mają coś chłopaki za pazuchą, bo jakby nie spojrzeć często (nie
zawsze) maja cos dobrego.

... Już mi to wyjaśniłeś, że nic się nie różnią od reszty.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267714
Author: Seweryn Habdank-Wojewódzki
Date: Fri, 23 Nov 2007 20:56
64 lines
3369 bytes
Witam

Sebastian Kaliszewski wrote:

> Jest tylko rozwiązaniem czego innego. Ten problem raczej lepiej rozwiązać
> tak:
> 
> void test (whatever_ptr<A> arr[])
> {
>   ...
> }
 
Takie rozwiązanie też miałem, ale ono jest "za odległe" od paskudnego stylu
Pana F.

>> To działa prosto i skutecznie. No chyba, że masz kontrprzykład -- a masz
>> duże szanse na posiadanie takowego.
> 
>   A *arr = new B[10];
>   test(arr);

Tu masz rację :-). Nie mam rozwiązania. 

Ale czy Ty mnie ponownie nie wpuszczasz w kanał?

Proszę dopisz mi do tego działające delete?
Jak dopiszesz delete, spróbuję podejść do zadania raz jeszcze.
Nie potrafię elegancko napisać delete.

> PyTk. Jest poniekąd obce, ale jest wbudowane. Taki paradoks.

Cudze że hej. Wiedziałem że o tym myślisz, ale to JEST cudze.
 
>> Czyżby ideał miał wady?
> 
> Ubogie. Normalnie używa się PyQt czy WxPythona.

Czasem PyGTK. Wszystko cudze.

> To jest przykład. Przekazania parametrów mają określoną semantykę, którą
> ty zmieniasz. 

Ja zmieniam? Pan F. parszywie rzutuje, a ja zmieniam wydaje mi się że
wszystkie chwyty dozwolone. SOA#1 -- mi działa.

> Zresztą pokazałęm rozwiązanie poprawne, które w dodatku nie 
> daje się tak łatwo oszukać jak zrobienie A* arr = new B[10];

Rozwiązanie poprawne, które podałeś jest takie, że się nim brzydzisz,
przecież smart_ptr<> to szablony, mają synchronizację (której nie widzę),
poza tym przecież to nawet nie jest w standardowej bibliotece.

Dlatego nie pisałem o smart_ptr, ale możesz mi wierzyć też miałem taką
propozycję.

> Czemu takie coś przechodzi?!?? Nie ma prawa działać, ale przechodzi :)

Dopisz działające delete i wracam na ring :-D.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267710
Author: Seweryn Habdank-Wojewódzki
Date: Fri, 23 Nov 2007 23:35
19 lines
2104 bytes
Witam

Sebastian Kaliszewski wrote:

> Sebastian nie będzie "odbierał chleba" miejscowym piewcom półksiężyca z
> dwoma krzyżykami.

Na czarnym tle, powiewającego sztandaru, trupio blady księżyc pokryty
czaszkami i cztery topory ustawione w dwa "++" ociekające krwią
niewiernych ;-).

Czy przyłączasz się do księżyca? W sumie innej opcji nie masz :-D. 
Z resztą co ja tu pytam, już od dawna dawna należysz do księżyca.

Pozdrawiam.

-- 
|\/\/|   Seweryn Habdank-Wojewódzki
 \/\/
Re: Ciemna strona C++
#267715
Author: Sektor van Skijlen
Date: Sat, 24 Nov 2007 14:48
35 lines
2828 bytes
Dnia Fri, 23 Nov 2007 14:06:32 +0100, Sebastian Kaliszewski skrobie:
> >>>Pytanie kontrolne:
> >>>
> >>>Czemu w Javie, C#, C i C++ są "ichnie" GUI, a np. taki Python nie ma
> >>>swojego? Jak jest taki wielki to niech ma.
> >>
> >>Python ma swoje. W standardowej dystrybucji.
> > 
> > 
> > A jak się nazywa może mi powiesz, bo zazwyczaj to o czym słyszę to wszystko
> > jest obce.

> PyTk. Jest poniekąd obce, ale jest wbudowane. Taki paradoks.

PyTk? Wbudowane? Jaja sobie robisz?

Toż to najzwyklejsze dowiązania do Tk, podobnie jak istnieją do Qt, Wx, GTK
itd.

A dowiązania do Tk (poza naturalnym Tcl) są i dla Py i dla Perla i nawet
dla C++ (tak, mówię o cpptk :).

> > Czyżby ideał miał wady?

> Ubogie. Normalnie używa się PyQt czy WxPythona.

Owszem, Tk bez IWidgets ma dość ubogie możliwości - acz do prostego GUI się
nadaje.


-- 
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: Ciemna strona C++
#267711
Author: Sebastian Kaliszewski
Date: Thu, 29 Nov 2007 13:25
16 lines
2245 bytes
Seweryn Habdank-Wojewódzki wrote:
>>Sebastian nie będzie "odbierał chleba" miejscowym piewcom półksiężyca z
>>dwoma krzyżykami.
> 
> 
> Na czarnym tle, powiewającego sztandaru, trupio blady księżyc pokryty
> czaszkami i cztery topory ustawione w dwa "++" ociekające krwią
> niewiernych ;-).
> 
> Czy przyłączasz się do księżyca? W sumie innej opcji nie masz :-D. 
> Z resztą co ja tu pytam, już od dawna dawna należysz do księżyca.

Ale jestem Rebeliantem :)

pzdr
\SK
Page 2 of 10 • 486 total messages
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads