🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.python
Article #26601

Re: python vs php - potrzebne argumenty

#26601
From: Sebastian Kaliszewski
Date: Wed, 09 Dec 2009 18:54
344 lines
15934 bytes
Piotr Sawicki wrote:
> Sebastian Kaliszewski powiada:
> 
>>> Tylko że taki kod może poprawnie obsługiwać błędy mimo braku 
>>> w danym miejscu try/except.
>> Tak samo kontynuacja zapisana gdzieś globalnie może być poprawną obsługą 
>> błędu, mimo braku w danym miejscu jej jawnego przekazania. 
> 
> Przyznam że kompletnie nie chwytam o co Ci chodzi. Jakiś przykład kodu?

Użyję pseudopythona (czyli jakby zapewne wyglądały kontynuacje 
zrealizowane w Pythonie gdyby je ktoś zrealizwoał:


def z_bledem(err_cont, a, b):
   if not a:
     err_cont.call(ErrorA())
   elif not b:
     err_cont.call(ErrorB())


def wolanie(err_cont):
   callcc cont:
     for i in range(10):
       z_bledem(random.choice(True, False), random.choice(True, False))
   continue error:
     if error.type is ErrorA():
       obsługa_na_miejscu()
     else:
        # pozostałe błędy ma obsłużyć wolajacy wolanie
        err_cont.call(error)


VS


def z_bledem(a, b):
   if not a:
     raise ErrorA()
   elif not b:
     raise ErrorB()

def wolanie()
   try:
     for i in range(10):
       z_bledem(random.choice(True, False), random.choice(True, False))
   except ErrorA as error:
     obsługa_na_miejscu()
   # pozostałe błędy ma obsłużyć wolajacy wolanie


Co zabawne w powyższym w wersji kontynuacyjnej jeśli pominiemy ostatnie 
else to błąd zostanie po cichu zignorowany.


>>> Nadal nie wyczajam argumentu, musiałbyś skonkretyzować 
>>> tok rozumowania (są bez sensu - kontrprzykłady że z sensem
>>> - ale tam są podstawowe - omgwtf).
>> One mają sens gdy stosowane są do uzyskania rzeczy które w pozostałych 
>> językach są kluczowe, tj podstawowe konstrukcje sterujące.
> 
> No ale są tam stosowane również przy obsłudze sytuacji wyjątkowych. 
> Bezsensownie?

Kluczowe jest *również*.

> 
>>> No właśnie nie - w przypadku obsługi błędów zwykłymi if-errcode
>>> widać na pierwszy rzut oka czy kod był napisany już z obsługą
>>> błędów czy jeszcze bez (i czy wszystkie są pokryte, w jaki sposób).
>> Tego ostatniego nie widać bez znajomości semantyki wołanej funkcji.
> 
> To czy wszystkie (kwantyfikatorowo) to bez znajomości: errcode<>success.

Tyle samo mi daje catch(...) -- w obu wypadkach niewiele.


>>> w miejscu wywołania funkcji wiem co się stanie po powrocie.
>> Tzn albo pójdzie normalnie, albo poleci w stornę sprawdzenia 
>> błedu -- tak samo jest przy wyjątkach.
> 
> Nie tak samo, bo jest napisane czarno na białym jaka to strona.

Jeśli mamy cokolwiek więcej niż jeden ogólny błąd to dokładnie tak samo 
nie wiadomo. W dodatku łatwiej zrobić źle i niezauważyć (niezłapany 
wyjątek wyleci w sposób zwykle widoczny, dziurawa obsługa błędu w 
kontynuacji poprostu błąd zgubi).

> A z exceptionami hgw gdzie poleci, trzeba sprawdzać cały program.

I tak trzeba sprawdzać cały program. I tu i tu.


>>> Chyba rozumiem - myślałeś że chodzi mi o metodę javową sprawdzania
>>> wyjątków automatycznie. No więc nie, o czytelność kodu.
>> Co do czytelności kodu, to i tak nie widzisz lokalnie, 
>> jakie błędy dana funkcja rzuca tylko jakie są obsługiwane
> 
> A to akurat jest najmniejszy problem, żeby to sprawdzić 
> wystarczy zajrzeć w jeden wskazany nazwą procedury fragment
> kodu - to można mieć w ide pod klikiem. Żeby sprawdzić jaka
> będzie obsługa wyjątku trzeba przeczytać zylion miejsc
> kodu które mogą wywoływać aktualnie czytany kawałek.

To samo przecież, w oczywisty sposób dotyczy użycie kontynuacji. Nawet 
jal kontynuację dostaniesz jako parametr, przy każdym wołaniu może to 
być kontynuacjia utworzona zupełnie gdzie indziej więc gdzie indziej 
prowadząca. Bez sprawdzenia wszysktkuch miejsc wołania i tak nie wiesz.


>> BTW. zrobiono w swoim czasie badania co wpływa na liczbę 
>> błędów w kodzie programów pisanych w różnych językach. 
> 
> Jak znam życie to nie robili eksperymentów tylko pomiary.

Robili eksperyment. Ludzie dostali do napisania programy (w języku który 
znali), potem te programy starannie sprawdzono patrząc ile jest błędów.

> W szczególności niewykrycie innych korelacji mogło wynikać 
> nie z ich braku, a z przyjęcia złych hipotez badawczych.

Hipotezą było, że są języki mniej i bardziej błędogenne. Sprawdziĸła się 
tylko w takim stopniu w jakim dany język pozwalał na napisanie kodu 
składającego się z mniejszej liczby konstrukcji. Koerlacja była 
zachowana również pomiędzy różnymi programami w tym samym języku -- 
programy dłuższe miały proporcjonalnie więcej błędów.


>>> Dowolny fragment kodu z licznymi wywołaniami procedur/funkcji.
>>> Jeśli to jest napisane z wyjątkami to mam trzy możliwości:
>>> 1) sprawdzanie wyjątku jest przy każdym wywołaniu,
>>> 2) przy żadnym,
>>> 3) przy niektórych.
>>> W 1) wyjątki są redundante z ifami; w 2) nie wiem czy obsługa
>>> błędów była przewidziana czy nie, a w dodatku przebieg sterowania
>>> robi się zupełnie nieoczywisty (bo każdy call jest potencjalnym
>>> exit pointem);
>> Zupełnie jak przy kontynuacjach. 
> 
> Niezupełnie, bo wiem że może skoczyć i gdzie.

