-
1. Data: 2018-11-16 09:27:40
Temat: Niezmienniki pętli
Od: Maciej Sobczak <s...@g...com>
Zastanawiam się, czy to jest pojęcie wyłącznie akademickie.
W tzw. "normalnym" programowaniu, które praktykuje większość programistów, nigdy nie
widziałem odwołania się do takiej koncepcji w sensie wykorzystania niezmienników w
projektowaniu kodu.
Jak programista ma do napisania pętlę, to w praktyce:
- albo już pisał podobną i napisze jeszcze raz (to jest najczęstszy przypadek),
- albo nie pisał, ale rozumie i napisze posługując się głównie intuicją (wtedy mamy
frajdę, bo coś nowego),
- albo nie rozumie i nie napisze.
Niezmienniki pozwalają jednak pętlę zaprojektować albo przeanalizować i np. dojść do
wniosku, że jest poprawna.
Nie pytam o metody formalne, tylko o powiedzmy nieco bardziej świadomą praktykę
programistyczną. Nazwijmy to ładnie "attentive engineering". Albo "mindful
engineering".
Pytanie jest takie: czy ktoś z Was spotkał się z tym pojęciem (poza szkołą) a nawet z
niego skorzystał w praktyce? Czy to jest praktyka, do której staracie się sięgać w
tym trzecim przypadku? A może bardziej regularnie?
Czy może po prostu w ogóle temat jest oderwany od tzw. rzeczywistości?
Ciekawi mnie Wasze spojrzenie na tą sprawę również wtedy, gdy piszecie w językach
nie-imperatywnych, gdzie takich klasycznych pętli jest mniej albo w ogóle ich nie ma.
Czy w związku z tym zagadnienie niezmienników jest niepotrzebne? A może nadal jest
potrzebne i coś innego je zastępuje?
Wersja dla quizowiczów:
- wiem i używam albo pamiętam, że mogę,
- słyszałem i ignoruję,
- nie rozumiem pytania[*].
[*] https://en.wikipedia.org/wiki/Loop_invariant
--
Maciej Sobczak * http://www.inspirel.com
-
2. Data: 2018-11-16 16:22:45
Temat: Re: Niezmienniki pętli
Od: q...@t...no1 (Queequeg)
Maciej Sobczak <s...@g...com> wrote:
> - wiem i używam albo pamiętam, że mogę,
> - słyszałem i ignoruję,
> - nie rozumiem pytania[*].
>
> [*] https://en.wikipedia.org/wiki/Loop_invariant
Nie słyszałem, teraz się dowiedziałem. Nigdy nie używałem.
--
https://www.youtube.com/watch?v=9lSzL1DqQn0
-
3. Data: 2018-11-16 16:48:17
Temat: Re: Niezmienniki pętli
Od: s...@g...com
> Czy w związku z tym zagadnienie niezmienników jest niepotrzebne? A może nadal jest
potrzebne i coś innego je zastępuje?
1. Wiedziałem co to jest.
2. Stosuję
3. Sam też stosujesz
Najprostrze zastosowanie:
QList<int> lList = {0, 1, 2, 3, 4, 5};
for(int i(0); i < lList.size(); ++i)
// tu robisz coś z lList
W tej pętli niezmiennikiem sprawdzanym przed wejściem w pętlę i po kazdej iteracji
jest:
i < lList.size()
Nieco bardziej ogólne jest:
QList<int> lList = {0, 1, 2, 3, 4, 5};
for(int& lItem : lList)
// tu robisz coś z lItem
W tym przypadku niezmiennikiem (ukrytym) jest fakt iteracji po wszystkich elementach
listy.
4. Zazwyczaj dalszych niezmienników w pętli nie sprawdzam. Głównie ze względu na 2
wady:
4.1. Puchnięcie i zaciemnianie kodu.
4.2. Spowolnienie programu.
5. Bardzo często sprawdzam parametry wejściowe funkcji (wierzę i stosuję coś w
rodzaju programowania kontraktowego).
5.1. Wierzę w try, throw, catch (wyjątki obowiązkowo dziedziczone po std::exception z
opisem i kodem błędu).
5.2. Nie wierzę w i nie cierpię Assert (to tak jak by bez ostrzeżenia uderzyć kogoś w
twarz bez dalszego komentarza).
5.3. Toleruję wartości zwracane (jako informacje o błędach) i brak standaryzacji w
dostępie do opisów błędów w Qt.
-
4. Data: 2018-11-16 16:50:03
Temat: Re: Niezmienniki pętli
Od: s...@g...com
> wierzę i stosuję coś w rodzaju programowania kontraktowego
https://pl.wikipedia.org/wiki/Programowanie_kontrakt
owe
-
5. Data: 2018-11-16 17:18:42
Temat: Re: Niezmienniki pętli
Od: AK <n...@n...net>
On 2018-11-16 16:22, Queequeg wrote:
> Maciej Sobczak <s...@g...com> wrote:
>
>> - wiem i używam albo pamiętam, że mogę,
>> - słyszałem i ignoruję,
>> - nie rozumiem pytania[*].
>>
>> [*] https://en.wikipedia.org/wiki/Loop_invariant
>
> Nie słyszałem, teraz się dowiedziałem. Nigdy nie używałem.
Identycznie.
No... prawie. "Widzialem" invariaty w Eifflu, ale w tym kontekscie
nie/nie mialem pojecia, ze tak mozna i ze to cos daje.
AK
-
6. Data: 2018-11-16 20:14:21
Temat: Re: Niezmienniki pętli
Od: q...@t...no1 (Queequeg)
s...@g...com wrote:
> Najprostrze zastosowanie:
^^
sz
> for(int i(0); i < lList.size(); ++i)
> // tu robisz coś z lList
> W tej pętli niezmiennikiem sprawdzanym przed wejściem w pętlę i po kazdej iteracji
jest:
> i < lList.size()
"In computer science, a loop invariant is a property of a program loop
that is true before (and after) each iteration."
Twierdzisz, że po ostatniej iteracji pętli i < lList.size() będzie dalej
true?
Nie myl niezmiennika z warunkiem kontynuowania pętli.
> 5.2. Nie wierzę w i nie cierpię Assert (to tak jak by bez ostrzeżenia
> uderzyć kogoś w twarz bez dalszego komentarza).
Czyli twoim zdaniem lepiej, gdy program działa dalej na błędnych danych i
w sposób, którego nie przewidział programista, niż gdy wypisze komunikat
o błędzie wraz z lokalizacją, niespełnionym warunkiem i np. innymi
informacjami diagnostycznymi i zakończy się, nie robiąc szkód?
Bo wiesz, oprogramowanie się testuje, takie błędy wychodzą i takie błędy
się poprawia, zamiast ignorować.
--
https://www.youtube.com/watch?v=9lSzL1DqQn0
-
7. Data: 2018-11-16 20:40:34
Temat: Re: Niezmienniki pętli
Od: s...@g...com
W dniu piątek, 16 listopada 2018 20:14:23 UTC+1 użytkownik Queequeg napisał:
> s...@g...com wrote:
>
> > Najprostrze zastosowanie:
> ^^
> sz
>
> > for(int i(0); i < lList.size(); ++i)
> > // tu robisz coś z lList
> > W tej pętli niezmiennikiem sprawdzanym przed wejściem w pętlę i po kazdej
iteracji jest:
> > i < lList.size()
>
> "In computer science, a loop invariant is a property of a program loop
> that is true before (and after) each iteration."
>
> Twierdzisz, że po ostatniej iteracji pętli i < lList.size() będzie dalej
> true?
>
> Nie myl niezmiennika z warunkiem kontynuowania pętli.
Ok! W takim razie nie używam niezmienników pętli ani niezmienników klas. Za wolne to
jest na wersję release. Może warto by było to pisać w blokach kompilowanych
warunkowo.
> > 5.2. Nie wierzę w i nie cierpię Assert (to tak jak by bez ostrzeżenia
> > uderzyć kogoś w twarz bez dalszego komentarza).
>
> Czyli twoim zdaniem lepiej, gdy program działa dalej na błędnych danych i
> w sposób, którego nie przewidział programista, niż gdy wypisze komunikat
> o błędzie wraz z lokalizacją, niespełnionym warunkiem i np. innymi
> informacjami diagnostycznymi i zakończy się, nie robiąc szkód?
>
> Bo wiesz, oprogramowanie się testuje, takie błędy wychodzą i takie błędy
> się poprawia, zamiast ignorować.
Czytaj ze zrozumieniem:
> 5.1. Wierzę w try, throw, catch (wyjątki obowiązkowo dziedziczone po std::exception
z opisem i kodem błędu).
-
8. Data: 2018-11-16 20:51:30
Temat: Re: Niezmienniki pętli
Od: g...@g...com
W dniu piątek, 16 listopada 2018 09:27:41 UTC+1 użytkownik Maciej Sobczak napisał:
> Zastanawiam się, czy to jest pojęcie wyłącznie akademickie.
>
> W tzw. "normalnym" programowaniu, które praktykuje większość programistów, nigdy
nie widziałem odwołania się do takiej koncepcji w sensie wykorzystania niezmienników
w projektowaniu kodu.
> Jak programista ma do napisania pętlę, to w praktyce:
> - albo już pisał podobną i napisze jeszcze raz (to jest najczęstszy przypadek),
> - albo nie pisał, ale rozumie i napisze posługując się głównie intuicją (wtedy mamy
frajdę, bo coś nowego),
> - albo nie rozumie i nie napisze.
>
> Niezmienniki pozwalają jednak pętlę zaprojektować albo przeanalizować i np. dojść
do wniosku, że jest poprawna.
> Nie pytam o metody formalne, tylko o powiedzmy nieco bardziej świadomą praktykę
programistyczną. Nazwijmy to ładnie "attentive engineering". Albo "mindful
engineering".
>
> Pytanie jest takie: czy ktoś z Was spotkał się z tym pojęciem (poza szkołą) a nawet
z niego skorzystał w praktyce? Czy to jest praktyka, do której staracie się sięgać w
tym trzecim przypadku? A może bardziej regularnie?
>
> Czy może po prostu w ogóle temat jest oderwany od tzw. rzeczywistości?
>
> Ciekawi mnie Wasze spojrzenie na tą sprawę również wtedy, gdy piszecie w językach
nie-imperatywnych, gdzie takich klasycznych pętli jest mniej albo w ogóle ich nie ma.
Czy w związku z tym zagadnienie niezmienników jest niepotrzebne? A może nadal jest
potrzebne i coś innego je zastępuje?
>
> Wersja dla quizowiczów:
> - wiem i używam albo pamiętam, że mogę,
> - słyszałem i ignoruję,
> - nie rozumiem pytania[*].
>
> [*] https://en.wikipedia.org/wiki/Loop_invariant
>
> --
> Maciej Sobczak * http://www.inspirel.com
Kevlin Henney poruszył ten temat w jednej z prezentacji,
pokazując związek logiki Hoare'a z "metodyką" "given-when-then"
stosowaną przy pisaniu testów:
https://www.youtube.com/watch?v=JiQct3QixMo
Jeżeli idzie o mnie, to zastanawianie się nad "warunkami początkowymi"
i "warunkami końcowymi" wydaje mi się dziwne. I o ile wyrażanie własności
programów wydaje mi się ważnym skillem (np. w połączeniu z model-checkerami
albo property-based testing), i dostrzegam pewną wartość w akademickich
narzędziach pokroju ATS i liniowych systemach typów, o tyle pytanie
o niezmienniki pętli jest dla mnie po prostu nienaturalną formą
rozumowania.
(Ale też jeśli mam wybór, wolę myśleć w oparciu o równania rekurencyjne,
niż imperatywne pętle)
-
9. Data: 2018-11-16 21:05:11
Temat: Re: Niezmienniki pętli
Od: q...@t...no1 (Queequeg)
s...@g...com wrote:
>> Nie myl niezmiennika z warunkiem kontynuowania pętli.
>
> Ok! W takim razie nie używam niezmienników pętli ani niezmienników klas.
> Za wolne to jest na wersję release. Może warto by było to pisać w
> blokach kompilowanych warunkowo.
Pytanie czy w danym zastosowaniu prędkość wykonania jest krytyczna, czy
może poprawność jest ważniejsza...
>> Czyli twoim zdaniem lepiej, gdy program działa dalej na błędnych danych i
>> w sposób, którego nie przewidział programista, niż gdy wypisze komunikat
>> o błędzie wraz z lokalizacją, niespełnionym warunkiem i np. innymi
>> informacjami diagnostycznymi i zakończy się, nie robiąc szkód?
>>
>> Bo wiesz, oprogramowanie się testuje, takie błędy wychodzą i takie błędy
>> się poprawia, zamiast ignorować.
>
> Czytaj ze zrozumieniem:
>> 5.1. Wierzę w try, throw, catch (wyjątki obowiązkowo dziedziczone po
std::exception z opisem i kodem błędu).
Ok, to spytam inaczej: czym, wg ciebie, jest asercja?
(dla uproszczenia: mówię o asercji sprawdzanej w czasie wykonania, nie o
statycznej, sprawdzanej w czasie kompilacji)
--
https://www.youtube.com/watch?v=9lSzL1DqQn0
-
10. Data: 2018-11-16 23:51:07
Temat: Re: Niezmienniki pętli
Od: Maciej Sobczak <s...@g...com>
> Najprostrze zastosowanie:
> QList<int> lList = {0, 1, 2, 3, 4, 5};
> for(int i(0); i < lList.size(); ++i)
> // tu robisz coś z lList
> W tej pętli niezmiennikiem sprawdzanym przed wejściem w pętlę i po kazdej iteracji
jest:
> i < lList.size()
Tak jak już zauważył Queequeg, to nie jest niezmiennik. W ogóle we wzorcu projektowym
o nazwie "jadę po kontenerze" nie ma niezmienników, chyba że weźmiemy pod uwagę
następujący:
- elementy o indeksach większych od i nie zostały jeszcze odwiedzone
Ale taki niezmiennik (chociaż prawdziwy) jest sztuczny i nic nie wnosi.
Ciekawsze są niezmienniki w tych pętlach, które swoim działaniem budują jakiś wynik i
ten wynik ma jakąś ważną stałą cechę. Np. zewnętrzna pętla w algorytmie sortowania
przez wybieranie ma taki niezmiennik:
- elementy o indeksach mniejszych od i są już posortowane
I taki niezmiennik jest już ciekawszy, bo bez patrzenia na algorytm jako całość
pozwala uzasadnić, że ta całość faktycznie coś sortuje.
Ale jak rozumiem z sondażu, nikt tego nie stosuje. Pewnie ma to związek z faktem, że
algorytm sortowania przez wybieranie już został wymyślony. :-)
> 5.2. Nie wierzę w i nie cierpię Assert (to tak jak by bez ostrzeżenia uderzyć kogoś
w twarz bez dalszego komentarza).
To też jest ciekawe. Zwłaszcza, że assert statyczny i dynamiczny to nie to samo.
--
Maciej Sobczak * http://www.inspirel.com