|
#61
|
|
|
|
|
Witam
> > Ah jak ja sie ciesze, ze zapanuje blogi spokoj nie porownywania, ale > > jakby porownywania. > > Nie zapanuje. Ja mam zwyczaj chwalić / krytykować to co znam. C++ znam > więc... :) No więc czemu nie można porównywać Scali i Pythona,? Poki co uzasadnienie jest takie, że nie można bo są na tyle rożne, że nie mozna. C++ jest na tyle różny od Pythona, że też ustalamy, że nie można ich porównywać. Pozdrawiam, Seweryn Habdank-Wojewódzki. |
|
|
|
#62
|
|
|
|
|
Witam
> Twój świat jest płaski. Jeśli wyjdziesz jednak poza płaskie struktury typu > mapa, lista, macierz czy wektor to często masz tak że nie tylko obiekty się > różnią, ale zależnie od typu różne są ich relacje z innymi elementami tej > samej struktury. Tak jest choćby w drzewie wyprowadzenia czy abstrakcyjnym > drzewie składni programu. To znaczy, że kłopoty są z rozróżnieniem iteratora od odwiedzającego. Iterator ma zadanie przesuwać się w strukturze niepłaskiej. Zadanie odwiedzjącego jest odpalanie określonej funkcjonalności. I wlasnie dlatego mam zle zdanie o tym wzorcu. Miesza wszystko w tyglu. Przykład Wiktora jest właśnie świadectwem na to. W nim, np. wyseparowałbym dodatkowo wzorzec stan (wspólny), bo jesli x,y,z nie maja nic wspolnego z u i v (czy jak im tam) to jesli mają jakis wspolny stan z ktorego pochodza to mozna go wyseparowac. I zaczyna si epowolny proces rozplatywania zawilosci w tym kodzie, gdzie nagle w jednym miescu pomieszane jest wszystko. Rozne argumenty, potencjalnie rozne typy argumentow (chociaz nie widze jak taki kod czysto wyglada, np. w Scali.), rozne typy objektowo wizytowanych, I jeszcze to nieszczesne iterowanie, ktore Twoim zdaniem jest zadaniem odwidzającego. A ja sugeruje, ze odwiedzajacy ma flote transportowa i jego zadaniem nie jest poruszanie sie tylko np. zbieranie podatku i tyle. > W wielu wypadkach taka jest natura problemu. Projekt jest dobry a wszelkei > inne kombinacje prowadzą do projektu gorszego. Znam przypadki, że goto musi być użyte. I to jest nie podważalne w tych przypadkach. Kiedys nawet na tej grupie podałem taki przykład gdzie ewidentnie rozwikłanie kodu z goto, było pogorszeniem tego kodu. Ale! Nie jest prawdą, że stosowanie goto jest dobre. Zawsze należy rozważyć jego eliminację. > Nie ma metod poprawy projektu, gdy problem nie jest przyjemnie płaski. Twoje > podejście to prosta droga do "jeśli projekt nie odpowiada rzeczywistości to > tym gorzej dla rzeczywistość". I doesn't Work(tm). Hmm... Matematyka wielokrotnie pokazała, że myślenie inne niż rzeczywistość bardziej odpowiada rzeczywistości -- tej prawdziwej. Zawsze staram się oderwać od rzeczywistości dorbnego problemu i spojrzeć na zadanie globalnie. Szczególnie to jest bardzo ważne, kiedy w jednym miejscu spotykają się różne wzorce i można je tam wykorzystać wielokrotnie do różnych celów. Odwiedzjący jest jednym z najtrudniejszych zadań. Szczególnie jeśli miesza się domyślnie z iteratorem, czasem ze stanem lub pyłkiem jeszcze czasami z metodą szablonową lub strategią. A gdziejś po drodze w okół stanu i lub pyłka pałęta sie serializacja. Dobra dekompozycja tego wszystkiego pozwala na zrobienie bardzo efektywnej struktury -- w sensie maintainowania. > Nie. To bardzo często znaczy że jedna klasa wymaga 0 inna 1 inna 2 inna 3 a > inna listy o zmiennej długości. I typy tych parametrów też są skrajnie > różne -- po np. jeden to jakiś skalar a inny to... inny element naszej > struktury lub nawet cała jej podstruktura. Hmm... i co? Ty chcesz to wszystko sprawdzić wewnątrz odwiedzającego. Ja staram się jak najbardziej dobrać odwiedzającego do zadania. Istaram się, aby odwiedzający rozumiał język odwiedzanego, a nie musiał cały czas chodzić z rozmówkami pod ręką. > > Jeżeli jest jakieś specjalne bardzo pokręcone zachowanie. > > Rozważam (i o tym pisałem) zastosowanie listy typów. > > Lista typów statyczna ma wadę o jakiej mowa w całym tym odgałęzieniu. Co z > tego, że jest statyczna skoro nie ma statycznej detekcji kompletności, > którą daje rzeczony Wizytator. Czemu nie ma? Nie myślisz dualnie do problemu. Typowe podejście jest takie przychodzi odwiedzający do x i do odpytuje, czyli w(x). A ja równocześnie myślę, że to x jest w relacj z w i mogę zadać pytanie czy mogę sprawdzić x(w). Zatem switch po typach zamieniam, na listę typow iterowana dzialającą na w. Czyli nawet testowo, mogę zapodać przeiterowanie wszystkich potencjalnych klas obslugiwanych przez odwiedziajacego w komponujac dualne API tak, aby było x(w). Bajkowy przykład: masz narzędzia i kawałki domu. Ty tylko i wyłącznie chcesz robić tak: ściana:-> wiertarka, młotek gwóźdź. Drzwi:-> wiertarka młotek gwóźdź. A Ja myślę jeszcze (oprócz tego powyżej) tak: wiertarka(ściana), młotek (ściana), gwóźdź (ściana), wiertakrka(dżwi), młotek (drzwi), gwóźdź (drzwi). I to ładnie załatwia lista typów <wiertarka, młotek, gwóźdź> pradująca na (x) gdzie x może być ściana lub drzwi. > Nonsens. Język ogólnego przeznaczenia który ignoruje istotny obszar ogólnej > rzeczywistości ma poważną wadę. Jakiej rzeczywiostości? Poprosze o przykład. > To nie jest świetnik w czymiś kodzie tylko dostostosowanie się do > rzeczywistości która często nie chce być płaska. Wyciąłeś moją bajkę, bo dla Ciebie rzeczywistość to wóda pita z gwinta. Dla mnie to nie jest procentowa rzeczywistość kodu który chcę po sobie zostawić. Tak jak powiedziałem nie brzydzę się goto, ale to jest ostateczność. Tak samo wizytatora staram się zrobić najlepiej i najczyściej jak się tylko da. > Co ty tu w ogóle? Wizytatora nie łata się switchem. Wizytator to jest idiom, > obejście, na brak odpowiedniej konstrukcji językowej. Pokaż mi język statycznie typowany gdzie kod jaki podał Wiktor jest elegancki. Przykład typów algebraicznych w Scali był upiększony i odchodzony ponieważ nie obsługiwał x,y,z całkiem innych niż u i v. Do tego jeszcze w kodzie Wiktora nie było nazw używanych metod. >> Nonsens. UnaryExpression to nie BinaryExpression i nie ConditionalOperation > i nie FusedBinaryExpression i nie TernaryExpression i nie > FunctionApplication. Super. A jak one się tam wtakim razie znalazły, jeśli nie mają NIC ze sobą wspólnego? Czym jest x,y,z i u i v? Podobne "obrazki" widzi się w rozbiorze drzewa wyrażeń matematycznych. A jednak tam się da posprzątać. W szczególności, że można pomyśleć dualnie. Czyli, że działamy operatorem na stanie zawartym w odwiedzającym, a nie ze ten bidny odwiedzający ma robić wszystko. > Ich użycia nie podlegają ujednoliceniu z tego fundamentalnego powodu, że to > na czym są używane jest zasadniczo inne. Kwestia podejścia. > Możesz się zgadzać lub nie -- faktów to nie zmieni. Wiem, widziałem nie jeden kod w C i C++ i jak mam zadobry humor to odwiedzam ActiveState i czytam recipsy, szczególnie mocne sa Perl (96% hardcore), potem Python (70% hardcore). Chłopaki prześcigują się jak coś napisać "krócej". > > Jeśli ktoś zamiast switch w obsłudze Wizytatora użyje > > if (){} else if(){} ... to co? > > To nie jest obsługa Wizytatora! Wizytatora tu nie ma! To jest jego core w proponowanej drodze myślenia. > To Wizytator jest obejściem na brak wałściwej konstrukcji językowej. Czy ty Sebastian wściekłeś się? Naprawdę ludzki mózg jest tak obszerny i tak twórczy, że zawsze będą pomysły, których nie wspierają języki, żadne. Pokaż mi język, który elegancko załatwia problem, ktory postawiłem jakiś czas temu dotyczący generycznej transpozycji kontenerów. Nie widzę takiego języka w promieniu kilku języków ktore znam i nie przypuszaczam, że to się łatwo rozwiązuje w tych o których słyszałem. Jednocześnie NIE twierdzę, że te wszystkie języki są do bani! > Gdyby problemy było nudno płaskie to różne rzeczy nie byłyby potrzebne. > Wizytator jest potrzebny jako idiom w językach statycznych, w których brak > odpowiedniej konstrukcji. Podaj język statyczny, który rozwiązuje wszystkie problemy wizytacji i jeszcze jak dorzucisz odrazu jako gratic to, że ŻADEN wzorzec projektowy nie musi być używany, bo język ma go wbudowanego, to bedzie super. A bosko będzie jeśli zadamzadanie matematyczne z mojej przestrzeni ostatnio 19 wymiarowej i język komendą do_it() zrobi to co chcę. Przekleństwem informatyki jest to że wzlania ludzi z myślenia. Informatyka powinna ułatwiać "robotę" automatyczną i nudną, ale myślenie powina stymulować do granic ludzkiego pojęcia. Niech mi ktoś wytłumaczy dlaczego największe mózgi informatyczne znają przedewszystkim te języki, które sa trudne, ktore nie zwalniaja z myslenia, ktore wrecz wyciskają z czlowieka siódme poty, nie mowie tylko o C. Bo np. czysto lispowe zamieniamie kazdej petli na rekurencje to jest szczegolnie dla poczatkujacych bardzo duze wyzwanie. No dobra. To na tyle bajek, bo i tak zostaną wycięte. Pozdrawiam, Seweryn Habdank-Wojewodzki. |
|
#63
|
|
|
|
|
Witam
> ma problemu, bo nie sprawdzamy wprost klas, a wartości określanego enuma, > przy czym to już do kodu klas (napisanego przez programistę) powiązanie > tego enuma z klasami, np: > > static enum IdentyfikatoryKlas { /* ... */ }; [...] Też taki kod napisałem w tym wątku. > Ale np. to się nie skompiluje > > class Foo {}; > class Bar: public Foo {}; > > Bar *ptr = new Foo(); > > Nie skompiluje się bo jest błąd. Zadaniem systemu typów jest wykrywanie > błędów. Oczywiście!!! > [...] > > >> W tym Wizytatorze masz Dokładnie to Samo(tm). Tylko, że więcej kodu i kod > >> jest porozrzucany po różnych miejscach. > > > To nie jest wizytator. To jest gniot na rządanie. > > Nie. To jest Wizytator -- na tym on właśnie polega. Wizytator polega na odwiedzaniu, a nie na bezmyślnym przepisywaniu kodu który powstał. Maciek skrytykował GoF i napisał swoje i na tym polega sukces. Ja uważam, że jest gro sytuacji, kiedy. Kod Maćka można jeszcze poprawić eliminując switch. > Jeśli Xiński dopisał klasę a ty jej nie obsługujesz to nie działa w sensie > najbardziej parszywym -- jest bug. Hmm... chyba się nie rozumiemy. Ale nasze dyskusje przez to są bardzo ciekawe. Ja o rybkach, Ty o grzybkach. Mowię, że samo napisanie klasy jeszcze niczego nie powinno powodować. Dopiero użycie jej powinno ją aktywować. > > Dla mnie do kitu to jest wizytator robiony switchem. > > Mniej do kitu niż Wizytator "Obiektowy" taki jak go opisuje GoF. Ten jest gorszy niż Maćka i ja GoF nie bronię. > > Czy standard C++ ma się zajmować problemem AIDS w EU? > > Standard C++ czyli języka ogólnego przeznaczenia ma się zajmować > użytecznością tego języka do rozwiązywania ogólnych problemów (w tym np. > pisania translatorów języków) No więc chłopaki pisząc GCC zmierzą się z podobnym problemem. Zobaczymy, czy im wyjdzie. Trzymam kciuki, cociaż zadanie jest trudne szczególnie politycznie. > Chyba nie zrozumiałeś. Maciek zamiast Wizytatora proponuje co innego, > właśnie ów Checked Switch. Wiem. Zrozumiałem ja chcę iść dalej i nie mieć switch, tylko samo checked. > Jak już napisałem gdzie indziej pewne problemy są wredne i albo mamy > odpowiednią konstrukcję językową (typy algebraiczne, checked switch) albo > robimy obejście idiomem Wizytator. Inne wyjścia charakteryzują się > niedopuszczalnym poziomem kaszany w kodzie. Poproszę o rzeczywisty przykład, spróbuję się zmierzyć. Za pewne masz rację, ale ja skorzystam, bo się czegoś nauczę. Póki co zamiast rozwiązywać problemy bijemy pianę. Pozdrawiam, Seweryn Habdank-Wojewódzki. |
|
#64
|
|
|
|
|
Dnia 06.07.2008 Seweryn Habdank-Wojewodzki <sh-w.SKASUJ> napisał/a:
> Bo np. czysto lispowe zamieniamie kazdej petli na rekurencje to jest > szczegolnie dla poczatkujacych bardzo duze wyzwanie. Ekhm, co to jest ,,czysto lispowe zamienianie każdej pętli na rekurencję''? W przypadku Scheme można by się zgodzić, ale common-lispnik jak chce napisać pętlę, to pisze pętlę (używając którejś z całej masy konstrukcji do pętlenia, np. DO, DOTIMES, LOOP czy niestandardowe, ale świetne, ITERATE). Choć i w Scheme (R5RS) jest DO. |
|
#65
|
|
|
|
|
Daniel Janus wrote:
> Ekhm, co to jest ,,czysto lispowe zamienianie każdej pętli na > rekurencję''? Coś, co tym bardziej mi się podoba im dłużej o tym myslę... ;-) Skoro iteracja jest równoważna rekursji pod względem wyrażalności, a zdecydowana większośc znanych mi pętli to wariacje na temat for_each, czyli funkcyjnego map, to dochodzę do wniosku, że należy pozbyć się imperatywnych konstrukcji sterujących w rodzaju for lub while jako pierwszoplanowych konstrukcji języka i zastąpić je lukrem syntaktycznym transformującym te pętle do rekursji. A w kompilatorze to sobie "odwiniemy", czy to prymitywnymi metodami takimi jak eliminacja rekursji ogonowej, czy też bardziej złożoną analizą równań różnicowych, podnoszeniem odpowiednich macierzy do potegi itp. Cóż, coraz bardziej "funkcyjnieję" na stare lata, co począć... ;-) Pozdrawiam Piotr Wyderski |
|
#66
|
|
|
|
|
Witam
> Ekhm, co to jest ,,czysto lispowe zamienianie każdej pętli na rekurencję''? > W przypadku Scheme można by się zgodzić, ale common-lispnik jak chce napisać > pętlę, to pisze pętlę (używając którejś z całej masy konstrukcji do pętlenia, > np. DO, DOTIMES, LOOP czy niestandardowe, ale świetne, ITERATE). Choć i w > Scheme (R5RS) jest DO. Mówię o treningu myślenia, a nie o możliwościach języka! Książkę, którą czytałem o "Lispie" cenię włąśnie za to,że kazała mi zapomnieć o "for". A Common Lisp jest językiem który for'a wprowadził "do standardu". Z resztą niech bedzie i Scheme, mnie sią Logo dobrze kojarzy w tym temacie. Obojętne. Mówię o kształtowaniu myślenia abstrakcyjnego, a nie o detalach który język co ma i czego nie ma. Pozdrawiam, Seweryn Habdank-Wojewódzki. |
|
#67
|
|
|
|
|
Witam
> czy też bardziej złożoną analizą równań różnicowych, > podnoszeniem odpowiednich macierzy do potegi itp. To się robi jako kawałek filtracji obrazów. Bardzo skuteczne są metody zaszywania takich prostych rzeczy w FPGA. Kiedy obraz z framegrabera wpada na banalna matryce i ma zostac wykonana "iteracja" filtru. Oczywiście nie zaszywa się całego potęgowania macierzy, bo nie potrzeba, ale to jest zbliżona rodzina zadań. Gdzie obraz staje się jakby odzwierciedleniem MxK jedno wymiarowych procesów stochatycznych, ktore należy filtorwać. Przydostępie do większej mocy FPGA można zafundować sobie badanie również niedalekiego sąsiedztwa, danej trajektori (czyli koloru pixela w czasie). Pozdrawiam, Seweryn Habdank-Wojewodzki |
|
#68
|
|
|
|
|
Seweryn Habdank-Wojewodzki wrote:
> Jeżeli za "// do something with the saw" kryje się, > np. use albo whatever, to nie potrzeba > mieć tego switch, bo KAŻDY Tool ma albo USE albo WHATEVER. > Przy czym zakładam, że Tool : public /*,np.*/ Usable. Bardzo prymitywny przykład. W rzeczywistych projektach wydzielenie wspólnego interfejsu może być średnio ciekawe. Np. USE może dla młotka przyjmować gwoździe a dla wiertarki wiertło. Jak tutaj wydzielić wspólny interfejs? > Uwaga! Jeżeli tak nie jest, to uważam, że projekt jest do poprawy > (lub czytaj dalej). Widziałem próby takie poprawy które czasami kończyły się: class someToolForMakingHoles: useAsHammer, useAsDrill ... ze sporą ilością pustych metod w każdej klasie. Dzięki wizytacji można uniknąć tworzenia częsci wspólnej interfejsu na siłę. Do tego stopnia nawet, że jedynym wspólnym intefejsem jest akceptacja wizytora. Ma to _czasami_ spore zalety. Tym bardziej, że z punktu widzenia jednych częsci kodu jakiś wspólny interfejs istnieje a z punktu widzenia innych - nie ma absolutnie żadnego wspólnego. Alternatywnie robi się setki adapterów które słodko utrudniają refaktoring i po cichu żeby nikt nie widział robi "dynamic_cast" z cichą modlitwą żeby się powiodło. > Jeżeli jest tak, że metody przyjmują jakieś x,y a inne z,q i one > są różnych typów, to jest również do korekty projektowej. Czyli USE powinno przyjmować gowździe albo wiertła a najlepiej oba? Nie rozumiem. > Następnie kolekcja zawiera USABLE*. I mogę wołać po prostu: > it->use(...) No to znowu przypadek trywialny. Życie składa się czasami z wołania metod z różnymi parametrami i co gorsza - typami. W tym miejscu it-> musisz znać różne typy albo na chama nagiąć ich interfejsy do wspólnego. I to rodzieranie szat tylko z powodu fobii? > NIE POTRZEBUJE SWITCH!!! Całe szczęscie, bo standardowa wizytacja nie używa switch i nowe konstrukcjie w c++ nie są potrzbne. > Wyjście: > Opakować parametry w klasę boost::any, DynamicAny, whatever. > Może być boost:variant, który jest bardziej restrykcyjny niż boost::any. ROTFL. I tak zamieniasz C++ na jakiś nie przymierzając php. A wizytacja robi to samo nie niszczać statycznej kontroli typów, wręcz wywalając błedy kompilacji jeśli coś spieprzysz. Nie wybrażam sobie używanie typów dowolnych w poważnym programie tylko z powodu fobii przed wizytacją. Można pozbywać się wizytacji jakimiś brutalnymi metodami przez adaptery, ale na rany boskie tylko nie any ! To nie Basic ! > Jeśli stan jest bardziej homogeniczny to lepiej mieć własny typ MyParam. > Dedykowany do przesłania parametrów ogólnych, ale dobrze określonych, > np.tylko int i string. W brew pozorom to nie jest złe > rozwiązanie. Co więcej zazwyczaj problemy są nie z typami skomplikowanymi, > a z typami prostymi jak double, int, czy char*, a tych nie jest wiele. Znowy trywializujesz. Takie przypadki mają sens kiedy obiekty leżą blisko siebie funkcjonalnie. Są projekty gdzie żeby wykonać jakąś akcję należy w obiekcie 1 wywołać metodę z typem X, w obiekcie 2 dodać coś do kolekcji a w obiekcie 3 odczytać pole. Wszystkie te trzy akcje mają ten sam sens logiczny dla klienta. Sposoby obsługi objektów zasadniczo się różnią. Klient ma dostać N adapterów (które trzeba napisać) do tego czy jednego wizytora? Co łatwiej napisać? Różnica niewielka, ale ... mimo wszystko ... wizytory wyglądają znacznie sympatyczniej opakowując całą funkcjonalnośc w jednym miejscu. > I statyczną iterację po typach. Oraz wykonanie jakichś funkcji > z zestawu funkcji, pobierających statycznie określony typ. > > use (Hammer & t, What & w), use(Axe & a, What & w). > > A w nich: > use (Hammer & t, What & w) {/*&Hammer::*/t.bij(w)} > use (Axe & a, What & w) {/*&Axe::*/a.siecz(w)} > use (Młotek & m, Kotek & k) { m.pieprz (k)} > (i one mogę być elegancko przeładowane, czy jak to się nazywa). > > Jeżeli mam listę typów, np. boost::tuple mytuple tuple<Hammer, Axe>. > To mogę wykonać coś ala > > boost::tuple_for_each <mytuple> (use(...)). Łomatko. A to wszystko daje ten sam efekt 10x bardziej skompikowany sposób niż wizytacja. Możesz wskazać jakikolwiek zysk z takiego podejścia poza ulgą że już nie masz wizytorów ? > W każdym razie znowu nie mam switch po typach odwiedzanych. Nic dziwnego, w wizytacji na dzisiaj nie ma switch w sposób widoczny gdziekolwiek. > Natomiast zaleta jest taka, ze jeśli te klasy czy są powiązane, > czy nie, pracują razem mając ustalone API. Nie zawsze takie API istnieje z punktu widzenia klienta. Powiem więcej, czasami bardzo źle by było jak by istniało. > Wizytor to nie jest lekarstwo na braki w języku. > To jest dziurawa przykrywka na śmietnik w kodzie i w projekcie. Nie widziałeś jeszcze _wszystkich_ projektów. Ja też nie. Dlatego nieco pokory, możesz się zdziwić że jednak wizytacji używa się w całkiem sporych . > Komitet, który szanuję, ma wystarczająco dużo problemów, > aby zajmować się śmietnikiem w moim kodzie. Dlatego > NIE uważam, że komitet ma zająć się poprawą switch'a > tylko dlatego, że Wizytator będąc słabym wzorcem > projektowym, którego trzeba łatać switchem, a to wymaga poprawy > switcha. Nic nie trzeba łatać. Wizytacja działa praktycznie tak samo bez tej konstrukcji. Nie ma potrzeby. > Mam ograniczone doświadczenie, ale do tej pory nie spotkałem się > z sytuacją, kiedy nie dało się tego uporządkować, adaptery + MyParams. > Chodzi mi cały czas o pełną enkapsulację. Czasami uporządkowanie tego w proponowany przez Ciebie sposób może skończyć się gorzej niż uzycie wizytorów. Moim zdaniem większym bałaganem są setki(!) adapterów robionych tylko po to żeby zadośćuczynić fobii przed wizytacją która to rozwiązuje elegancko i mniejszym nakładem kodu. Obiektowośc za wszelką cenę nie ma sensu. Warto wyluzować i nie twierdzić autorytarnie że to burdel w każdym projekcie, czasami jest to jedyne rozsądne wyjście. Co nie znaczy że je preferuje. Tylko nieśmiało zaznaczam, że robienie boost::any z powodu wizytorów uważam za przegięcie w stronę karykatury OO. > Gdyby w kodzie był porządek to wizytator nie jest potrzebny. Niestety zdarza się że nakład środków aby był niepotrzebny jest ... duży. > Natomiast proces odwiedzania (przychodzenia w gości) jest bardzo > potrzebny z wielu społecznych i ekonomicznych względów. > [cut crap] > [1] [..] Najbardziej rozwala mnie w tym kodzie zdanie (jako wada): "because adding a new class in the "subject" hierarchy (for example, by introducing the PneumaticHammer class) involves the modification in the whole Visitor hierarchy" Jak widać autor piszący ten tekst nie widział nigdy wizytorów defaultowych jak również preferuje GPF w runtime niż compilation error w compiletime. No, każdy robi jak umie, a jak nie umie, to pisze na neta jakieś "Alternative approach" które sprowadzają C++ do gorszego bagna niż php. Cool. Może nie OO ale "będę pisał w Basicu a wizytacji nie użyje, bo nie !". |
|
#69
|
|
|
|
|
On 6 Lip, 13:02, "Piotr Wyderski" <wyder...@mothers.against.spam-
ii.uni.wroc.pl> wrote: > Skoro iteracja jest równoważna rekursji pod względem wyrażalności, Co to jest "wyrażalność"? 1. Kolejne nieproduktywne odniesienie do rownoważności Turinga, że i tak wszystko da się napisać we wszystkim. 2. Odniesienie do takich aspektów języka jak czytelność czy zgodność kodu z projektem *oraz* zgodność kodu źródłowego z wynikowym. Jeśli masz na myśli 1., to polecam hasło reklamowe Microsoftu (prawdziwe, dotyczące Office'a): "How much time do you want to waste today?" > a zdecydowana większośc znanych mi pętli to wariacje na temat for_each, > czyli funkcyjnego map Jest jeszcze taki drobiazg jak efekty uboczne i ich *kolejność*. Pętle to nie "funkcyjne mapy", chociaż zgadzam się, że to drugie ma fajniejszą nazwę. :-) > to dochodzę do wniosku, że należy pozbyć się > imperatywnych konstrukcji sterujących w rodzaju for lub while jako > pierwszoplanowych konstrukcji języka i zastąpić je lukrem syntaktycznym > transformującym te pętle do rekursji. A w kompilatorze to sobie > "odwiniemy" Tylko raz? Ja proponuję, żeby każdy stopień kompilatora zwijał a potem rozwijał. I żeby producenci kompilatorów podawali, ile razy to się odbywa, żeby użytkownicy mogli się snobować i opowiadać sobie na imprezach, ile razy zamienili siekierkę na kijek i z powrotem. Bo przecież tylko ciecie piszą pętle jako pętle. > Cóż, coraz bardziej "funkcyjnieję" na stare lata, co począć... ;-) Czy to "funkcyjnienie" jest zjawiskiem pozytywnym? Bo mi się jakoś nie udziela i nie wiem, czy mam się martwić. ;-) |
|
#70
|
|
|
|
|
On 6 Lip, 15:31, Sebastian Bialy <h> wrote:
> > [1][..] > > Najbardziej rozwala mnie w tym kodzie zdanie (jako wada): > > "because adding a new class in the "subject" hierarchy (for example, by > introducing the PneumaticHammer class) involves the modification in the > whole Visitor hierarchy" > > Jak widać autor piszący ten tekst nie widział nigdy wizytorów > defaultowych Jeśli "wizytory defaultowe" są poprawką do złego rozwiązania (czyli rozwiązaniem problemu, który nie powinien był w ogóle wystąpić), to widział. > jak również preferuje GPF w runtime niż compilation error w > compiletime Gzie autor to preferuje? Z którego fragmentu tekstu to wywnioskowałeś? Wydaje mi się, że autor raczej preferuje techniki compile-time. > No, każdy robi jak umie Tak. > Może nie OO ale "będę pisał w Basicu a wizytacji nie > użyje, bo nie !". Co ma wspólnego visitor z OO? Składnię i użycie konstrukcji na poziomie mikro? Jakiś czas temu, chyba na pl.comp.programming, ktoś przekonywał, że Java jest "bardziej obiektowa", bo ma funkcję sinus w klasie a nie luzem. Nie spotkał się ze zrozumieniem większości. To, że visitor używa klas na poziomie mikro-konstrukcji, nie znaczy jeszcze, że to jest OO. No i nie zapominajmy, że OO jest środkiem a nie celem. Visitor jest niestety efektem wyeksponowania środka na poziom celu. |
|
#71
|
|
|
|
|
On 6 Lip, 00:06, Sebastian Kaliszewski <susun>
wrote: > >> W normalnych językach nie ma headerów. > > > Prawdziwe jest stwierdzenie: > > Nie we wszystkich językach są headery. > > Z nieezoterycznych są w 3: C, C++, Objective-C Ada, PL/SQL (wersja Oracle), ... Wiele języków odróżnia specyfikację od implementacji na poziomie fizycznej struktury kodu. No chyba że pod pojęciem "header" rozumiesz mechanizm sklejania tekstu na poziomie preprocesora. |
|
#72
|
|
|
|
|
Maciej Sobczak wrote:
>>Jak widać autor piszący ten tekst nie widział nigdy wizytorów >>defaultowych > Jeśli "wizytory defaultowe" są poprawką do złego rozwiązania (czyli > rozwiązaniem problemu, który nie powinien był w ogóle wystąpić), to > widział. Więc jak widział, to by nie pisał, że dodanie nowego typu wymaga zmiany całej hierarchi, bo to bzdura. Wymaga wymiany miejsc, w których świadomie zainstalowałem pułapkę kompilacyjną na nowy typ. _Świadomie_. >>jak również preferuje GPF w runtime niż compilation error w >>compiletime > Gzie autor to preferuje? Z którego fragmentu tekstu to wywnioskowałeś? Z całości. Że Visitors jest be, a switch cool. > Wydaje mi się, że autor raczej preferuje techniki compile-time. I uważasz, że ten zestaw dynamic_castów/static_castów to jest technika compile-time ? W wizytacji nie ma takich makabrycznych sztuczek dostawania się do obiektów wizytowalnych. Nie sposób się pomylić. U Ciebie wystarczy głupia literówka podczas copy-paste i nie dowiesz się, tym bardziej, że static_cast naprawde potrafi zrobic ciekawe rzeczy. > Co ma wspólnego visitor z OO? Składnię i użycie konstrukcji na > poziomie mikro? Niewiele. Za to wiele z kontrolą typów na poziomie kompilacji. Dajecie dwie alternatywy: a) Wizytory (be, pfuj i w ogóle) b) wygibasy przez switch/static_cast albo jakieś pokraczne interfejsy z boost::any czy templateów. a) daje zysk w postaci bardzo utrudnionego popełnienia błedu za cenę jednego "accept". b) daje zysk w postaci random GPFów podczas runtime podczas popełniania błedu. To ja wybieram bramkę nr a). > To, że visitor używa klas na poziomie mikro-konstrukcji, nie znaczy > jeszcze, że to jest OO. Nie twierdziłem, że vistyory są OO. Ale nie róbmy sobie jaj, boost::any tym bardziej. Visytory to zło, ale konieczne w wielu sytuacjach, inaczej ugrzęźniesz w workaroundach które mają u podstaw nic poza visitorofobią. > No i nie zapominajmy, że OO jest środkiem a nie celem. Visitor jest > niestety efektem wyeksponowania środka na poziom celu. Więc pokaż mi lepszy sposób na uzyskanie podobnych efektów małym kosztem. Ale nie rób sobie jaj ze switch/static cast, proszę, taki kod nadaje sie w zasadzie do śmieci w dużym projekcie bo nie sposób na nim zapanować. |
|
#73
|
|
|
|
|
On 6 Lip, 18:56, Sebastian Bialy <h> wrote:
> >>Jak widać autor piszący ten tekst nie widział nigdy wizytorów > >>defaultowych > > Jeśli "wizytory defaultowe" są poprawką do złego rozwiązania (czyli > > rozwiązaniem problemu, który nie powinien był w ogóle wystąpić), to > > widział. > > Więc jak widział, to by nie pisał, że dodanie nowego typu wymaga zmiany > całej hierarchi, bo to bzdura. Wymaga w realizacji, która jest opisana w artykule i w tym kontekście nie jest bzdurą. Nieprzypadkiem ta realizacja jest też zgodna z tą, która jest opisana w GoF. > Wymaga wymiany miejsc, w których > świadomie zainstalowałem pułapkę kompilacyjną na nowy typ. _Świadomie_. Czyli tak samo, jak w switch. > >>jak również preferuje GPF w runtime niż compilation error w > >>compiletime > > Gzie autor to preferuje? Z którego fragmentu tekstu to wywnioskowałeś? > > Z całości. Że Visitors jest be, a switch cool. Czyli rzuciłeś okiem na kod a nie przeczytałeś tekstu. Co ma wspólnego switch z GPF w runtime? > > Wydaje mi się, że autor raczej preferuje techniki compile-time. > > I uważasz, że ten zestaw dynamic_castów/static_castów to jest technika > compile-time ? Sprawdzanie błędów jest w compile-time. > W wizytacji nie ma takich makabrycznych sztuczek > dostawania się do obiektów wizytowalnych. Są bardziej makabryczne, bo intruzywne. Zrób visitora na cudzej hierarchii. > U > Ciebie wystarczy głupia literówka podczas copy-paste i nie dowiesz się, > tym bardziej, że static_cast naprawde potrafi zrobic ciekawe rzeczy. Pokaż mi przykład takiej potencjalnej literówki. Możesz posłużyć się kodem z artykułu. > Dajecie dwie alternatywy: > > a) Wizytory (be, pfuj i w ogóle) > > b) wygibasy przez switch/static_cast albo jakieś pokraczne interfejsy z > boost::any czy templateów. > > a) daje zysk w postaci bardzo utrudnionego popełnienia błedu za cenę > jednego "accept". Pokaż mi jak płacisz tą cenę przy cudzej hierarchii. > b) daje zysk w postaci random GPFów podczas runtime Pokaż przykład błędu, który prowadzi do GPF. > Ale nie rób sobie jaj ze switch/static cast, proszę, taki kod > nadaje sie w zasadzie do śmieci w dużym projekcie bo nie sposób na nim > zapanować. Przeczytaj to: http://www.cs.virginia.edu/sigbed/ar..._Gasperoni.pdf Jeśli napiszesz kiedyś soft do sterowania samolotem, to jednym z warunków uzyskania certyfikatu bezpieczeństwa będzie... przepisanie visitorów na switch. Dalej myślisz, że robię sobie jaja? Natomiast jeśli już zaczęliśmy temat "dużych projektów", to tam hierarchie zwykle nie są przystosowane do wizytacji, bo się ich po prostu nie projektuje pod tym kątem - takie rzeczy da się przewidzieć w zasadzie tylko wtedy, gdy od początku widać całość projektu, czyli właśnie w projektach zabawkowych. Wbrew Twojej argumentacji, w "dużym projekcie" visitor odpada z powodu swojej intruzywności. |
|
#74
|
|
|
|
|
On Jul 6, 5:35 pm, Maciej Sobczak <seemyhomep> wrote:
> Wiele języków odróżnia specyfikację od implementacji na poziomie > fizycznej struktury kodu. Dla uzupełnienia - nie tylko języki, patrz CORBA i inne wynalazki z językami opisu interfejsów. |
|
#75
|
|
|
|
|
Maciej Sobczak wrote:
>>Wymaga wymiany miejsc, w których >>świadomie zainstalowałem pułapkę kompilacyjną na nowy typ. _Świadomie_. > Czyli tak samo, jak w switch. W jaki sposób w realizacji z użyciem switch kompilator wstrzyma kompilację po zauważeniu dodatkowego typu ? Bo w implementacji wizytorów zatrzyma się jeśli nie "wypełnię" jednej z abstrakcyjnych metod w wizytorze (jeśli dziedziczę po Visitor) albo się nie zatrzyma (jeśli dziedziczę po Defaulting). Możesz mi pokazać ten mechanizm w swoim switchu ? Powtarzam: dodanie nowego typu powoduje wysypanie się kompilacji. > Czyli rzuciłeś okiem na kod a nie przeczytałeś tekstu. > Co ma wspólnego switch z GPF w runtime? To, że o ewentualnym braku supportu dla jakiegoś typu dowiadujesz się w runtime. I jeśli ten fragment kodu i ten typ pojawiają się po 15 tygodniach od release u kolesia w Australii to masz _poważny_ problem. Bo nie wszystko da się przetestować w każdej sytuacji. >>>Wydaje mi się, że autor raczej preferuje techniki compile-time. >>I uważasz, że ten zestaw dynamic_castów/static_castów to jest technika >>compile-time ? > Sprawdzanie błędów jest w compile-time. Rotfl. case Hammer_tag: { Drill & h = static_cast<Drill &>(t); // do something with the hammer } break; I dupa. Teraz jeśli wydaje Ci się to niemożliwe wyobraź sobie dziesiątki takich miejsc w kodzie. Szanse na błąd są całkiem spore. I w Twojej implementacji dowiesz się o tym w runtime. W RUNTIME. Ja dowiem się w compiletime. > Są bardziej makabryczne, bo intruzywne. Zrób visitora na cudzej > hierarchii. Zauważ, że Seweryn stwierdził z całą stanowczością, że visytory to burdel. Po czym przedstawił jeszcze większy burdel żeby się ich pozbyć. Ja twierdze że visitory to zło, ale czasem warto ich użyć zamiast robić sobie jaja z castowaniem albo przerabianiem C++ na php. Natomiast nigdzie nie twierdziłem, że można/trzeba ich użyć w każdym projekcie. Bo nie. W sytuacji jaką opisujesz nie da się wprost i próba ich tam wsadzenia jest bez sensu, to sztuka dla sztuki. >>Ciebie wystarczy głupia literówka podczas copy-paste i nie dowiesz się, >>tym bardziej, że static_cast naprawde potrafi zrobic ciekawe rzeczy. > Pokaż mi przykład takiej potencjalnej literówki. Możesz posłużyć się > kodem z artykułu. Pare linijek wyżej masz przykład złego kastowania. Jeśli sobie wyobrazisz, że akurat ten kast trafia się żadko - to masz ~0 szans na wykrycie go podczas pisania kodu a nawet testowania z coverage. Bo się żadko trafia i już. Inny przykład: zapomnisz o jakimś typie a pechowo masz do napisania "Reset tool state". Zapomniałeś o pile i akurat jej stan się nie skasował. Co spowodowało UB w programie, co doprowadziło do strat finansowych u klienta. Ja nie mogę zapomnieć. Kod się nie skompiluje bez jawnego napisania implementacji dla piły (bo tak założyłem w tym konkretnym visitorze). > Pokaż mi jak płacisz tą cenę przy cudzej hierarchii. A co ma o tego cudza hierachia? Straciłeś argumentację merytoryczną? Jak projektuje własną hierarchję mogę sobie accept wprowadzić. Jak mam cudzą to mam problem ... chyba ze zastosuje technikę shadow hierarchii. Co zdarzało mi się czynić z różnych innych względów. Przecież nie zamierzam biegać po ulicy i wciskać ludziom visitory do ich cudzych intymnych hierarchii. Cała zabawa w tym, żeby nie stosować takich pokracznych rozwiązań z castowaniem tracąc kontrolę typów tylko dlatego że "nielubienie visitorów jest trendy". To że visitor nie sprawdza się w jakiś przypadkach nie przekreśla go we wszystkich. >>b) daje zysk w postaci random GPFów podczas runtime > Pokaż przykład błędu, który prowadzi do GPF. Powyżej. >>Ale nie rób sobie jaj ze switch/static cast, proszę, taki kod >>nadaje sie w zasadzie do śmieci w dużym projekcie bo nie sposób na nim >>zapanować. >> Przeczytaj to: > > [..] Ani śladu po wizytacji. Za to: (1) Initialization: how can we prove that dispatch tables and tag/vtable fields are initialized correctly? (2) Modification: how can we prove that dispatch table and tag/vtable values are not updated maliciously or unintentionally during the execution of a program? Te pytania świadczą o daleko posuniętej dbałości o przypadkowe uszkodzenie się pamięci czy błąd kompilatora. Przy takiej (słusznej) paranoii nic mnie nie zdziwiłoby. Tym bardziej że dalej w tekście sugerują że metody wirtualne są niepewne. No i kul, programy o wysokiej pewności działania pisze się inaczej. > Jeśli napiszesz kiedyś soft do sterowania samolotem, to jednym z > warunków uzyskania certyfikatu bezpieczeństwa będzie... przepisanie > visitorów na switch. > Dalej myślisz, że robię sobie jaja? Tak, dlaej myślę że sobie robisz jaja zamieniając mechanizm o wyższej kontroli typów na ręczne kastowanie które jest siedliskiem błędów twierdząc usilnie, że nie można się pomylić. > Natomiast jeśli już zaczęliśmy temat "dużych projektów", to tam > hierarchie zwykle nie są przystosowane do wizytacji, bo się ich po > prostu nie projektuje pod tym kątem - takie rzeczy da się przewidzieć > w zasadzie tylko wtedy, gdy od początku widać całość projektu, czyli > właśnie w projektach zabawkowych. Na szęście życie nie jest takie proste i czasami zamiast projektować życie na podstawie hierarchi projektuje się hierarchię na podstawie życia. Wtedy teoria może być ciężka w implementacji. > Wbrew Twojej argumentacji, w "dużym projekcie" visitor odpada z powodu > swojej intruzywności. Całe szczęście że odpada. Bo ja vizytacji nie lubie i unikam. Natmiast nie doszedłem jeszcze do etapu zamiany _pewnego_ mechanizmu kontroli typów na dziecinadę ze switch/cast albo boost::any. Wtedy wywaliłbym C++ za okno bo używanie go traci sens. |
|
|
|
|
| Podobne wątki | |
| Ciekawostka przyrodnicza Dziś zostałam uraczona chłodnikiem "litewskim" z... krewetkami, w zastępstwie raków, chyba. Hmmm... :/ |
|
| Ciekawostka przyrodnicza Regulamin Promocji "Rachunek dyskretny" # Usługa pozwala Abonentowi na rozszerzenie zakresu zachowania w poufności informacji o połączeniach wykonywanych z numeru... |
|
| ciekawostka przyrodnicza > NH4(+) = NH3(+) + H ze niby wodor atomowy powstaje?? dziwne... |
|
| ciekawostka przyrodnicza Jestem dumnym posiadaczem dosyć wiekowego ale do tej pory spisującego się bez zarzutów kompa. Mój zestaw to Plyta główna Acorp 6bx67 z chipsetem 440BX Procesor Celeron 333,... |
|
|
Czasy w strefie GMT. Teraz jest 23:18. | Privacy Policy
|