Nie wiesz jeśli tylko gdziekolwiek przekazujesz dalej kontynuację 
otrzymaną "z zewnątrz" (w parametrach aktyualnie wykonywanej funkcji, 
lub co gorsza globalnie).

> I to każdy 
> poszczególny call, a nie cały obleczony try-catchem blok.

Jak ci bardzo na tej wiedzy zależy, to na końcu możesz mieć catch(...) 
-- wtedy wiesz, że tędy przeleci.


>> Jeśli masz statyczne specyfikacje wyjątków, to albo obsługa 
>> jest na końcu funkcji (w catch / except czy jak tam autorzy 
>> języka nazwali) albo w sygnaturze funkcji jest jawnie napisane, 
>> że leci dalej. 
> 
> To akurat nie jest złe - ale to słabsza cecha (w sensie matematycznym).

No właśnie nie widzę tej "słabszości".


>> W przypadku kontynuacji albo masz ogólny skok 
>> do miejsca gdzieś w ciele funkcji z której wołasz, 
>> albo kontynuacja była parametrem 
> 
> Albo wskazujesz inny fragment kodu - continuation passing style da się
> stosować nawet przy użyciu zwykłych procedur (tyle że to mało wygodne).

Ale ten fragment kodu jest skądś dany -- albo zrobiłem go sobie lokalnie 
(czyli tak jak catch / except) albo przyszedł z zewnątrz (czyli lokalnei 
nie wiem gdzie to dalej poleci).

> 
>> tej funkcji i wiesz tyle że leci dalej. W Rumym i podobnych 
>> masz jeszcze opcję, że kontynuacja była zapisana gdzieś 
>> i jawnie do wołanej funkcji nigdy przekazywana nie była 
>> a funkcja sobie i tak wyskoczyła.
> 
> Nie wiem jak wygląda implementacja kontynuacji w Rubym, 
> więc mogę się zgodzić że ją spartaczono skoro tak twierdzisz.

To nie jest kwestia spartaczenia kontynuacji tylko istnienia globalnych 
zmiennych. I (złego) nauczenia ludzi by ich (nad)używali do trzymania 
kontynuacji.


