Andrzej Jarzabek
4/29/2013 3:32:00 PM
On Apr 29, 2:32 pm, Edek <edek.pienkow...@gmail.com> wrote:
> Dnia Mon, 29 Apr 2013 04:29:20 -0700 po glebokim namysle Andrzej Jarzabek
> rzekl:
>
> > No ale wyjatki (takie jak w Javie czy C++) nie sluza do powiadamniania
> > procesów. Jesli trzeba powiadomic procesy, to kod, który to robi mozesz
> > miec w catch.
>
> Tylko ze to jest strasznie niewygodne.
Tak samo niewygodne, jak zwracanie z funkcji pary (wynik, blad).
> Dziala ok w c++ dla prostych
> rzeczy, typu odczytaj dokument z bazki, przetwórz, zapisz, ale majac
> nie jeden watek tylko mase i bilioteki w setkach tysiecy linii kodu
> nawet RAII robi sie klopotliwe gdy dolaczona jest reakcja
> zewnetrznych systemów.
W ramach tego, ze w C++ nie masz wbudowanych mechanizmów takich jak
channel i goroutine, nie jest to bardziej klopotliwe niz rozwiazanie
bez wyjatków.
A ze zamiast goroutines uzywasz bibliotek dajacych ci patterny takie
jak futures, to jest to zdecydowanie mniej klopotliwe, bo owe
biblioteki zapewniaja ci propagacje wyjatków przez granice watku.
> Dopiero male goroutines z mniejszym stosem sa swiatelkiem
> w tunelu. Zamiast olbrzymiego stosu przez który leci wyjatek ma
> sie niewielkie procedury polaczone kanalami. Widze, ze niedlugo
> powiemy, ze BASIC tez dzialal.
Nic ci to nie zmienia, nadal musisz ten blad obsluzyc. W Erlangu
róznice masz faktycznie o tyle, ze piszesz programy w ten sposób, ze
kazdy blad powoduje ubicie "procesu", który mozesz potem albo
automatycznie restartowac, albo czekac na interwencje operatora, który
moze dojsc do tego co sie stalo i naprawic blad - wlacznie z
poprawieniem blednego kodu i uruchomieniem go bez zatrzymywania
systemu.
> > recover i jak dla mnie sa to po prostu wyjatki, tylko troszeczke inaczej
> > zrobione. Z tego co przeczytalem jest to ficzer dodany do jezyka w
> > pózniejszym etapie i sadze, ze narzekanie, ze nie ma wyjatków raczej
> > pochodzi z czasu, kiedy nie bylo.
>
> Hmm. Ja zyje tu i teraz, ale moze zle robie ;)
I narzekasz, ze Go nie ma wyjatków?
> > Jesli chodzi o to, co panic/recover wnosza do rozproszonej architektury,
> > to przykro mi, ale nie widze róznicy. W dodatku z wykorzytsaniem w
> > kontekscie wspólieznosci nie wydaja sie wnosic zbyt wiele w stosunku do
> > wyjatków, bo z tego co wyczytalem to wyjscie z goroutine w stanie
> > spanikowanym wywala caly program.
>
> Tu nie ma zadenj róznicy, wyjatki tez trzeba lapac. Mi nie jest przykro
> ze rozmówca sie nie zgadza, wrecz przeciwnie.
Mi jest przykro, ze nie widze róznicy, a nie, ze sie nie zgadzasz.
Balem sie po prostu, ze osleplem, wiec z ulga przyjmuje do wiadomosci,
ze róznicy nie ma.
> > Interesujaca róznica miedzy tradycyjnymi wyjatkami a panic/recover jest
> > "dynamiczny" charakter tych drugich. Jak rozumiem defer/recover mozna
> > rejestrowac np. warunkowo w klauzuli if. Czy to dobrze czy zle,
> > nie mam szczególnie zdania: widze potencjalne problemy z czytelnoscia,
> > latwoscia wnioskowania p programie, wykrywaniem bledów i refaktoryzacja,
> > w dodatku "tradycyjne" podejscie oparte o zakresy wydaje mi sie
> > elegantsze. Byc moze natomiast panic/defer/recover maja jakies ciekawe
> > idiomatyczne sposoby stosowania, które moze nawet jeszcze nie sa
> > odkryte. Po prostu nie wiem.
>
> Moze najpierw "doczytam i wiem" a potem sugerowanie problemów? Podobny
> cleanup stosuje sie w C, tylko bez automatycznego zwijania stosu. Z tymi
> znienawidzonymi goto.
No wiec otóz równiez uwazam, ze C jest kiepskim jezykiem, w którym
brak sensownych rozwiazan jest przyczyna duzej ilosci problemów.
> > Niepokojace natomiast sa argumenty ze strony projektantów jezyka typu
> > "tak, wiemy, ze (costam w) panic/recover jest kijowe. Specjalnie
> > zrobilismy kijowe, zebyscie nie uzywali panic."
>
> No tak, bo panic to wszyscy lubia. Ech... . Go ma taka filozofie:
> pozwlamy pisac ryzykowny kod, ale oferujemy bezpieczne metody
> pisania.
Nie ma nic szczególnie bezpiecznego w tym, co oni proponuja zamiast.
Odpowiednikiem rzucenia wyjatku i nie zlapania go jest cos takiego:
foo, err := getFoo(bla)
bar, err := makeBar(foo)
Tak, oczywiscie, taki mechanizm i taka konwencja sa krokiem do przodu
w stosunku do tego, co jest w C, ale nad wyjatkami nie widze zadnej
przewagi.
> > Ach, ale akurat to, czy wyjatki sa dobre, czy niedobre to jest oddzielny
> > temat od tego, czy sprzatanie zasobów przez finally jest dobre czy
> > niedobre. Sa jezyki, które maja inne rozwiazania rtego problemu, i nawet
> > w samej Javie da sie stworzyc (i tworzy sie)
> > odpowiednie wrappery.
>
> Ja podalem konkretny przyklad i nic nie mówilem o tym, czy finally
> jest "dobre" czy "niedobre". Majac RAII uzywa sie RAII, majac finally
> uzywa sie finally, majac goto w C uzywa sie goto. Mówimy o braku
> wyjatków w Go i z czym to sie je w porównaniu do innych jezyków.
Ale twój argument dotyczyl tego, ze defer jest lepsze od sprzatania
zasobów niz finally. Moze i jest, ale to nie jest argument za tym, ze
bez wyjatków lepiej, bo przeciez istnieje wiele mechanizmów jezykowych
do sprzatania zasobów lepszych niz finally.
W Groovy na ten przyklad, który ma dokladnie takie same wyjatki jak
Java, problem zamykania pliku mozna zalatwic w ten sposób:
myFile.withWriter { writer ->
zapisuj_do_pliku_uzywajac writer
}
> > Takie rozwiazanie, jak daje ci go, czyli zlapac wyjatek w watku, który
> > go rzucil i przekazac jako wynic coroutine to z grubsza tak samo mozesz
> > zrobic w C++ przy pomocy future, try/catch, i pair.
>
> Ano nie. To znaczy da sie, ale praktyka zupelnie inaczej wyglada.
Praktyka jest taka, ze sie uzywa wyjatków, bo tak lepiej.
> W BASICu tez sie da pisac.
Ale nie da sie uzyskac praktycznie tego samego rezultatu.
> > [...]
> > No wiec dokladnie w taka strone, w jaka mu exception handler kaze
> > poleciec. Dokladnie tak jak z panic w Go.
>
> Ano nie. Chociazby kod podzielnoy jest na goroutines, a nie na
> jeden monolityczny watek ze stoma ramkami stosu.
Ale dlaczego monolitycznego? Watki masz takie, jakie sobie napiszesz.
Dokladnie tak samo, jak rozumiem, jak goroutines - bedzie ich tyle i
takie duze, jak sobie programista podzieli program. Myle sie?
> To inna architektura,
> trzeba przekazac informacje o bledzie przez channele a nie tylko w góre
> stosu.
I czym to sie rózni od programu wielowatkowego w C++?
> Panic nie jest "dokladnie tak samo", tylko wlasnie "zupelnie
> inaczej", choc ma wspólne cechy, bo sluzy do tego samego celu.
Jest dokladnie tak samo, z dokladnoscia do duperel. Tak samo jak
wyjatek przerywa wykonanie biezacej funkcji i zwija stos tak dlugo, az
nie trafi na handlera. Róznica jest taka, ze handlery mozna sobie
dynamicznie rejestrowac, co z pewnoscia moze byc przyczyna wielu
radosnych bledów, ale czy ma jakies praktyczne zastosowania?
> > Po przyjrzeniu sie wyglada troche tak, jakby w Go interfejsy dawaly
> > generycznosc - przynajmniej taka jak w Javie, a moze nawet troche
> > mocniejsza. Nie mam racji?
>
> Oj, j.w., doczytajmy moze najpierw. Bo ja juz nie wiem, czy brakuje
> generyków czy sa generyki, zdecydujmy sie na zajecie jakiejs
> pozycji w argumentacji, pogubilem sie ;)
Moja pozycja jest taka: w jezykach statycznie typowanych generyki w
takiej czy innej formie sa przydatne. Równiez, a moze nawet przede
wszystkim przy pisaniu zlozonych systemów serwerowych, równiez w
przypadku, kiedy sa one wspólbiezne czy rozproszone.
W temacie czy Go ma generyki, wyjatki i tak dalej nie mam zadnego
szczególnego stanowiska - tak czy inaczej raczej uzywac nie bede. Na
podstawie tego, co widze pobieznie sie przygladajac, Go ma wyjatki i
generyki. Jesli chcesz mi wylumaczyc, dlaczego panic/recover nie sa
wyjatkami w takim sensie, jak exceptions z Javy czy C++, albo dlaczego
interfejsy nie sa typami generycznymi w takim sensie, jak w Javowych
generics, to chetnie przeczytam i ewentualnie podyskutuje. Nie chce ci
sie - tez dobrze, mozemy w takim razie chyba zakonczyc dyskusje na
tym, ze nasza rozbieznosc zdan co do przydatnosci generyków i wyjatków
bierze sie stad, ze inaczej rozumiemy te pojecia.