>> W przypadku wyjątków Każda wołana funkcja też ma swoją sygnaturę -- 
>> wystarczy znać tę sygnaturę by wiedzieć jakie wyjątki wypuszcza.
> 
> Ale nie kto je łapie.

Tak samo jest z kontynuacjami. Skaczesz do podanej z zewnątrz 
kontynuacji, ale bez obejrzenia całego kodu nie wiesz skąd się ona 
(kontynuacja) wzięła.


>>> w 3) sprawdzenie poprawności jest pracochłonne
>>> (trzeba rekursywnie sprawdzać kto ten kod wywołuje i które wyjątki 
>>> łapie).
>> Przy statycznej kontroli jak w Javie nie trzeba, bo jak nie jest 
>> obsłużone to się nie skompiluje. Podobnie jak z jawnie przekazywanymi 
>> kontynuacjami.
> 
> Jeśli sygnatura mówi o przerzucaniu wyjątku wyżej to nadal 
> nie wiem, czy to właściwa obsługa błędów, czy wpisana na odwal 
> się, aby skompilowało - trzeba sprawdzać gdzie indziej.
> Całe to rozwiązanie zachęca do robienia stubów które zbiorczo
> łapią wszystko jak popadnie, kontynuacji nie ma sensu tak 
> odbębniać (bo trzeba je wpisać w każdym miejscu).

To tylko jeden parametr. Co gorsza kontynuacje zachęcają by je stworzyć, 
przekazać gdzie są wymagane a następnie po cichu wyrzucić.


>> Tzn. tyle mówi teoria -- i tu i tu można zrobić obsługę wszystkiego w 
>> jednym punkcie. W przypadku wyjątkiem jedno catch / except w "programie 
>> głównym" w przypadku kontynuacji -- jedna kontynuacja wzięta też z 
>> programu głównego. I jak mówi praktyka tak się dzieje dużo dużo częściej 
>> niż byłoby to uzasadnione (dopuszczam przypadki, że to jest 
>> uzasadnione). 
> 
> Zgoda, programowanie to nie smażenie hamburgerów 
> - zawsze można spartaczyć i nie ma co szukać silver bullet.
> Za to różnica jest w łatwości wykrycia takiego partactwa:
> jak trzeba je jawnie wpisywać to widać, a jak nie trzeba 
> (i dobry kod może wyglądać tak samo jak zły) to nie.

Przy specyfikowaniu wyjątków jest nie gorzej niż przy kontynuacjach -- 
czy dodam do funkcji dodatkowy parametr czy dospecyfikuję rzucane 
wyjątki to widać/ nie widać partactwo tak samo.


>>> Istotnie lepsze jest przelecenie kodu pagedownem i patrzenie
>>> czy każdy call ma jawnie wpisaną obsługę błędów, mając pewność
>>> że albo sterowanie przejdzie linijkę dalej, albo (w razie sytuacji
>>> wyjątkowej) przesunie się do wskazanego miejsca - bo z wyjątkami
>>> to nie bardzo wiadomo gdzie to przeskoczy, okaże się w runtimie.
>> A we wskazanym miejscu będzie dispatch do kolejnej kontynuacji 
>> przekazanej z wyższego wołania. 
> 
> Tego się nie da nie zauważyć - bo jest jawne.

Za to nie widać, że jakiś błąd został po cichu zgubiony.

>  
>>>> W Javie masz jawny przepływ sterowania -- wyjątki są częścią sygnatur 
>>> No pliz, to jest tylko wstępna deklaracja jakie w ogóle wyjątki mogą 
>>> zostać rzucone do góry przez cały hektar kodu z niejawnymi wyskokami.
>> Hektar? Jak ktoś napisał funkcję na 1000 wierszy to sam sobie jest 
>> winien. Ta wstępna deklaracja musi pasować do wszystkich wywołań w 
>> połączeniu z obsługą wyjątków w kodzie tą wstępną deklaracją objętym.
> 
> No właśnie musi pasować do wszystkich razem a nie każdego oddzielnie.

A otrzymana z zewnątrz kontynuacja tak samo będzie pasować do wszystkich 
razem.


>>>> Erlang jest nieco bardziej "praktyczny" w użyciu. 
>>> ,,Praktyczny'' to nie jest ficzer ani składni ani semantyki.
>>> Po prostu przyczyny leżą poza językiem, choćby wsparcie
>>> silnego koncernu - gdzie byłaby java bez suna.
>> Nie porównujmy Javy z Erlangiem.
>>
>> Właśnie uważam że istotne znaczenie ma tu semantyka, w połączeniu z 
>> występowaniem w skłądni i w standardowej bibliotece tego, co potrzeba. 
> 
> I które to są te kluczowe różnice w składni i semantyce między 
> Erlangiem a innymi funkcyjnymi? Bo dla mnie jest przede wszystkim mniej
> czytelny, a plusy widzę głównie w maszynie wirtualnej (czy jak to zwać).

Ta wiele rzeczy co ta maszyna wirtualna daje to część semantyki.
Głównie w całej zabawie w przesyłanie komunikatów w około którego 
wszystko się kręci. I w tym, że mamy "wbitą w semantykę" współbieżność.


>>>>>> No właśnie coraz więcej różnych kolesi metaprogramuje w C++. 
>>>>>> Zobacz sobie boost::lambda [...] a zwłaszcza boost::mpl 
>>>>> Zaraz zaraz, używanie lambd czy foralli to nie jest metaprogramowanie.
>>>> Ale ich napisanie w języku w których ich nie ma już jest :)
>>> E tam, to jest użycie biblioteki, co za różnica jak zaimplementowanej.
>> No ale użycie mpl już jest -- bo to w zasadzie jedyne zadanie tej 
>> biblioteki.
> 
> Lambdy, funkcje wyższych rzędów, częściowa ewaluacja i leniwość 
> to cechy w dobrych językach dostępne out of the box, bez żadnego 
> metaprogramowania.

Ale ja nie mówię o tym. boost::lambda to co innego niż boost::mpl. 
boost::mpl daje metefunkcje (biedne i niewygodne ale są).

> Po prostu C++ jest tak biedne, że inaczej niż 
> metaprogramowaniem nie dało się tego doimplementować. Co jeszcze 
> nie znaczy, że używając lambdy pisze się program tworzący programy 
> (fakt że to kwestia definicji MP, ja wysoko stawiam poprzeczkę).

W mpl pisze się programy piszące programy.


>> BTW. nigdy nie podobało mi się użycie monad (plus dziwacznych typów 
>> reprezentujących stan świata) do uzyskiwania prawie-imperatywizmu. 
>> Dla mnie to jest intelektualny hack.
> 
> Zamyka efekty uboczne w piaskownicy, niezły wynik.

Stawiając płot dookoła sebie zamykam świat za płotem? Intelektualny hack 
i tyle :)

W szczególności stan świata jest niezdefiniowany (bo i nie ma jak), jest 
ukrywany w pseudowartości która wartością nie jest. Nie bardzo więc 
można mówić o zbiorze wartości (skoro nie ma wartości), więc i nie 
bardzo można mówić o funkcji.

> 
>> Usiłowanie (niby) czysto funkcyjnej realizacji zadań które 
>> nie dają się sprowadzić do podania argumentów przy wywołaniu 
>> i poczekania na wynik 
> 
> Wszystkie się dają, kwestia czytelności i łatwości napisania.

Nie dają się. Istnieją zadanie w których całe clue polega na tym, że są 
w nich zależności czasowe.


>> Funcyjność nie jest interaktywna, może być 
>> interaktywnie użyta niejako z zewnątrz.
> 
> Nie mam pojęcia, co masz na myśli.

To, że wykonanie funkcji to przygotowanie argumentów i poczekanie na 
wynik. Możesz taką funkcję sobie w różnych miejscach i z różnymi 
argumentami wołać i za każdym razem czekać na wynik. Ale robienie z 
funkcji czegoś co realizuje złożone zależności czasowe to co najwyżej 
intelektualny hack.

pzdr

\SK

-- 
"Never underestimate the power of human stupidity" -- L. Lang
-- 
http://www.tajga.org -- (some photos from my travels)
Technical Details
Message-ID: <9j55v6-ih2.ln1@bozon.softax.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.task.gda.pl!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!atlantis.news.neostrada.pl!news.neostrada.pl!bozon.softax.pl!news
References: <h83in7$rl3$1@inews.gazeta.pl> <op.u2vg6knceaqjf2@mydot.ftpviewlocal.com> <f45ba553-947c-40ff-a96a-88ac21ea20ab@37g2000yqm.googlegroups.com> <op.u26lj6r2eaqjf2@jzabielloosx.dubtilt.local> <929230b3-8c01-4aa0-ba4d-af46cf4196f1@m16g2000yqc.googlegroups.com> <hdqtq7$2qja$1@news2.ipartners.pl> <9417e837-c468-4fe6-9ec8-5c17b268cecd@u7g2000yqm.googlegroups.com> <hds989$q2i$1@news.lublin.pl> <slrnhg3lqh.ee.ps171721@duch.mimuw.edu.pl> <hdslom$1ps$7@news.lublin.pl> <slrnhg3o3d.60f.ps171721@duch.mimuw.edu.pl> <hdsvmg$8mc$1@news.lublin.pl> <slrnhg4ts4.fq3.ps171721@duch.mimuw.edu.pl> <slrnhgqec3.tfh.ps171721@duch.mimuw.edu.pl> <lntcu6-2q7.ln1@bozon.softax.pl> <slrnhh8r0k.kjc.ps171721@duch.mimuw.edu.pl> <kr1fu6-2br.ln1@bozon.softax.pl> <slrnhhd3u2.sq6.ps171721@duch.mimuw.edu.pl> <qvmiu6-434.ln1@bozon.softax.pl> <slrnhhgo44.er.ps171721@duch.mimuw.edu.pl> <ri2nu6-fci.ln1@bozon.softax.pl> <slrnhhttme.gtn.ps171721@duch.mimuw.edu.pl>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.task.gda.pl!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!atlantis.news.neostrada.pl!news.neostrada.pl!bozon.softax.pl!news
From: Sebastian Kaliszewski <s.bez_spamu@remove.this.informa.and.that.pl>
Newsgroups: pl.comp.lang.python
Subject: Re: python vs php - potrzebne argumenty
Date: Wed, 09 Dec 2009 19:54:00 +0100
Organization: TP - http://www.tp.pl/
Lines: 344
Message-ID: <9j55v6-ih2.ln1@bozon.softax.pl>
References: <h83in7$rl3$1@inews.gazeta.pl> <op.u2vg6knceaqjf2@mydot.ftpviewlocal.com> <f45ba553-947c-40ff-a96a-88ac21ea20ab@37g2000yqm.googlegroups.com> <op.u26lj6r2eaqjf2@jzabielloosx.dubtilt.local> <929230b3-8c01-4aa0-ba4d-af46cf4196f1@m16g2000yqc.googlegroups.com> <hdqtq7$2qja$1@news2.ipartners.pl> <9417e837-c468-4fe6-9ec8-5c17b268cecd@u7g2000yqm.googlegroups.com> <hds989$q2i$1@news.lublin.pl> <slrnhg3lqh.ee.ps171721@duch.mimuw.edu.pl> <hdslom$1ps$7@news.lublin.pl> <slrnhg3o3d.60f.ps171721@duch.mimuw.edu.pl> <hdsvmg$8mc$1@news.lublin.pl> <slrnhg4ts4.fq3.ps171721@duch.mimuw.edu.pl> <slrnhgqec3.tfh.ps171721@duch.mimuw.edu.pl> <lntcu6-2q7.ln1@bozon.softax.pl> <slrnhh8r0k.kjc.ps171721@duch.mimuw.edu.pl> <kr1fu6-2br.ln1@bozon.softax.pl> <slrnhhd3u2.sq6.ps171721@duch.mimuw.edu.pl> <qvmiu6-434.ln1@bozon.softax.pl> <slrnhhgo44.er.ps171721@duch.mimuw.edu.pl> <ri2nu6-fci.ln1@bozon.softax.pl> <slrnhhttme.gtn.ps171721@duch.mimuw.edu.pl>
NNTP-Posting-Host: 83.18.189.42
Mime-Version: 1.0
X-Trace: atlantis.news.neostrada.pl 1260382649 15200 83.18.189.42 (9 Dec 2009 18:17:29 GMT)
X-Complaints-To: usenet@news.neostrada.pl
NNTP-Posting-Date: Wed, 9 Dec 2009 18:17:29 +0000 (UTC)
User-Agent: Thunderbird 2.0.0.23 (X11/20090817)
In-Reply-To: <slrnhhttme.gtn.ps171721@duch.mimuw.edu.pl>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit