abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    včera 17:11 | Nová verze

    Byl vydán Nextcloud Hub 8. Představení novinek tohoto open source cloudového řešení také na YouTube. Vypíchnout lze Nextcloud AI Assistant 2.0.

    Ladislav Hagara | Komentářů: 10
    včera 13:33 | Nová verze

    Vyšlo Pharo 12.0, programovací jazyk a vývojové prostředí s řadou pokročilých vlastností. Krom tradiční nadílky oprav přináší nový systém správy ladících bodů, nový způsob definice tříd, prostor pro objekty, které nemusí procházet GC a mnoho dalšího.

    Pavel Křivánek | Komentářů: 9
    včera 04:55 | Zajímavý software

    Microsoft zveřejnil na GitHubu zdrojové kódy MS-DOSu 4.0 pod licencí MIT. Ve stejném repozitáři se nacházejí i před lety zveřejněné zdrojové k kódy MS-DOSu 1.25 a 2.0.

    Ladislav Hagara | Komentářů: 37
    25.4. 17:33 | Nová verze

    Canonical vydal (email, blog, YouTube) Ubuntu 24.04 LTS Noble Numbat. Přehled novinek v poznámkách k vydání a také příspěvcích na blogu: novinky v desktopu a novinky v bezpečnosti. Vydány byly také oficiální deriváty Edubuntu, Kubuntu, Lubuntu, Ubuntu Budgie, Ubuntu Cinnamon, Ubuntu Kylin, Ubuntu MATE, Ubuntu Studio, Ubuntu Unity a Xubuntu. Jedná se o 10. LTS verzi.

    Ladislav Hagara | Komentářů: 13
    25.4. 14:22 | Komunita

    Na YouTube je k dispozici videozáznam z včerejšího Czech Open Source Policy Forum 2024.

    Ladislav Hagara | Komentářů: 3
    25.4. 13:22 | Nová verze

    Fossil (Wikipedie) byl vydán ve verzi 2.24. Jedná se o distribuovaný systém správy verzí propojený se správou chyb, wiki stránek a blogů s integrovaným webovým rozhraním. Vše běží z jednoho jediného spustitelného souboru a uloženo je v SQLite databázi.

    Ladislav Hagara | Komentářů: 0
    25.4. 12:44 | Nová verze

    Byla vydána nová stabilní verze 6.7 webového prohlížeče Vivaldi (Wikipedie). Postavena je na Chromiu 124. Přehled novinek i s náhledy v příspěvku na blogu. Vypíchnout lze Spořič paměti (Memory Saver) automaticky hibernující karty, které nebyly nějakou dobu používány nebo vylepšené Odběry (Feed Reader).

    Ladislav Hagara | Komentářů: 0
    25.4. 04:55 | Nová verze

    OpenJS Foundation, oficiální projekt konsorcia Linux Foundation, oznámila vydání verze 22 otevřeného multiplatformního prostředí pro vývoj a běh síťových aplikací napsaných v JavaScriptu Node.js (Wikipedie). V říjnu se verze 22 stane novou aktivní LTS verzí. Podpora je plánována do dubna 2027.

    Ladislav Hagara | Komentářů: 0
    25.4. 04:22 | Nová verze

    Byla vydána verze 8.2 open source virtualizační platformy Proxmox VE (Proxmox Virtual Environment, Wikipedie) založené na Debianu. Přehled novinek v poznámkách k vydání a v informačním videu. Zdůrazněn je průvodce migrací hostů z VMware ESXi do Proxmoxu.

    Ladislav Hagara | Komentářů: 0
    25.4. 04:11 | Nová verze

    R (Wikipedie), programovací jazyk a prostředí určené pro statistickou analýzu dat a jejich grafické zobrazení, bylo vydáno ve verzi 4.4.0. Její kódové jméno je Puppy Cup.

    Ladislav Hagara | Komentářů: 0
    KDE Plasma 6
     (74%)
     (8%)
     (2%)
     (16%)
    Celkem 825 hlasů
     Komentářů: 4, poslední 6.4. 15:51
    Rozcestník

    Python, C a CFFI

    6.2.2021 00:36 | Přečteno: 3654× | Linux | Výběrový blog | poslední úprava: 6.2.2021 01:06

    Rád programuji v Pythonu, protože je to dostatečně jednoduché a současně na rozdíl od např. C nemusím řešit spoustu detailů. Bohužel problémem je nízký výkon oproti nativnímu kódu. Dále je občas nutné volat funkce z cizí knihovny, která poskytuje jen Cčkové API.

    Operace s velkými poli, které by byly nepoužitelně pomalé kdyby se dělaly přímo v Pythonu po prvcích, většinou vyřeší numpy, ale ne vždy se dají požadované operace snadno vyjádřit pomocí vektorových numpy funkcí, nebo je to neefektivní (např. je potřeba provést více operací nad jedním velkým polem a v numpy to nejde zfúzovat a tak se pole zbytečně vícekrát čte z paměti a kopíruje). Existují na to různé další opravy typu „napsat to tak aby to zvládlo přeložit pypy/rpython/numba“ - různé přístupy viz tento dotaz v poradně - ale mně přijde nejjednodušší tu „vnitřní smyčku“ napsat v C. Další důvod, proč je potřeba psát a z Pythonu volat Cčkové funkce, je lowlevel interakce s Cčkovými knihovnami a hardwarem - v mém konkrétním případě librtlsdr, kterou jsem potřeboval hodně lowlevel používat když jsem z rtl-sdr dělal Tamaru, a libbladeRF, kterou na radar používám teď (a k ní výrobce dodává pythoní bindingy udělané přesně tak jak popíšu v tomto zápisku).

    CFFI

    Předpokládejme, že máme Cčkový zdroják a hlavičkový soubor:

    # hello.h
    int hello(int number);
    # hello.c
    #include <stdio.h>
    int hello(int number) {
      printf("hello, and my number is %i\n", number);
      return number * number;
    }
    

    Z programu uděláme normální sdílenou knihovnu:

    $ gcc -fPIC -c hello.c -o hello.o
    $ gcc -shared hello.o -o hello.so
    

    a tu pak použijeme takto:

    import cffi
    ffi = cffi.FFI()
    
    # načteme definice funkcí - aby CFFI vědělo, jaké argumenty předávat a jakou návratovou hodnotu vyzvednout
    ffi.cdef(''.join(open("hello.h").readlines()))
    
    # nahrajeme naši knihovnu
    util = ffi.dlopen("./hello.so")
    
    # spustíme
    ret = util.hello(123)
    print("function returned: %i"%ret)
    
    hello, and my number is 123
    function returned: 15129
    

    Makefile

    Tady je na to Makefile který zhruba používám. Postupně jsem nasbíral spoustu warningů které stojí za to v gcc zapnout…

    CC=gcc
    
    CFLAGS=\
    -fno-common \
    -fno-omit-frame-pointer \
    -std=gnu11 \
    -Wall \
    -Wextra \
    -Wduplicated-cond \
    -Wduplicated-branches \
    -Wlogical-op \
    -Wrestrict \
    -Wnull-dereference \
    -Wjump-misses-init \
    -Wdouble-promotion \
    -Wshadow \
    -Wformat=2 \
    -pedantic
    
    ifeq ($(DEBUG),1)
    CFLAGS+=-Og -g -fsanitize=address
    else
    CFLAGS+=-O3
    endif
    
    .PHONY: clean
    
    all: hello.so
    
    clean:
    	rm -f *.so *.o
    
    %.so: %.o
    	$(CC) -shared $< -o $@
    
    %.o: %.c %.h
    	$(CC) -fPIC $(CFLAGS) -c $< -o $@
    
    

    Vlákna

    Volání funkce uvolňuje pythoní GIL, takže váš program normálně běží dál. A klidně můžete volat funkce z víc threadů:

    int hello2(int number) {
      for(int i = 0; i<2*1000*1000*1000; i++) {
        if(i%(500*1000*1000) == 0) {
          printf("hello, my number is %i and iteration is %i\n", number, i);
        }
      }
      return number * number;
    }
    
    import threading
    
    for i in range(4):
      threading.Thread(target=util.hello2, args=(i,)).start()
    
    hello, my number is 0 and iteration is 0
    hello, my number is 1 and iteration is 0
    hello, my number is 2 and iteration is 0
    hello, my number is 3 and iteration is 0
    hello, my number is 0 and iteration is 500000000
    hello, my number is 1 and iteration is 500000000
    hello, my number is 3 and iteration is 500000000
    hello, my number is 2 and iteration is 500000000
    hello, my number is 0 and iteration is 1000000000
    hello, my number is 3 and iteration is 1000000000
    hello, my number is 1 and iteration is 1000000000
    hello, my number is 2 and iteration is 1000000000
    hello, my number is 3 and iteration is 1500000000
    hello, my number is 0 and iteration is 1500000000
    hello, my number is 1 and iteration is 1500000000
    hello, my number is 2 and iteration is 1500000000
    

    Můžete tak používat například pythoní synchronizovanou frontu pro zpracovávání požadavků (producer-consumer) a nemusíte řešit pthreads a věci kolem.

    Pole dovnitř

    Asi hlavní věc, proč to celé děláme, je, že chceme strkat numpy pole tam a zpátky. Tomu se musí trošku pomoct a musí se tomu ručně vrazit správně přetypovaný pointer. Předstírejme třeba, že v numpy není funkce počítající 1/x, a potřebujeme ji na single precision floatech.

    void reciprocal(float * input, float * output, size_t len) {
      for(size_t i = 0; i<len; i++) {
        output[i] = 1/input[i];
      }
    }
    
    import numpy as np
    
    data_in = np.array(np.random.normal(size=20), dtype=np.float32)
    data_out = np.empty_like(data_in)
    
    util.reciprocal(ffi.cast("float *", data_in.ctypes.data), ffi.cast("float *", data_out.ctypes.data), len(data_in))
    print("input: %s"%data_in)
    print("output: %s"%data_out)
    print("allclose: %s"%np.allclose(data_out, np.reciprocal(data_in)))
    
    input: [-0.6700668   0.7850408  -1.3823526   1.5933608  -0.18592156  0.7123875 ... ]
    output: [-1.4923886  1.2738192  -0.72340447  0.62760425 -5.378612    1.4037304 ... ]
    allclose: True
    

    Pole ven

    Výsledek můžeme také alokovat uvnitř Cčkové funkce a vracet ho ven do Pythonu. Těžko říct, jestli je to moudré - někdy by se měl uvolnit, ale to by se asi mělo koordinovat s destrukcí toho numpy pole, co se z toho vytvořilo.

    void alloc(float ** output, size_t * output_len) {
      size_t len = 10;
      float * buf = malloc(len * sizeof(float));
      for(size_t i = 0; i<len; i++) {
        buf[i] = i;
      }
      *output = buf;
      *output_len = len;
    }
    
    arr_p = ffi.new("float **")
    l_p = ffi.new("size_t *")
    
    util.alloc(arr_p, l_p)
    
    dt = np.dtype(np.float32)
    l = l_p[0]
    print("received %i floats"%l)
    arr = np.frombuffer(ffi.buffer(arr_p[0], l*dt.itemsize), dtype=np.float32)
    print("result: %s"%arr)
    
    received 10 floats
    result: [0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
    

    Soubory, mmap

    Do CFFI funkcí můžete strkat třeba i file deskriptory (soubor.fileno()), jenom je předtím v Pythonu flushněte ať se vám nepomíchají buffery. Samozřejmě to můžou být i filedeskriptory běžících příkazů získané pomocí subprocess.Popen, takže se nemusíte forkovat v Cčku, což je vždycky opruz.

    Pointer, co strkáte do funkce, může být klidně získaný pomocí np.memmap, což uděláte na jeden řádek a nemusíte řešit takový ten standardní céčkový horor se získáváním velikosti souboru a mapováním.

    data = np.memmap(soubor, dtype=np.uint8, mode="r")
    util.cat(ffi.cast("uint8_t *", data.ctypes.data), len(data))
    

    Satanizér

    V Makefile výše jste si možná všimli, že se pomocí make DEBUG=1 dá zapnout sanitizér. O tom budu víc psát v jiném zápisku, každopádně ve zkratce hlídá, jestli neděláte takové ty špatné věci jako čtení a zápis mimo alokovanou paměť. Například následující kód sám o sobě nespadne (což je samozřejmě undefined behavior závislé na konkrétním překladu a na tom, že heap zrovna nekončí v 16 bajtech za „legálním“ obsahem pole):

    void crash() {
      int * buf = malloc(4 * sizeof(int));
      for(int i = 0; i<8; i++) {
        printf("read %i: %X\n", i, buf[i]);
      }
    }
    
    read 0: 7F2BAC60
    read 1: 7FEB
    read 2: 7F2BAC60
    read 3: 7FEB
    read 4: 29302E33
    read 5: 3E3E3E0A
    read 6: 71
    read 7: 0
    

    Chyba tak může zůstat dlouho neodhalena, až ji nějaký útočník využije pro čtení mimo povolený rozsah. Když to ale zkompilujeme a spustíme s asanem, program poslušně spadne:

    $ make DEBUG=1
    $ ASAN_OPTIONS=detect_leaks=0 LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/10/libasan.so ./hello6.py 
    read 0: BEBEBEBE
    read 1: BEBEBEBE
    read 2: BEBEBEBE
    read 3: BEBEBEBE
    =================================================================
    ==2285214==ERROR: AddressSanitizer: heap-buffer-overflow
        #0 in crash /home/jenda/tmp/cffi/hello.c:43
    

    Trochu mrzuté jsou dvě věci:

    ASAN zpomaluje běh programu, protože přidává tyto kontroly. Podle konkrétního programu je zpomalení 10-300%. Dále alokuje spoustu paměti navíc (bezpečnostní zóny + metadata). Proto se typicky používá při testování a ne pak v produkci.

    Kompilace pro OpenWRT

    Takto vytvořený software potřebuju spouštět na OpenWRT, a to ještě k tomu na MIPSu a jako libc používají musl, takže se jednoznačně musí crosskompilovat. Jak to s tímhle udělat?

           

    Hodnocení: 100 %

            špatnédobré        

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    6.2.2021 01:15 _
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Mě přijde lepší použít C++ a pybind11. Nativní kód nepotřebuje většinou nic navíc, jen šablonu, co zaregistruje požadované funkce/třídy do pythonu a je hotovo. Všechno funguje oboustraně a bez zbytečného kódu jak na straně pythonu tak v C++. C interface v blogu se hodí jen na hodně jednoduché věci, dřív nebo později narazíš na problém se složitějšími datovými strukturami a je to prakticky stejně složité jako C API (pokud teda umíš C++).
    6.2.2021 08:04 Radovan
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Bohužel problémem je nízký výkon oproti nativnímu kódu
    Rouhání, aneb něco co bastlič pythonista nikdy nepřizná.
    6.2.2021 11:46 dumblob | skóre: 10 | blog: dumblog
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Dneska už bych pomalu pro takto popsané případy užití asi sáhnul po V. Po překousnutí syntaxe, je to způsobem přemýšlení docela blízko Pythonu (při tomto "přirovnání" vědomě pomíjím některá PEP doporučující spoustu neefektivností pro zlepšení čitelnosti Pythonu).

    Jendo, dej kdyžtak vědět, pokud zkusíš V, jaké z toho máš pocity (jo, je to stále alfa verze se vším všudy, ale ty benefity prostě už začínám vnímat).
    6.2.2021 12:14 Martin Mareš
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Nejsem Jenda, ale přeci jen se o pár dojmů podělím.

    To vypadá na další pokus jak spasit svět tím, že zakážeme všechny ty věci, ve kterých občas programátoři dělají chyby. Co na tom, že spoustu užitečných konstrukcí je najednou nutné obcházet či zapisovat kostrbatě, čímž klesá čitelnost kódu a zákonitě vznikají úplně nové chyby.

    Mít proměnné apod. defaultně read-only je zajímavý nápad, ale u svatýho Tučňáka, to jste opravdu nemohli vymyslet lepší syntaxi pro read-write než přidávat klíčové slovo mut? To je zoufale neergonomické.

    Zrušit globální proměnné je radikální... Takže když si chci při ladění přidat počítadlo, kolikrát mi někdo zavolal funkci, tak mám smůlu? To kvůli tomu musím předělat rozhraní, abych si stav předal? To opravdu nebylo míněné jako vtip???

    Nahrazení výjimek povinným kontrolováním chyb při volání každé funkce, která by mohla selhat, je zajímavý pokus. Ale uvědomil si autor, že většina chyb, která mohou nastat, jsou takové, se kterými v daném kontextu nelze nic rozumného udělat? Typicky třeba čtení ze souboru: ano, disk mi může shořet, takže technicky vzato čtení může selhat. Jenže pokud se stane tohle, stejně je většinou jediná rozumná reakce pokusit se chybu zalogovat a okamžitě ukončit celý program. Čili přesně to, co mi výjimky zařídí samy. Není potřeba na bambilion míst dopisovat explicitní kontrolu.

    Takže sečteno a podtrženo: rozhodně to není jazyk, ve kterém by mě lákalo programovat.
    6.2.2021 12:39 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    To vypadá na další pokus jak spasit svět tím, že zakážeme všechny ty věci, ve kterých občas programátoři dělají chyby.
    Předpokládám, že to je narážka na Rust :-D ...
    Ale uvědomil si autor, že většina chyb, která mohou nastat, jsou takové, se kterými v daném kontextu nelze nic rozumného udělat?
    ... Rust tohle řeší panickingem, což vevnitř funguje stejně jako výjimky, ale nevyužívá se to pro ošetřování běžných chyb, pouze pro "katastrofické" chyby, se kterými nejde nic dělat.

    Což je celkem elegantní řešení, protože stále máš tu možnost "katastroficky selhat", ale přitom výjimky jinak do jazyka nezasahují a nezpůsobují ty miliony problémů jako v C++, kde snad polovina C++ standardu je jen řešení nepříjemností s výjimkami...

    Jinak ale tohle není žádný novátorský experiment, to je prostě převzaté z funkcionálních jazyků (ML rodina), které to takhle mají už drahně let a funguje to...
    Takže sečteno a podtrženo: rozhodně to není jazyk, ve kterém by mě lákalo programovat.
    Souhlasim, ale z jiného důvodu: Nedodělaný a nepromyšlený memory management. Na stránkách píší malým písmem, že:
    Note: right now autofree is hidden behind the -autofree flag. It will be enabled by default in V 0.3.
    Takže pokud tomu dobře rozumim, aktuálně by default je dynamicky naalokovaná paměť prostě leaknuta. A na autofree enginu se pracuje. Je to takhle zřejmě už roky, vzpomínám si, když jsem se na V díval před lety, bylo to to samý a je to to samý stále. A je to zabugovaný.

    Nevim přesně, jak ten jejich autofree engine má fungovat, na stránkách k tomu není vůbec žádný popis, ale IMO se pokoušejí o něco jako Rust, aniž by ale k tomu měli tu formalizaci, typový systém a ucelený design jako má Rust. Z mého amatérského odhadu to bez podobné formalizace a za spolupráce typového systému dotáhnout není možné (bez GC).

    Ten jejich přístup mi přijde silně neseriózní, tj. že prezentují všechny skvělé featury jazyka včetně high-level věcí jako built-in web framework & ORM, ale přitom nemají dořešenou tak základní věc jako je dynamická alokace.

    Byť V jinak vypadá dobře, dokud nepřijdou s hmatatelným, dobře dokumentovaným/komunikovaým a fungujícím řešením memory managementu, rozhodně bych v tom nic nepsal.
    6.2.2021 13:10 Martin Mareš
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Předpokládám, že to je narážka na Rust :-D ...
    Kdyby jenom :-) Je to narážka na dlouhou tradici, která se táhne minimálně k Adě a Java do ní také docela zapadá. The Hacker's Dictionary pro to uvádí hezký termín "bondage-and-discipline language" :)
    ... Rust tohle řeší panickingem, což vevnitř funguje stejně jako výjimky, ale nevyužívá se to pro ošetřování běžných chyb, pouze pro "katastrofické" chyby, se kterými nejde nic dělat.
    Problém vidím v tom, že pro každého jsou katastrofické chyby něco jiného. Pokud píši běžnou aplikaci, chyba při čtení z disku je katastroficka. Pokud píši databázový systém, chci takové věci sakramentsky pečlivě ošetřovat, aby se nadále dalo dostat k datům, která nejsou chybou přímo postižena.
    Jinak ale tohle není žádný novátorský experiment, to je prostě převzaté z funkcionálních jazyků (ML rodina), které to takhle mají už drahně let a funguje to...
    Pro jistou hodnotu toho "funguje" souhlasím. Jenže ono to platí zejména díky tomu, že se v takových jazycích určité druhy programů prostě nepíší :)
    6.2.2021 13:49 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Pro jistou hodnotu toho "funguje" souhlasím. Jenže ono to platí zejména díky tomu, že se v takových jazycích určité druhy programů prostě nepíší :)
    Ono to funguje i v opacnem smeru. V tech uzasnych jazycich, kde je mozne delat opravdu cokoliv, se taky urcite druhy programu proste nepisi. Webovou aplikaci napsanou v C jsem videl naposledy v devadesatych letech.
    Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
    6.2.2021 14:55 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Problém vidím v tom, že pro každého jsou katastrofické chyby něco jiného. Pokud píši běžnou aplikaci, chyba při čtení z disku je katastroficka.
    Na chybě čtení z disku mi nic katastrofického nepřijde a to ani v triviálním programu, v takové situaci mi panikování nebo nedej bože výjimky přijdou jako kanón na vrabce, stačí návratové hodnoty (příklad v Rustu).
    Pro jistou hodnotu toho "funguje" souhlasím. Jenže ono to platí zejména díky tomu, že se v takových jazycích určité druhy programů prostě nepíší :)
    To asi záleží o jakém jazyku konkrétně se budem bavit, ale moc nevim, co tím myslíš. Java má diametrálně jiné zaměření než Rust. Adu moc neznám.
    Josef Kufner avatar 6.2.2021 15:14 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Tak zrovna u čtení z disku jsou výjimky docela fajn, neboť se tam toho může podělat neskutečně mnoho a hlídání všech návratových hodnot je otrava. To pak každá funkce je obalená do if a celé je to blé a fuj. Když to hází výjimky, tak okolo dáš jeden try-catch a máš klid.
    Hello world ! Segmentation fault (core dumped)
    6.2.2021 20:14 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Tak zrovna u čtení z disku jsou výjimky docela fajn, neboť se tam toho může podělat neskutečně mnoho a hlídání všech návratových hodnot je otrava.
    No ani ne. Viz ten příklad výše. Stačí mi standardní knihovnou předpřipravený typ io::Error, resp. io::Result, který ty otravný možnosti obsahuje. Obalení do if netřeba, od toho je ten operátor ? , který v podstatě dělá to samé co ten if (resp. dělá to pattern match), takže je to principielně stále jenom jednoduchá operace nad návratovou hodnotou, není pod tim žádná šílená a těžko předvídatelná magie jako u výjimek, ale přitom to není výřečné (v zásadě výřečnost IMO <= v porovnání s výjimkama).
    6.2.2021 21:19 Martin Mareš
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Pořád mi přijde velmi neergonomické muset se o to explicitně starat. Pořád je to o znak víc u každeho volání funkce, než byste měl s výjimkami.

    Výjimky nemusí být magické, ne každý jazyk je C++ :)
    7.2.2021 00:24 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Pořád mi přijde velmi neergonomické muset se o to explicitně starat. Pořád je to o znak víc u každeho volání funkce, než byste měl s výjimkami.
    No, tak to už je o tom, jaký člověk preferuje přístup... Osobně mi tohle řešení přijde ve výsledku ergonomičtější, než muset řešit výjimky a jejich problémy, ale jinak ano, třeba ten Rust je celkem hodně explicitní jazyk a chápu, že někomu to nevyhovuje...
    Výjimky nemusí být magické, ne každý jazyk je C++ :)
    Máš na mysli něco konkrétního? Mně přijdou výjimky +- ok ve vysokoúrovňových / dynamicky typovaných jazycích. Nicméně čím statičtější typy a nížší úroveň, tím víc, mi přijde, výjimky interferují se zbytkem jazyka... Ale možná to mají někde vyřešeno nějak hezky...
    7.2.2021 01:04 plostenka | blog: plstnk
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Výjimky nemusí být magické, ne každý jazyk je C++ :)
    Máš na mysli něco konkrétního? Mně přijdou výjimky +- ok ve vysokoúrovňových / dynamicky typovaných jazycích. Nicméně čím statičtější typy a nížší úroveň, tím víc, mi přijde, výjimky interferují se zbytkem jazyka... Ale možná to mají někde vyřešeno nějak hezky...
    Treba v assembleru pro OS/360 (a navazujici z/Arch) se vyjimky (jako zminovany IO error, invalid pointer, zapis na NULL,...) resi jednoduse pomoci ESTAE. Na zacatku programu (teda muze byt kdekoliv) je specialni instrukce, ktera rekne jadru "pri preruseni X predej rizeni na adresu Y". No a na adrese Y si pak muzu vyjimku nejak osetrit, treba revertem ruznych zmen, nebo jakkoliv jinak (dostanu registry v puvodnim stavu a podle PSW vim, kam se pripadne vratit a pokracovat v programu). Po zaregistrovani ESTAE rutiny uz se o to nemusim nikde dal starat, zadne zvlastni ify, try-catch-finally a podobne zpomalujici kontroly vsude mozne.
    7.2.2021 11:32 Martin Mareš
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Ono staticky typovaných nízkoúrovňových jazyků v posledních desetiletích moc nevzniklo, tak těžko srovnávat :-)

    Ale měl jsem na mysli výjimky v Pythonu nebo v Raku (Perl 6). Obojí mi přijde víceméně bezproblémové a nevidím důvod, proč by nemohly fungovat podobně i v nižším jazyku.

    V nízkoúrovňových jazycích se dají použít i jiné přístupy, kdysi jsem experimentoval s transakcemi v Céčku. Je to docela pohodlné, ale znamená to, že všechny knihovny, které používám, musí o transakcích vědět.
    Josef Kufner avatar 7.2.2021 14:41 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Otazníček v Rustu a jeho typový systém je z pohledu programátora–uživatele docela dost podobný výjimkám. V případě nízkoúrovňových jazyků je to docela rozumný přístup, který kombinuje jednoduchost návratových hodnot a pohodlnost výjimek. Je to ale pořád hodně explicitní a komplikuje to propagaci výjimek/chyb skrz několik úrovní kódu. V případě nekritického kódu je velmi pohodlné, když můžu nechat výjimky neošetřené a odchytit je až na svrchních vrstvách aplikace. Pak chyby není potřeba prakticky vůbec řešit a přesto se to bude chovat slušně a padat kultivovaně v omezeném kontextu.
    Hello world ! Segmentation fault (core dumped)
    xkucf03 avatar 7.2.2021 15:13 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Výhoda výjimek
    Je to ale pořád hodně explicitní a komplikuje to propagaci výjimek/chyb skrz několik úrovní kódu. V případě nekritického kódu je velmi pohodlné, když můžu nechat výjimky neošetřené a odchytit je až na svrchních vrstvách aplikace. Pak chyby není potřeba prakticky vůbec řešit a přesto se to bude chovat slušně a padat kultivovaně v omezeném kontextu.

    Přesně tak. Tohle považuji za zásadní výhodu výjimek, kterou žádné jiné řešení nedokázalo nahradit (ačkoli se samo prezentuje jako „lepší“ alternativa k výjimkám).

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    7.2.2021 20:44 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Je to ale pořád hodně explicitní a komplikuje to propagaci výjimek/chyb skrz několik úrovní kódu. V případě nekritického kódu je velmi pohodlné, když můžu nechat výjimky neošetřené a odchytit je až na svrchních vrstvách aplikace. Pak chyby není potřeba prakticky vůbec řešit a přesto se to bude chovat slušně a padat kultivovaně v omezeném kontextu.
    IMO zase záleží na kontextu. V kontextu nějakého high-level a hlavně dynamického jazyka, budiž, proč ne.

    V kontextu třeba C++ mi přijde, že veškeré výhody výjimek jsou draze vykoupeny nutností si všude dávat pozor na exception safety atd., přecijen, je to jazyk, kde nemáš GC a může se za přítomnosti výjimek snadno stát, že někde leakne alokace nebo bude objekt v nějakém polo-inicializovaném stavu apod.

    V kontextu Rustu mam pochybnost, jestli by vůbec bylo možné ten jazyk navrhnout s výjimkami tak, aby mohl posyktovat ty záruky, které poskytuje teď. Myslim si, že spíš ne, případně se značnými obtížemi.

    Ono tohle přetejká i do vysokoúrovňových jazyků. Vezmi v úvahu třeba situaci, kdy vyletí výjimka např. při zamčeném mutexu nebo něco podobného, to se pak musí specielně řešit, např. přes finally, případně je tohle důvod, proč i jazyky jako Java a Python přidali podporu RAII (v Pythonu with, v Javě try-with-resources), má svoji specielní (IMO divnou) syntaxi a je k tomu potřeba specielní podpora ze strany těch objektů, v Javě AutoClosable/Closable, v Pythonu __enter__() a __exit__() ... A ve výsledku ten původně krásně čistý návrh se komplikuje, vyžaduje specielní jazykové featury na v zásadě rutinní činnost a flow control divoce skáče mezi "bussiness" kódem a všelijakými catch a finally bloky na různých úrovních...

    Stojí tohle celé za kousek pohodlí, kdy člověk nemusí specifikovat návratové error typy a používat otazníčky? To mi vůbec nepřijde jasné, někomu možná jo a možná mu přijdou try-catch-finally bloky v pohodě a ergonomické. Mně osobně určitě ne, to si radší napíšu ten Result a pár otazníčků, vim pak aspoň, co od toho kódu můžu očekávat (a můžu používat funkcionální přístup apod.)...
    xkucf03 avatar 7.2.2021 21:50 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Výjimky, RAII, byznys procesy, úroveň abstrakce
    A ve výsledku ten původně krásně čistý návrh se komplikuje, vyžaduje specielní jazykové featury

    Nevím, jak se to komplikuje a jak je to ošklivé v Pythonu, ale Java má od verze 7 (2011) v podstatě normální RAII. Jediná nepěkná věc oproti třeba C++ je na tom to, že ti přibývají úrovně zanoření a explicitně v kódu vidíš {…} místo toho, aby si to jen ošéfoval kompilátor podle pořadí vzniku těch objektů – to je prostě daň za to, že ten jazyk staví primárně na GC a nikoli primárně na RAII.

    na v zásadě rutinní činnost a flow control divoce skáče mezi "bussiness" kódem a všelijakými catch a finally bloky na různých úrovních...

    Nic by „divoce skákat“ nemělo. Jak už tu správně poznamenal deda.jabko, výjimky jsou součást kontraktu a měly by odrážet úroveň abstrakce dané metody/třídy. Pokud ti např. selže metoda založOsobu(), tak by měla vyhodit něco jako ChybaZakládáníOsoby nebo ChybaPersonálníhoSystému a ne SQLException (to je jen technický detail, který tě většinou nezajímá). To, že se osobu nepodařilo založit, je byznysový problém a ten byznys proces navržený analytikem by s touto možností měl počítat a nějak na ni reagovat (např. odložit požadavek pro pozdější zpracování nebo zobrazit nějaké detaily, aby šlo zadání opravit a zkusit to znovu).

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    7.2.2021 23:25 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Jak už tu správně poznamenal deda.jabko, výjimky jsou součást kontraktu a měly by odrážet úroveň abstrakce dané metody/třídy.
    Cože? Vždyť je to přesně naopak :-) Hodnotové typy jsou součástí kontraktu, výjimky obecně nikoli.

    Specielní případ jsou checked exceptions v Javě, ale ty IMO nejsou dobrým základem pro argument. Zaprvé, checked exceptions nespecifikují kontrakt úplně, v podstatě bys musel uděla audit celýho kódu pod voláním nějaké funkce (včetně dependencí), abys zjistil, jestli se tam někde nevyhazují byznys chyby jako RuntimeException.

    Zadruhé, checked exceptions jsou AFAIK kontroverzní i mezi javisty a dá se pochybovat, jestli to vůbec jsou výjimky. Minimálně je to velmi specielní varianta výjimek, ze které se moc nedají posuzovat výjimky obecně. Viz tento článek, vypůjčím si citaci:
    The thing about checked exceptions is that they are not really exceptions by the usual understanding of the concept. Instead, they are API alternative return values.
    Tj. v podstatě to je emulace toho konceptu hodnotových error typů nad implementací výjimek.
    8.2.2021 00:16 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Jak už tu správně poznamenal deda.jabko, výjimky jsou součást kontraktu

    Vždyť je to přesně naopak :-) Hodnotové typy jsou součástí kontraktu, výjimky obecně nikoli.
    Deda.jabko tu psal cituji: checked vyjimky pak jsou soucasti kontraktu

    Priste prosim mlatit jineho slameneho panaka.
    bys musel uděla audit celýho kódu pod voláním nějaké funkce (včetně dependencí), abys zjistil, jestli se tam někde nevyhazují byznys chyby jako RuntimeException.
    RuntimeException jsou urceny pro kriticke chyby, pokud to nekdo pouziva jinak, je to chyba. Podobne jako kdyz nekdo zneuziva napriklad navratovou hodnotu typu int, kdy napriklad vysledek spada do intervalu 0..INT_MAX a chyba je -1.

    Neni to dobre, vede to k necekanym chybam, snadno to clovek prehledne, ale lidi to proste delaji, protoze jim to v dany okamzik prijde jako dobry napad a nikdo jim v tom nezabrani.
    The thing about checked exceptions is that they are not really exceptions by the usual understanding of the concept. Instead, they are API alternative return values.
    Ten argument, je takovy pochybny:
    The whole idea of exceptions is that an error thrown somewhere way down the call chain can bubble up and be handled by code somewhere further up, without the intervening code having to worry about it
    Jednak ta premisa mi prijde zvolena ponekud arbitrarne, za druhe checked exceptions tu nejsou kvuli kodu jako takovemu, ale kvuli programatorovi, aby vedel, ze metoda muze selhat. Checked vyjimky jsem se naucil mit rad, kdyz mi pri obhajobe jednoho projektu v C# spadl natvrdo program, protoze jsem neosetril zapis na disk, ktery zrovna byl v rezimu read-only nebo neco takoveho. Vec, kterou jsem proste prehledl, ... pricemz normalne v Jave bych to odchytil a oznamil chybu.

    Za treti, vyjimky predstavuji reseni chybovych stavu na urovni rizeni behu programu, muzes to chapat jako uzitecnou podmnozinu nelokalnich skoku. V tomto smeru je to chytrejsi bratricek konstrukci typu ON ERROR GOTO/GOSUB, ktere mely starsi programovaci jazyky (a nekdo tu vzpominal i najeke OS/360 nebo co). Proto to opravdu nevidim jako dalsi navratovou hodnotu.

    Hodnotove typy na druhou stranu predstavuji reseni chybovych stavu na urovni toku dat.

    Co z toho je spravne(jsi) je otazka filozofickeho pohledu. Bud se divas na program jako na sekvenci operaci, v takovem pripade osetreni chybovych stavu pomoci skoku dava smysl. Nebo program chapes jako postupnou transformaci vstupnich dat, v takovem pripade dava smysl pracovat s chybami jako navratovymi hodnotami.
    Tj. v podstatě to je emulace toho konceptu hodnotových error typů nad implementací výjimek.
    Kdyz si k tomu pridas kombinaci try-catch-finally, uz to chce notnou davku fantazie, aby to v tom clovek videl.
    Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
    8.2.2021 00:59 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Deda.jabko tu psal cituji: checked vyjimky pak jsou soucasti kontraktu. Priste prosim mlatit jineho slameneho panaka.
    Já jsem ten tvůj komentář popravdě zatím nečetl, reagoval jsem na výrok "výjimky jsou součást kontraktu" ...
    Co z toho je spravne(jsi) je otazka filozofickeho pohledu.
    Ano, s tím v obecný rovině určitě souhlasim a je pravda, že hodnotový typy s chybami komplikují data (jejich strukturu). Výjimku dělám jen v případě použití jako C++, Rust apod., kde komplikovat flow control mi přijde výrazně horší než komplikovat data. Nemůžu vyloučit, že by to třeba někdo uměl udělat tak, aby ty výjimky do toho zapadly dobře, ale zatím jsem to neviděl...
    Kdyz si k tomu pridas kombinaci try-catch-finally, uz to chce notnou davku fantazie, aby to v tom clovek videl.
    Abych se přiznal, tomu nerozumim. V čem vidíš přínos checked exceptions oproti hodnotám? Když už člověk stejně musí správně otypovat každou funkci po cestě - což představuje IMO většinu té režie s jedním i druhým způsobem -, proč vůbec ten mechanismus výjimek používat?
    8.2.2021 01:01 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    s/flow control/control flow/
    8.2.2021 01:42 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Jeste, ze jsi mi usetril praci.
    proč vůbec ten mechanismus výjimek používat?
    je pravda, že hodnotový typy s chybami komplikují data (jejich strukturu)
    Dodam jeste, ze historicky obalovat hodnoty tak, aby obsahovaly jeste indikator chyby, bylo neco nemyslitelneho kvuli vysoke rezii.
    Abych se přiznal, tomu nerozumim
    Citovals tady:
    The thing about checked exceptions is that they are not really exceptions by the usual understanding of the concept. Instead, they are API alternative return values.
    Tj. v podstatě to je emulace toho konceptu hodnotových error typů nad implementací výjimek.
    Takze jeste jednou. V situaci, kdy nauvazujes jenom try-catch, ale mas tam i finally, uz musis provadet hodne velkou ekvilibristiku, abys (checked) vyjimky prohlasil pouze za jinou navratovou hodnotu.

    Hele, mozna je to uz opravdu starim, ale mne oba pristupy prijdou zcela kromulentni (dokonce si myslim, ze vraceni hodnot je cistejsi reseni), a nemam problem kombinovat oba pristupy, kde je to vhodne. Mam kod psany ve funkcionalnim stylu, vracim hodnoty, pisu imperativni kod, pouzivam vyjimky. Nemam uplne nutkavou potrebu propagovat jedno jedinne spravne reseni. Ale pokud mas background v C++, nedivim se, ze vyjimky nemas rad.
    Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
    8.2.2021 11:43 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Takze jeste jednou. V situaci, kdy nauvazujes jenom try-catch, ale mas tam i finally, uz musis provadet hodne velkou ekvilibristiku, abys (checked) vyjimky prohlasil pouze za jinou navratovou hodnotu.
    No tohle mi právě není jasné, finally mi nepřijde nijak specielní...
    kromulentni
    TIL. To je teda poněkud kontrafibularita tohle slovo :-D
    Hele, mozna je to uz opravdu starim, ale mne oba pristupy prijdou zcela kromulentni (dokonce si myslim, ze vraceni hodnot je cistejsi reseni), a nemam problem kombinovat oba pristupy, kde je to vhodne. Mam kod psany ve funkcionalnim stylu, vracim hodnoty, pisu imperativni kod, pouzivam vyjimky. Nemam uplne nutkavou potrebu propagovat jedno jedinne spravne reseni. Ale pokud mas background v C++, nedivim se, ze vyjimky nemas rad.
    Já jenom ještě znovu zdůraznim, že silnej názor na výjimky mam právě hlavně v oblasti C++, Rustu apod. Čim vejš a dynamičtějc nad touhle oblastí, tim méně mam ohledně výjimek jasno. Java je v tomhle ohledu poněkud specielní případ, protože jednak je v tom spektru někde vprostřed a jednak ty checked exceptions jsou IMO neobvyklá varianta výjimek. Není mi tam moc jasná ta motivace, ale budiž, vyhovovalo by mi to víc než běžné výjimky, právě kvůli tomu konktraktu... Respektive to, že je staticky rekurzivně verifikovaný, to je na tom za mě ta důležitá část...
    8.2.2021 12:25 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    No tohle mi právě není jasné, finally mi nepřijde nijak specielní...
    Tak to dopada, kdyz tu copy-pastujes argument od nekoho jineho, aniz bys ho uplne promyslel.
    The thing about checked exceptions is that they are not really exceptions by the usual understanding of the concept. Instead, they are API alternative return values.
    Tj. v podstatě to je emulace toho konceptu hodnotových error typů nad implementací výjimek.
    Pokud neuvazujes finally, tok dat i rizeni muze jeste jakz takz pripominat navratovou hodnotu. S finally se ti to uz dost zasmodrchava.
    Není mi tam moc jasná ta motivace
    A vis, ze uz jsem to sem psal? Smyslem je donutit programatora k tomu, aby si uvedomil, ze dane volani muze skoncit vyjimkou a udelat rozhodnuti, kde ji bud zpracuje nebo preda dal. Cilem je omezit mnozstvi chyb, ktere programator muze udelat.

    Motivacni priklad:
    FILE *f = fopen("foo", "r");
    fputs("bar", f);
    fclose(f);
    
    Pises kod, kde rikas, co se ma delat. Bud nechces resit, co se ma stat, kdyz kterakoliv z tech operaci selze (na kazdou jednu instrukci tam mas dalsi if), nebo na to proste zapomenes. Kdyz mas checked exceptions uz te prekladac upozorni, ze by ses tomu mel venovat.

    Problem je, ze programatori se nechcou venovat korektnimu osetrovani chybovych stavu (nejbliz mistu, kdo se to da udelat) a berou to jako zbytecny opruz. Coz pak vede k tomu, ze maji radeji unchecked vyjimky nebo delaji prasarny, jak tu ukazoval bherzet.
    Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
    8.2.2021 13:28 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Tak to dopada, kdyz tu copy-pastujes argument od nekoho jineho, aniz bys ho uplne promyslel.
    To je nemístné nařčení :-) Já tady ten názor psal už před časem, na tenhle článek jsem narazil včera. V podstatě to bylo ve stylu "Hele, někdo jinej si myslí to samé co já."
    Pokud neuvazujes finally, tok dat i rizeni muze jeste jakz takz pripominat navratovou hodnotu. S finally se ti to uz dost zasmodrchava.
    Ať dělám co dělám, zašmodrchání nevidim... IMO finally mapuje víceméně 1:1 např. na situaci, kdy v jazyce se sumárními errory udělám něco jako (v pseudokódu)

    result := foobar();
    finalize_something();
    use_or_bubble_up(result);
    

    ... případně na konvenience jako RAII, monády a kdesi cosi, podle konkrétního jazyka (tušim, že Haskell má i funkci nazvanou finally).
    A vis, ze uz jsem to sem psal? Smyslem je donutit programatora k tomu, aby si uvedomil, ze dane volani muze skoncit vyjimkou a udelat rozhodnuti, kde ji bud zpracuje nebo preda dal. Cilem je omezit mnozstvi chyb, ktere programator muze udelat.
    Nerozumíme si. Tuhle motivaci chápu a souhlasim s tim, vracení sumární hodnoty má v tomhle stejné vlastnosti - nedovolí ti ignorovat chybu, poskytuje probublávání, je to staticky typované atd. Čemu úplně nerozumim je motivace použít pro tohle mechanismus výjimek místo návratových hodnot. Odpovim si sám: Je to dáno historicky, mechanismus výjimek už existoval a zdál se good enough, a naopak sumární typy nebyly zpopularizované, bylo to něco divného, muselo by se to přidávat + mechanismy na probublávání atd...
    Josef Kufner avatar 8.2.2021 14:33 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Jak se vlastně něco jako finally řeší v Rustu? Namísto try-catch má otazníček, má i něco místo finally?
    Hello world ! Segmentation fault (core dumped)
    8.2.2021 14:43 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    kdy v jazyce se sumárními errory udělám něco jako (v pseudokódu)
    result := foobar();
    finalize_something();
    use_or_bubble_up(result);
    
    To uz ale zacinas nehezky zasahovat do poradi jednotlivych operaci, ktere jdou (mohou jit) proti prirozenemu poradi, jak v nich uvazuje programator.
    Čemu úplně nerozumim je motivace použít pro tohle mechanismus výjimek místo návratových hodnot.

    Nevyhoda navratovych hodnot je v tom, ze maji rezii, maji rezii vzdy, bez ohledu na to, jestli kod bezi standardni vetvi nebo doslo k chybe.

    U vyjimek se ta rezie koncentruje do jejich vyvolani a zpracovani, coz je situace, ktera nastava zridka nebo vubec.

    Dneska jsme v situaci, kdy ma vetsinou smysl rezignovat na tuto rezii, ale jeste relativne nedavno to bylo neco tezko akceptovatelneho.
    Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
    8.2.2021 22:07 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Nevyhoda navratovych hodnot je v tom, ze maji rezii, maji rezii vzdy, bez ohledu na to, jestli kod bezi standardni vetvi nebo doslo k chybe.

    U vyjimek se ta rezie koncentruje do jejich vyvolani a zpracovani, coz je situace, ktera nastava zridka nebo vubec.

    Dneska jsme v situaci, kdy ma vetsinou smysl rezignovat na tuto rezii, ale jeste relativne nedavno to bylo neco tezko akceptovatelneho.
    Ok, to je fair enough.

    Výkon návratových hodnoty se dá zvýšit hinty pro branch prediction. V případě Rustu tím, že na to je operátor + ten Result typ má na sobě nějaké anotace, které říkají, co je standardní a chybová varianta, má na to v zásadě kompilátor dostatek informací. Ale jestli to reálně dělá, to nevím...
    xkucf03 avatar 8.2.2021 21:19 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Nerozumíme si. Tuhle motivaci chápu a souhlasim s tim, vracení sumární hodnoty má v tomhle stejné vlastnosti - nedovolí ti ignorovat chybu, poskytuje probublávání, je to silně typované atd. Čemu úplně nerozumim je motivace použít pro tohle mechanismus výjimek místo návratových hodnot. Odpovim si sám: Je to dáno historicky, mechanismus výjimek už existoval a zdál se good enough, a naopak sumární typy nebyly zpopularizované, bylo to něco divného, muselo by se to přidávat + mechanismy na probublávání atd...

    Oba ty přístupy mají něco do sebe (viz výše: funkcionální vs. imperativní styl). Ale ta motivace pro výjimky je zjevná a ty výhody (při imperativním stylu) nenahraditelné.

    Můžeš sice zřetězit volání metod/funkcí tak, abys tím emuloval IFy, cykly, try, catch atd. ale není to moc hezké ani čitelné. Lidi častěji uvažují tím imperativním stylem – mají nějakou posloupnost kroků, které se mají postupně vykonat. Mám rád, když je ten optimistický scénář (to proč ten program spouštíš, ta podstata) vidět jasně na první pohled a jsi co nejméně rozptylován ošetřováním různých chybových a málo častých stavů. A ty výjimky tomu pomáhají mj. tím, že jedním catch můžeš chytit celou množinu chyb vznikajících na různých místech (v try bloku máš většinou víc kroků, protože tě často nezajímá, který konkrétně selhal, typicky nepotřebuješ do try obalovat každé jednotlivé volání).

    Za mne jsou tedy výjimky užitečný syntaktický cukr, který umožňuje psát přehlednější kód a snižovat chybovost, explicitně vyjádřit, který výsledek je standardní-dobrý a který výjimečný-chybový + (kontrolované) výjimky donutí autora volajícího kódu se k těm chybám nějak postavit (nebo je vědomě poslat výš).

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    8.2.2021 22:47 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Lidi častěji uvažují tím imperativním stylem – mají nějakou posloupnost kroků, které se mají postupně vykonat. Mám rád, když je ten optimistický scénář (to proč ten program spouštíš, ta podstata) vidět jasně na první pohled a jsi co nejméně rozptylován ošetřováním různých chybových a málo častých stavů.
    Připadá ti, že takovýhle kód to nesplňuje?

    fn foobar() -> Result<Baz> {
        let zdroj1 = otevreni_1()?;
        let zdroj2 = otevreni_2()?;
        let baz = Baz::zkus_nacist(&zdroj1, &zdroj2)?;
        Ok(baz)
    }

    Kód obsahuje staticky typovaný error handling. Nejsou použity výjimky. Result<Baz> je alias pro Result<Baz, MujError>, abych to nemusel vypisovat u každé funkce v tom modulu, když všechny vracejí ten stejný error typ (pokud by funkce v modulu vracely různé error typy, bylo lepší alias nepoužít a mít to u každé explicitně). MujError definuje konverze/obalení nízkoúrovňovější error typů, takže třeba otevreni_1() může vracet nějaký detailněší typ, ze kterého se ten můj aplikačně-specifický vytvoří. Případný chybový výsledek se nemusí řešit hned o úroveň výš, může se nechat zase otazníky nebo nějak jinak probublat vejš, někam odeslat, uložit, zalogovat, zobrazit nebo mapovat či zabalit do ještě více high-level erroru, podle toho, co si přeje uživatel té funkce.

    Ta funkce obsahuje normální lineární "optimistický" kód. Jediné, co rozptyluje z hlediska error handlingu jsou ty otazníčky (a ten Ok() na konci). Někomu to vadí (M. Mareš výše). Mně osobně to přijde naopak lepší - není to moc znaků, ale přitom okamžitě vidim, kde všude může funkce selhat. Když budu hledat třeba nějakou chybu související s control flow, bude to mnohem snažší. Oproti tomu s výjimkami při pohledu na tu funkci vůbec nevidim, jestli to které volání způsobí nebo nezpůsobí přerušení normálního control flow návrat s chybou.

    (Toť můj subjektivní pohled.)
    xkucf03 avatar 8.2.2021 21:19 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce

    Tohle je pěkný příklad. Mimochodem, kdysi jsem si zkoušel udělat vzor pro odchytávání chyb a zavírání zdrojů v céčku, ale vyšlo mi z toho něco s hromadou IFů a GOTO:

    #include <stdio.h>
    
    // Jednotlivé chyby simulujeme změnou počtu argumentů příkazu.
    // Místo "argc == ?" by bylo volání nějaké funkce, která může selhat.
    
    #define THROW(throwable) do { result = 1; goto throwable; } while (0)
    
    int main(int argc, char**argv) {
            int result = 0;
            printf("program startuje\n");
    
            if (argc == 2) THROW(exception_0); // simulace chyby
    
            printf("otevření zdroje 1\n");
    
            if (argc == 3) THROW(exception_1); // simulace chyby
    
            printf("otevření zdroje 2\n");
    
            if (argc == 4) THROW(exception_2); // simulace chyby
    
            printf("normální běh programu\n");
    
    exception_2:
            printf("uzavření zdroje 2\n");
    exception_1:
            printf("uzavření zdroje 1\n");
    exception_0:
            printf("program končí s kódem: %d\n", result);
            return result;
    }

    S tím pojmenováním nejsem moc spokojený – asi nemá cenu si hrát na to, že to jsou výjimky a jejich chytání – to makro a návěstidla by se měly jmenovat jinak (Nějaké nápady? Lepší řešení?). Ale jinak to asi nějak takhle musí vypadat. Tím se zavře vše, co se stihlo otevřít, ale žádná velká krása to není a to ošetřování chyb odvádí pozornost od hlavního toku programu. Oproti tomu výjimky přímo podporované v syntaxi jazyka jsou velice elegantní řešení.

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    8.2.2021 22:18 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Kdybys chtěl v C emulovat ten control-flow výjimek, tak možná setjmp.h. Ale nejsem si jistý, že je to dobrý nápad.
    xkucf03 avatar 8.2.2021 22:37 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Výjimky, GOTO, C, C++, komplexita závislostí

    Na tom by se dalo ledasco postavit… Ale to už radši použiji C++. Obecně nemám moc důvod používat C (kromě nějakého přispívání do existujících projektů).

    Céčko je zajímavé snad leda z důvodu snižování komplexity (závislostí), protože C je takový společný jmenovatel (prakticky libovolný počítačový systém bude C obsahovat, nejde se mu moc vyhnout) a zároveň kompilátor typu TCC má jen nějakých 90 000 řádků kódu (není to úplně málo, ale srovnej si to s GCC nebo LLVM/Clang na kterých staví většina ostatních jazyků).

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    9.2.2021 10:02 okbobcz | skóre: 8
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Přesně tak jsou implementovány výjimky v Postgresu. Jen je to zabalené do maker. V Postgresu se výjimky používají pro uvolnění zdrojů. Většina výjimek je zachycená, v typickém scénáři dojde k uvolnění zdrojů alokovaných danou funkcí a k reraisnutí výjimky o úroveň výš. Na top úrovni dojde k rollbacku aktuální transakce a k zobrazení chyby. Výjimku lze zachytit a ošetřit, ale to se prakticky v Postgresu nedělá.

    9.2.2021 11:07 z_sk | skóre: 34 | blog: analyzy
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    za printf("normáln atd. ma ist return pred vynimky :)
    debian.plus@protonmail.com
    9.2.2021 19:35 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce
    Ne, nemá, protože tam simuluje uzavírání zdrojů a k tomu má dojít i při bezchybném běhu.
    xkucf03 avatar 8.2.2021 21:18 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Výjimky, RAII, byznys procesy, úroveň abstrakce + kontrakt metody

    Kontrakt je mnohem víc než signatura metody. Obsahuje i předpoklady, podmínky, vedlejší efekty, obecně chování, vztahy mezi metodami, pořadí volání, vícevláknovou bezpečnost, reentranci atd.

    Je pravda, že když mluvím o výjimkách, tak myslím primárně ty kontrolované, ale to tady nehraje roli. Kontrakt může spočívat i v tom, že když není splněna nějaká podmínka, tak metoda vyhazuje (běhovou) NullPointerException či IllegalArgumentException. Kontrakt taky může definovat vztah mezi více metodami, což je další věc, kterou signatura sama o sobě nepopisuje. Např. kontrakt pro equals()hashCode() říká, že když equals() vrací true, tak hashCode() obou objektů musí být stejný (ale obráceně to neplatí, stejný hash může znamenat i nerovnost).

    Kontrakt je většinou popsaný v komentáři nebo nějaké specifikaci. Ale samozřejmě, čím víc toho lze vyjádřit natvrdo pomocí datových typů, signatur, anotací atd., tím líp.

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    xkucf03 avatar 7.2.2021 11:54 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    což vevnitř funguje stejně jako výjimky, ale nevyužívá se to pro ošetřování běžných chyb, pouze pro "katastrofické" chyby, se kterými nejde nic dělat.

    Do jaké kategorie patří třeba situace, kdy editovaný soubor nejde uložit, protože na disku došlo místo?

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    Josef Kufner avatar 7.2.2021 12:52 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    PHP má od počátku dvojí chyby – fatální a ty ostatní. Teď se ty fatalní pozvolna předělávají na výjimky, neboť lidi zjistili, že občas je potřeba odchytit i ty oprávněně fatální chyby, jako například chyby syntaxe a používání nedefinovaných věcí.

    Ono ta "katastrofická" chyba je o něco méně katastrofická, když je uvnitř pluginu, který je naprosto postradatelný a vůbec nevadí, když se nenačte. Třeba nabízení souvisejících produktů v košíku e-shopu je zcela postradatelná věc, ale pokud kvůli tomu upadne i ten košík a nejde nakoupit, tak je to problém. A přitom stačí, aby v produkčním prostředí nebyla nějaká knihovna používaná výhradně při vývoji a někde zůstal zapomenutý ladicí výpis.
    Hello world ! Segmentation fault (core dumped)
    xkucf03 avatar 7.2.2021 15:14 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    +1
    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    7.2.2021 13:42 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Do jaké kategorie patří třeba situace, kdy editovaný soubor nejde uložit, protože na disku došlo místo?
    To je určitě bežný I/O error, který by se měl ohlásit uživateli. Panicking je na "katastrofické" chyby ve smyslu assertů, tj. narušení invariantů, tzn. tohle by bylo na panic jen v případě, že bys měl předpoklad, že k tomu nesmí dojít...

    Ale samozřejmě záleží na situaci. Nedávno jsem řešil případ, kdy si načtu ze souboru seznam cest k jiným souborům. Ten seznam má být z definice (specifikace rozhraní) validní Unicode, což na začátku zkontroluju (s řádným error reportingem samozřejmě), načtu ty data atd., nicméně ty cesty si ukládám a ještě s nima dál nějak pracuju, předávám dál apod. Datovej typ pro cestu nezaručuje validní Unicode, ale já vím, že ta cesta na Unicode zkonvertovat jde, protože už jsem to ověřil na začátku. Takže pak už tam error reporting nedávám, je tam jen assert/panicking, protože by se to mohlo stát jenom kvůli chybě v programu (někdo by třeba vyhodil tu kontrolu na začátku apod.) nebo nějaké fakt hodně zásadní chybě třeba s pamětí nebo něco. Ale není to běžný/očekávatelný chybový stav.

    Doufám, že to takhle dává smysl...
    Josef Kufner avatar 7.2.2021 13:47 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    A vadí něčemu, aby assert házel výjimku?
    Hello world ! Segmentation fault (core dumped)
    7.2.2021 14:33 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    No, to záleží na kontextu. V kontextu jazyka, který s výjimkama hodně počítá, to asi dává smysl, třeba Java hází NullPointerException, to je víceméně assert...
    8.2.2021 17:31 luky
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Ano, pokud vyhozeni vyjimky muze napachat skody - treba pokud pouzivate NVRAM a zjistite poruseni konzistence pameti, je lepsi okamzite zpanikarit nez riskovat, ze obsluha vyjimky napacha vic skody.
    xkucf03 avatar 7.2.2021 15:29 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Výhoda výjimek, assert

    Obávám se, že autor kódu, který vyhazuje výjimku (či jinak generuje chybu), není ten, kdo by mohl posoudit, jak moc závažná ta chyba je – vždy záleží na úhlu pohledu toho, kdo ten kód volá – na něm je, aby s chybou naložil tak, jak považuje za vhodné.

    Ty asserty vypadají, že jsou jiné a že by dávalo smysl je považovat za „katastrofické“ chyby, protože označují problém v kódu, ze kterého se nelze zotavit, jde o situaci, která by neměla nikdy nastat (a pokud ano, tak v důsledku toho, že někdo chybně změnil jinou část programu a předpoklady přestaly platit, takže je stejně potřeba to opravit v kódu a překompilovat). Jenže: rozsáhlejší programy se běžně skládají z různých komponent, knihoven a pluginů – viz #25 – ty sice běží v jednom paměťovém prostoru, v jednom procesu, ale přesto některé z nich mohou být postradatelné a ty pak nechceš, aby chyba v jedné takové komponentě shodila celý program – chceš i takovou chybu nějak odchytit a zotavit se z toho, protože všechno kromě té jedné komponenty může klidně pokračovat dál a není důvod, aby kvůli tomu došlo ke ztrátě dat a výpadku.

    Přijde mi lepší ke všem chybám přistupovat jednotným způsobem, viz #31 a nechat na autorovi volajícího kódu rozhodnutí, na jaké úrovni a jak je bude ošetřovat.

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    7.2.2021 18:21 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Obávám se, že autor kódu, který vyhazuje výjimku (či jinak generuje chybu), není ten, kdo by mohl posoudit, jak moc závažná ta chyba je – vždy záleží na úhlu pohledu toho, kdo ten kód volá – na něm je, aby s chybou naložil tak, jak považuje za vhodné.
    Samozřejmě. Proto taky se ten assert dělá často až na tom výsledném hodnotovém typu, kde se rozhodneš, jestli ho nějak ošetříš, zpropaguješ, nebo řekneš "tady očekávám hodnotu a když je tam chyba, tak panic".

    Případně různá API obvykle poskytují varianty s panickováním a bez, např. funkce foo() , která může panikovat, a k tomu do páru funkce try_foo(), která vrací result typ.
    7.2.2021 19:06 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Obávám se, že autor kódu, který vyhazuje výjimku (či jinak generuje chybu), není ten, kdo by mohl posoudit, jak moc závažná ta chyba je – vždy záleží na úhlu pohledu toho, kdo ten kód volá – na něm je, aby s chybou naložil tak, jak považuje za vhodné.
    Což je třeba problém s checked/unchecked výjimkami v Javě. Autoři tohoto vynálezu říkají, že unchecked mají být jen výjimky, které jsou natolik závažné, že program se z nich nemůže zotavit a pokračovat správně ve své funkci.

    Co to znamená v praxi? Že typicky např. reflexe vyhazuje bambilion checked výjimek, které musíš někde ručně obalit do unchecked výjimek, abys je nemusel předávat napříč celou hierarchií volání. Vycházím samozřejmě z předpokladu, že tou reflexí dělám něco, z čeho se program zotavit nedokáže.

    Setkal jsem se už s názorem, že checked výjimky v Javě jsou úlet a mnohem lepší je všechny výjimky obalovat do unchecked výjimek a je-li to relevantní, tak je vyjmenovávat v throws klauzuli (lze tam volitelně uvést i unchecked výjimky, standard to povoluje a jejich ošetření nevynucuje, ale např. IDE je našeptává). Já na to tak striktní názor nemám, ale faktem je, že výjimky v Javě často bohužel vedou na úplně zbytečný (a často nebezpečný) boiler-plate kód – hlavně méně zkušeným programátorům to dělává velké problémy.

    Takže… @SneakyThrows? :) Určitě je to lepší než to obalovat do RuntimeException, dá se to líp ošetřit později, ale stejně nevím, no. Názor?
    7.2.2021 20:23 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Což je třeba problém s checked/unchecked výjimkami v Javě.
    Přesně tak, to jsem zapomněl dodat, plus podobné rozkoly v jiných jazycích, třeba v C v userspace assert versus návratová hodnota nebo v kernelu panic versus návratová hodnota.

    Další rokzol, ke které vedou výjimky, je, že na posouzení uživatele API není jenom to, jestli nějaká chyba je katastrofická, ale taky to, jestli to vůbec je chyba (se kterou by se mělo nakládat specielním způsobem - vyhození výjímky). Proto mam radši tu filosofii, že nekatastrofická chyba je úplně normální stav a normální hodnota, se kterou se pracuje standardním způsobem, a ta filosofie výjimek - "Soustřeďme se na happy path a ošetření chyb dělejlme bokem" - pak vede k tomu, že lidi někde odchytávají výjimky a převádějí je zpátky na obyčejné hodnoty, např. funkce zkusí něco udělat, a když nastala výjimka, vrátí false. To pak celej ten koncept staví na hlavu, mohla to rovnou bejt hodnota...
    xkucf03 avatar 7.2.2021 21:26 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Přesně tak, to jsem zapomněl dodat, plus podobné rozkoly v jiných jazycích, třeba v C v userspace assert versus návratová hodnota nebo v kernelu panic versus návratová hodnota.

    Viz #43 – pořád je lepší (běhová) výjimka, kterou lze aspoň odchytit, než nějaká panika, která ti shodí úplně všechno. Totéž platí třeba i pro System.exit() v Javě – fakt nechceš, aby ti nějaká knihovna (nebo plugin) shazovala celý program (takže to zakážeš přes SecurityManager). Podobný problém je, když ti někdo bude zasírat STDIO. Obecně chceš, aby ten kód vespod jen sloužil a nedělal bordel – a řízení měl pevně v rukách ten klientský kód nad tím.

    ale taky to, jestli to vůbec je chyba

    Nějaký příklad? Tohle podle mého problém nebývá – obvykle je jasné, co je žádoucí chování a co je nějaký výjimečný scénář. Pokud to jasné není, tak tě samozřejmě nikdo nenutí výjimky používat – metoda bude vracet třeba různé typy se společným předkem nebo jeden typ s nějakými příznaky atd.

    Někdo se může chtít vyhýbat výjimkám kvůli výkonu, ale většinou asi půjde o předčasnou optimalizaci.

    Třeba céčkovská API často trpí tím, že se pro předávání výjimek (resp. chybových stavů) zneužije návratová hodnota. Tzn. místo toho, aby návratová hodnota obsahovala něco užitečného, co si můžeme rovnou přiřadit do proměnné, tak obsahuje jen informace o výjimce/chybě a ta užitečná hodnota (kvůli které jsme danou funkci volali) se vrací skrze výstupní proměnnou (ukazatel jako argument funkce). To mi přijde poměrně zvrácené – byť chápu, že to v tom jazyce moc jinak nejde a taky že to může být z hlediska výkonu lepší (vrátit třeba číslo -123 než někde vyrábět nějakou výjimku).

    Proto mam radši tu filosofii, že nekatastrofická chyba je úplně normální stav a normální hodnota, se kterou se pracuje standardním způsobem, a ta filosofie výjimek - "Soustřeďme se na happy path a ošetření chyb dělejlme bokem"

    Viz #31 – ne všechny výjimky chci řešit tam, kde vznikly – některé chci nechat probublat trochu výš a ošetřit je na jednom místě společně.

    pak vede k tomu, že lidi někde odchytávají výjimky a převádějí je zpátky na obyčejné hodnoty, např. funkce zkusí něco udělat, a když nastala výjimka, vrátí false. To pak celej ten koncept staví na hlavu, mohla to rovnou bejt hodnota...

    To záleží na zadání. Ano, někteří programátoři dělají chyby, neuvažují logicky, jsou nepořádní, dělají mizernou práci, chybně převedou výjimku na false (někdy to smysl dává, někdy ne – to záleží na zadání k tomu klientskému kódu) atd. Ale z toho nelze vinit výjimky.

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    7.2.2021 23:07 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Viz #43 – pořád je lepší (běhová) výjimka, kterou lze aspoň odchytit, než nějaká panika, která ti shodí úplně všechno.
    Tady jde IMO o nepochopení. Panika je určena pro stavy které jsou fakt špatné, ie. kdy nechat ten program běžet je horší než ho odstřelit, kdy třeba hrozí nevalidní přístup do paměti nebo něco podobného. Už jsem to zmiňoval - v jazyce jako Rust to existuje z +- stejného důvodu jako panikování v kernelu.

    Všimni si, že implementace JVM asserce taky obsahuje...
    Viz #31 – ne všechny výjimky chci řešit tam, kde vznikly – některé chci nechat probublat trochu výš a ošetřit je na jednom místě společně.
    Samozřejmě, vždyť obecně ani není možné řešit chybu tam, kde vznikla. Jazyky používající sumární typy to různými způsoby podporují. Třeba obalení nízkoúrovňového typu do vyššího (třeba aplikačně specifického) error typu mi např. v Rustu přijde ergonomičtější než s výjimkami.
    7.2.2021 20:52 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Autoři tohoto vynálezu říkají, že unchecked mají být jen výjimky, které jsou natolik závažné, že program se z nich nemůže zotavit a pokračovat správně ve své funkci.
    Toto rozdeleni dava smysl. Protoze checked vyjimky pak jsou soucasti kontraktu dane metody a programatorovi je jasne, ze metoda muze skoncit takovou nebo makovou vyjimkou a nuti programatora k tomu, aby se rozhodl, jestli se s tou vyjimkou vyporada, protoze vi, jak na to zareagovat, nebo ji preda vys.
    typicky např. reflexe vyhazuje bambilion checked výjimek,
    Vzhledem k tomu, ze reflexe pracuje na nizsi urovni, je proste prilezitosti, kde muze nejaka akce selhat mnohem vic nez v beznem kodu, a dava smysl, aby jednotlive metody manifestovaly, ze mohou selhat z takoveho a takoveho duvodu.
    Vycházím samozřejmě z předpokladu, že tou reflexí dělám něco, z čeho se program zotavit nedokáže.
    Ale to obecne neplati.
    Že typicky např. reflexe vyhazuje bambilion checked výjimek, které musíš někde ručně obalit do unchecked výjimek, abys je nemusel předávat napříč celou hierarchií volání.
    Hlavni problem je, ze rada programatoru, a casto i tech zkusenejsich, si neuvedomuje, ze stejne jako mas v kodu ruzne urovne abstrakce, tak vyjimky musi tyto urovne abstrakce kopirovat.

    Dejme tomu, ze mas pomoci reflexe implementovane pluginy a mas metodu void invokeAction(String name, Object... args).

    Muzes si vybrat, jak to resit:

    (1) Bud muzes nechat vsechny vyjimky probublat, tj. void invokeAction(String name, Object... args) throws MethodNotFoundException, IllegalAccessException, ClassNotFoundException.

    (2) Prebalit vsechno do unchecked vyjimky void invokeAction(String name, Object... args).

    (3) Zabalit to do vlastni vyjimky: void invokeAction(String name, Object... args) throws PluginInvocationException.

    Problem s (1) je jednak ten, ze se ti ty vyjimky zacinaji kupit (to je spis takovy esteticky problem), ale hlavne ti dochazi k prosakovani abstrakce a naruseni zapouzdreni.

    Problem s (2) je ten, ze necha uzivatele dane metody v blahove nevedomosti, ze metoda muze selhat. U (3) je neprijemne, ze to vyzaduje urcity kod navic, ale na druhou stranu uzivatel te metody vi, ze muze selhat a osetrit to podle sveho uvazeni (nekdy to muze byt fatalni, nekdy ne). Navic to umoznuje odstinit uzivatele od toho, co je pricinou vyjimky, proste vi, ze dana funkce selhala.

    Bohuzel (1) potkavam docela casto, (2) uz jsem parkrat taky potkal a je to podle me prasarna.

    Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
    xkucf03 avatar 7.2.2021 21:03 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    +1
    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    7.2.2021 21:07 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Ano, těmi příklady jsi to shrnul moc krásně. U (3) je největší problém ten boiler-plate kód: někde musíš definovat třídu vyjímky, provádět odchycení a přebalení v try/catch bloku a následně uvádět u každé metody – obtěžuje to občas stejně jako absence volitelného dynamického typování. To poslední zmiňované je méně závažný z uváděných problémů.

    Typicky mě to úplně nejvíc frustrovalo v testech a nebo při prototypování. Kolikrát jsem si posteskl, jak mi chybí nějaký syntaktický cukr pro něco jako @thisCouldGoTerriblyWrong(); (který by jakoukoliv případnou výjimku přebalil na unchecked).

    V produkčním kódu se s tím holt nějak popereš. Ten boiler-plate kód napíšeš (spíš vygeneruješ) jednou, uděláš nějaký refactoring, který předefinuje metody atd. Ale během samotného vývoje, kdy ještě nevíš, jestli to opravdu budeš řešit právě takto, je to fakt otrava a lidi potom mají tendenci to občas neskutečně naprasit… a pak na to zapomenout a nechat to tam.
    7.2.2021 23:33 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    provádět odchycení a přebalení v try/catch bloku
    Tohle mě při používání výjimek strašně štvalo. Moc nerozumim, jak si může někdo stěžovat na neergonomii otazníkového operátoru, ale přitom tolerovat tohle. Přitom ten otazníkový operátor umí využít implementaci From traity, a umí tedy zkonvertovat jeden error na druhý (a udělat z toho původního třeba příčinu v tom novém), aniž by bylo potřeba to explicitně dělat v každém místě použití (opravdu jsem jediný, komu to přijde jako šílenost?).

    Samozřejmě někdy člověk nechce jen tupě zkonvertovat, ale chce přitom dodat nějaké informace (třeba jméno souboru, že kterého selhalo čtení), nicméně k tomu není moc problém si připsat nějakou funkci nebo využít existující knihovní funkce, takže ve výsledku to není o moc složitější, mj. právě protože ta chyba je normální hodnota.
    8.2.2021 10:14 podlesh
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Asi tak. Hlavní problém je absence elegantního způsobu jak celý try/catch/finally implementovat jednou (a nejlépe parametricky) a pak už jen používat.

    Jenomže to je obecný problém Javy, absence metaprogramování. Něco se dá polepit lambdama, ale zrovna výjimky ne, ty se prostě musí dělat copypastou.

    Josef Kufner avatar 8.2.2021 11:15 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Bylo by příliš zvrhlé používat v Javě Céčkový preprocesor? :-)
    Hello world ! Segmentation fault (core dumped)
    xkucf03 avatar 8.2.2021 21:27 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Makra, preprocesory, AOP, úpravy a generování bajtkódu

    To je zvrhlé v kterémkoli jazyce, protože jen tak lepíš kousky textu dohromady a doufáš, že z toho vyjde validní zdroják. V Javě existují a používají se mnohem hygieničtější prostředky – aspektově orientované programování, různé (anotační) procesory nebo úprava a generování bajtkódu, kde jsou pro tebe jednotlivé kousky programu/kódu objekty, se kterými si můžeš hrát a různě je skládat a ohýbat.

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    9.2.2021 18:19 Vinicius
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Něco takového existuje, používalo se to třeba pro Java ME Midlety, kdy opravdu záleželo na tom, aby výsledná aplikace byla co nejmenší, nebo bylo potřeba z jednoho zdrojového textu připravit více variant pro různé telefony.
    8.2.2021 21:06 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Tak k metaprogramování mají blíž spíš anotační procesory a agenti (instrumentace). První zmíněné se používá na generování kódu při kompilaci, to druhé na modifikaci bajtkódu při zavádění programu. Ale pro běžné použití je to dost těžkopádné.

    Jednou se mi stalo, že jsem fakt nutně potřeboval dědit z final třídy, prostě to nešlo řešit jinak a nakonec to skončilo tak, že jsem tu knihovnu prostě forknul a ty keywordy tam umazal s vědomím, že pokud se to nepodaří protlačit do upstreamu, tak holt někde budu muset udržovat patche a klepat se hrůzou při každém pokusu tu knihovnu zupgradovat. Teorie byla taková, že se to velmi důkladně otestuje, a upgradovat se prostě pokud možno nebude. Nakonec se ukázalo, že celý ten projekt je tak neskutečně plesnivý, že to raději používat nebudeme vůbec, a celé se to zahodilo. O nedlouho později ke stejnému závěru došli i autoři onoho projektu a přestali to vyvíjet.

    Bohužel šlo o velmi netriviální věc, psát si celé sami od začátku nepřipadalo v úvahu a na výběr v té době nebylo. Ale jak říkám, nakonec se to jako slepá ulička ukázalo z jiných důvodů a naštěstí se to tedy použít nemuselo. Muselo se zůstat u předchozího řešení, které fungovalo, ale bylo tak pomalé, že prostě existovala velká finanční motivace to nahradit něčím rychlejším.
    xkucf03 avatar 7.2.2021 20:57 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Což je třeba problém s checked/unchecked výjimkami v Javě.

    To se mi taky nelíbí. Ale pořád je to výrazně lepší, než nějaký assert, který nejde odchytit a způsobí tvrdý pád programu, paniku, katastrofu. Ty asserty bych nechal leda tak pro testovací provoz, kde tvrdý pád zajistí, že nad tou chybou nikdo nepřimhouří oko a nezůstane to bez povšimnutí. Ale v produkci chci mít možnost se z chyb zotavit nebo třeba říct: když spadne tahle komponenta/knihovna/plugin, tak si to jen někam poznamenáme, nějak na to zareagujeme, ale nesletí nám kvůli tomu celý systém.

    unchecked mají být jen výjimky, které jsou natolik závažné, že program se z nich nemůže zotavit a pokračovat správně ve své funkci

    Říkat můžou ledasco, ale tohle je blbost. Určitou dobu tu byla velká móda předělávat všechna rozhraní tak, aby vyhazovala nekontrolované výjimky místo kontrolovaných – v hello world příkladech to vypadalo hezky a lidem se to líbilo. Ten ukázkový kód najednou vypadal jednoduše, sluníčkově, jako by žádné problémy neexistovaly. Ve skutečnosti ale jen předstíráš, že problém neexistuje. V praxi se pak stejně ustálil zvyk, že na určité úrovni odchytneš úplně všechny výjimky (včetně běhových) a nějak je ošetříš – pro jistotu, aby ti nesletěl celý systém, ale třeba jen jeden požadavek nebo jen jedna malá část, zatímco ostatní můžou v pohodě doběhnout. Viz třeba ten příklad s košíkem a souvisejícími produkty v #25.

    lepší je všechny výjimky obalovat do unchecked výjimek a je-li to relevantní, tak je vyjmenovávat v throws klauzuli (lze tam volitelně uvést i unchecked výjimky

    To není dobrý nápad, jde to proti typové kontrole. Místo toho, abys měl rozhraní popsané strojově čitelným způsobem (signaturou metody), na kterém může stavět kompilátor a další nástroje, tak si píšeš nějaké poznámky do komentářů a doufáš, že si je ostatní programátoři přečtou. Je to asi jako kdybys místo typu boolean vracel String a do komentáře napsal, že v něm bude vždycky jen "Y" nebo "N".

    výjimky v Javě často bohužel vedou na úplně zbytečný (a často nebezpečný) boiler-plate kód

    Pokud tu výjimku na dané úrovni neumíš nebo nechceš ošetřit, tak ji nech probublat nahoru. Jestliže nenajdeš vhodný nadtyp, který bys deklaroval, tak to přebal do nějaké jiné výjimky, která bude odpovídat abstrakci tvojí metody. Pokud si myslíš, že ta výjimka nikdy nenastane a je na volaných metodách deklarovaná zbytečně, tak ji můžeš přebalit do běhové výjimky – třeba tím @SneakyThrows. Je to trochu ošemetné a spoléháš na to, že ten, kdo tvůj kód volá si na nějaké úrovni odchytne i ty běhové výjimky, aby mu nespadlo úplně všechno. Ale neříkám, že je to vyloženě špatně – někdy to smysl dává.

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    7.2.2021 21:18 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    Určitou dobu tu byla velká móda předělávat všechna rozhraní tak, aby vyhazovala nekontrolované výjimky místo kontrolovaných – v hello world příkladech to vypadalo hezky a lidem se to líbilo.
    Ono ještě trochu záleží na tom, o jakém kusu softwaru se bavíme. U knihoven jsou unchecked výjimky strašná prasárna, tam se není o čem bavit.

    Konkrétně s tím názorem, že checked výjimky je lepší vůbec nepoužívat, jsem se setkal na projektu, který sestával převážně z mikroslužeb a malých modulů, kde stačilo výjimky odchytávat a logovat na vyšší úrovni. Kdyby se tam všude předávala výjimka, že se nelze připojit k databázi (třeba), tak by to znamenalo písmenka navíc, ale nemělo by to vůbec žádnou přidanou hodnotu, protože stejně se s tebou chybou nedá skoro nic dělat a musí se to odchytit na tom jednom místě nahoře, kde se řekne „aha, tak úloha nám neproběhla, protože … a asi to teda zkusíme znovu později“.

    Tak to jen pro kontext, jakou optikou se na ty checked/unchecked výjimky dívám. Jinak samozřejmě máte s dedou.jabko pravdu, že jako součást kontraktu např. u knihoven to dává smysl. Pořád to ale není dokonalý koncept a občas mi přijde lepší to ohnout – v případě, který popisuji, jsem na to ze začátku strašně prskal, ale nakonec jsem uznal, že je to daleko lepší.
    7.2.2021 21:25 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Výhoda výjimek, assert
    (Všechny výjimky jsou ultimátně odděděné z jedné unchecked výjimky nebo jejích potomků a součástí „kontraktu“ implicitně je znalost, kde se ty výjimky odchytávají. Když je potřeba něco ošetřovat i jinde na nižší úrovni, tak to klidně může být checked výjimka.)
    Jendа avatar 6.2.2021 16:31 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Není mi jasné, jestli říkáš „místo Pythonu používej V pro napsání celé aplikace“ nebo „ty C moduly piš ve V a volej je z toho Pythonu“. To první jako fakt nejde, protože tím přijdu o celý ekosystém Pythonu, od featur jazyku po knihovny od numpy po GTK, to druhé neřeší spoustu věcí, např. numerické výpočty → budu chtít třeba použít intrinsics (ručně volané SSE/AVX instrukce); volání C API → to se ve V deklaruje celkem podobně jako ukazuju v zápisku, takže je blbost jít Python → V → C.
    6.2.2021 23:45 dumblob | skóre: 10 | blog: dumblog
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Ju, dle zápisku jsem usoudil, že se jedná o menší věci (už jenom dle toho, že neřešíš tu správu paměti atd.), takže jsem měl na mysli tu první variantu (vše ve V). Nějak mi uniklo, že tam chceš "celý/velkou_část ekosystému Python" (ty featury jazyka Python nepočítám, protože ty mi právě přijdou docela dobře nahraditelné).

    P.S. Vzhledem k tomu, že V je transpiler do C, tak pro vlastní bindingy (pokud se nespokojíš s existujícím výběrem) napíšeš o poznání méně kódu než v Pythonu.

    P.P.S. V má samozřejmě "vestavěný" assembler (jako C), takže intrinsics a instrukce jsou vlastně "first class citizens" (vše se jede přes unsafe{...} blok) a nemusíš vlastně nic moc řešit.
    Jendа avatar 7.2.2021 01:04 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Ju, dle zápisku jsem usoudil, že se jedná o menší věci (už jenom dle toho, že neřešíš tu správu paměti atd.)
    Správu paměti neřeším v té céčkové části.
    Jendа avatar 7.2.2021 21:30 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Jinak velikost těch věcí je typicky kolem tisíce řádek Pythonu a stovky řádek C.
    6.2.2021 18:25 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Jů, hele, další programovací jazyk. Když to odborně zhodnotím po té estetické stránce – protože to je reálně jediná věc, kterou se dnes popularita programovacích jazyků řídí, že? – tak mě hned jako první praští do očí ošklivý keyword fn místo dnes již zábavnějšího fun. Na druhou stranu samozřejmě chválím použití pascalovského := pro přiřazení a vynechání kulatých závorek pro řídící proměnné foreach cyklu.

    Víc tam toho takhle na první pohled po estetické stránce nevidím. Ten ukázkový zdroják vypadá standardně, Picasso ani Tančící dům to není, ale ani to v dnešní době neurazí. Označil bych to za takovou klasickou nudnou užitkovou novostavbu.

    Jestli není cílem vytvářet umění a znovu implementovat všechny ty knihovny a frameworky, tak se obávám, že by bylo na výběr z ustálenějších, lépe podporovaných programovacích jazyků, kde je jen otázkou coding-stylu a popř. správně nastavených lintů nebo warningů docílit víceméně čehokoliv (užitečného), co podporuje náhodně vybraný hobby jazyk.

    (Nemám nic proti hobby jazykům, ba naopak. Ale vážně, nepřijde vám, že se to s tím hledáním dokonalého jazyka pro produkční použití začíná dost přehánět?)
    6.2.2021 21:17 Michal Kubeček | skóre: 72 | Luštěnice
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Ale vážně, nepřijde vám, že se to s tím hledáním dokonalého jazyka pro produkční použití začíná dost přehánět?

    Začíná? :-)

    7.2.2021 00:50 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Poslední dobou mi to přijde fakt extrém. Jak jsem psal, nemám nic proti hobby/výzkumným jazykům, ale předčasné masovější rozšíření za jiným účelem než je testování toho jazyka (a jeho filozofie, idiomů, myšlenek) vede akorát na zbytečnou fragmentaci. Alespoň trochu seriózněji jsem se zabýval více jazyky než bych na prstech spočítal a přesto pak jdu a potkám někde zase něco úplně nového. A nestačí se znovu doučit pár preprocesorových maker nebo něčeho, ale znovu studovat dokumentaci od datových typů po řídící struktury, kde většina je toho stejně +/- stejná a zbytek jsou různé záludnosti, které člověka vypečou. Přitom by často stačilo vyjít třeba ze striktního subsetu existujícího jazyka (pokud nepodporuje/nelze použít meta-programování) a pak tam něco přidat, nebo tak.
    7.2.2021 12:07 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Alespoň trochu seriózněji jsem se zabýval více jazyky než bych na prstech spočítal a přesto pak jdu a potkám někde zase něco úplně nového.
    Ono to zas nebude až tak dramatický, konkrétně v tomhle případě (jazyk V) mi přijde silně nepravděpodobný, že by to používalo víc jak 5 a půl člověka, je to ve stejným stavu už roky. To v produkci s největší pravděpodobností nepotkáš. Všelijakých obskurních experimentálních jazyků existují mraky a je to tak celkem normální.
    Jak jsem psal, nemám nic proti hobby/výzkumným jazykům, ale předčasné masovější rozšíření za jiným účelem než je testování toho jazyka (a jeho filozofie, idiomů, myšlenek) vede akorát na zbytečnou fragmentaci.
    To je těžký; pokud má nějakej jazyk prorazit do reálnýho používání, v zásadě není jiná možnost než testovat ho v produkci. Experimentální jazyky, který nejsou v produkci a jen je někdo někde testuje na nějakejch pár víceméně syntetickejch projektech, budou experimentální navždy.
    Přitom by často stačilo vyjít třeba ze striktního subsetu existujícího jazyka (pokud nepodporuje/nelze použít meta-programování) a pak tam něco přidat, nebo tak.
    Nestačilo. Striktní subsety nefungujou. Můžeš nastolit striktní subset na svém projektu nebo ve firmě, ale v rámci ekosystému se to nemůže podařit, lidi budou prostě ten jazyk používat se vším všudy. Třeba u C++ šance, že by se lidi shodli, co přesně má obsahovat ten "správnej" subset je nula.

    Další věc je, že tyhle jazyky si s sebou nesou za dekády nabalený technický i 'kulturní' (nebo ekosystémový) dluh, kterýho se v podstatě není možný zbavit jinak než vytvořením novýho jazyka. Viz třeba Digraphs & Trigraphs in C++:
    Trigraphs were proposed for deprecation in C++0x, which was released as C++11. This was opposed by IBM, speaking on behalf of itself and other users of C++, and as a result trigraphs were retained in C++11. Trigraphs were then proposed again for removal (not only deprecation) in C++17. This passed a committee vote, and trigraphs (but not the additional tokens) are removed from C++17 despite the opposition from IBM.
    ... mi to přijde totálně absurdní. A podobně je to se vším. C++ ekosystém čekal na moduly >= 15 let [1]. Za tu dobu můžeš mít komplet vyvinut nový jazyk od prvního nápadu/nástřelu (Rust 2006) přes první stabilní verzi (Rust 2015) po nasazení v produkci a adopci velkými firmami (Rust dnes).

    Lidi už taknějak mají plné zuby té malé množiny několika vyvolených posvěcených jazyků, kde se na nic nesmí sáhnout, na řešení problémů se čeká dekády a stejně to ve výsledku je hrozný a člověk se musí (obrazně i doslova) přizpůsobovat tomu, že na nějakém počítači v roce 1970 nešly napsat složené závorky.
    7.2.2021 12:39 Martin Mareš
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Zrovna digrafy a trigrafy sice v jazyku strašily, ale jsou v zásadě neškodné. Ano, člověk je může omylem napsat, ale od jakéhokoliv dnešního překladače okamžitě schytá warning. Za těch asi 30 let, co v Céčku píšu, se mi to stalo dvakrát. Ostatně, uvidíme za 20 let, jaký balast se nahromadí v Rustu a jak těžké bude se ho zbavit :) Dlouhodobá udržitelnost programovacích jazyků je hodně těžký problém a viděno zpětně, málokterému jazyku se to povedlo tak dobře jako Céčku.

    Nakolik je Rust dospělý jazyk, bych byl ochoten polemizovat. Jistě, mnoho toho umí, ale co třeba dynamické linkování? Ne, nechcete mít po systému tisíc kopií částí standardní knihovny. Nechcete překládat úplně všechno znovu, pokud se v té knihovně najde bezpečnostní chyba, kterou potřebujete opravit na řádu hodin. Jako jazyk na samostatně stojící velké projekty už je Rust docela OK, od jazyka vhodného pro stavbu celého operačního systému má zatím na míle daleko.
    7.2.2021 14:22 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Ostatně, uvidíme za 20 let, jaký balast se nahromadí v Rustu a jak těžké bude se ho zbavit :)
    Ano, s tim zcela souhlasim, je klidně možný, že to bude blbý. On nějakej ten balast tam je už teď. Je tam na tohle koncept editions, který zatim (2015 → 2018) fungoval velmi pěkně, ale samozřejmě není zaručeno, že to půjde takhle dobře i v budoucnu...
    Jistě, mnoho toho umí, ale co třeba dynamické linkování?
    Z technického pohledu mi ta situace s dynamickým linkováním nepřijde moc odlišná od C++ (což je otázka, jestli je dobře :-D Asi není.). Když budeš chtít maximalizovat binární kompatibilitu, je nejjistější napsat C API wrapper (v Rustu i C++). Co se týče ABI jazyka jako takového, v C++ jsou linuxové garance zpětné kompatibility dané mechanismy, které si kolem toho povětšinou Linux vytvořil sám, tj. třeba Itanium ABI apod. C++ jako jazyku je to dodnes dost u zadku, co si budeme povídat. A koneckonců jsou s tím také problémy (viz třeba PITA na CentOSu/RedHatu). V zásadě od C++ se to liší tím, že GCC má aktuálně zapojením lidí apod. blíže k Linuxu než rustc.

    Co se týče stavby OS, jako problém bych spíš viděl alokátory/alokaci. Zlepšilo se to sice za poslední dobu (podpora custom alokátorů, zachytávání chyb, ...), ale stále to ještě není ono, ty API nejsou všechny stabilizovaný a ekosystém na to není moc připravený (nicméně když člověk píše např. jádro, je asi jasné, že nepoužije kdejakou knihovnu určenou pro userspace).
    xkucf03 avatar 7.2.2021 15:18 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    +1
    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    7.2.2021 18:44 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Všelijakých obskurních experimentálních jazyků existují mraky a je to tak celkem normální.
    Ano. Bez toho bychom se nikam neposunuli.
    To je těžký; pokud má nějakej jazyk prorazit do reálnýho používání, v zásadě není jiná možnost než testovat ho v produkci. Experimentální jazyky, který nejsou v produkci a jen je někdo někde testuje na nějakejch pár víceméně syntetickejch projektech, budou experimentální navždy.
    Jde o to, jestli ten jazyk testuješ úmyslně (a s ohledem na okolnosti je to vhodné), nebo ne.
    Striktní subsety nefungujou. Můžeš nastolit striktní subset na svém projektu nebo ve firmě, ale v rámci ekosystému se to nemůže podařit, lidi budou prostě ten jazyk používat se vším všudy.
    Nerozumíme si. Myslel jsem to tak, že můžeš vytvořit úplně nový jazyk, který bude modifikací nějakého již existujícího (resp. jeho subsetu, protože v praxi ty jazyky často jsou zatížené balastem, který tam třeba nechceš). Takto např. byly do Javy přidány generika – vzniklo rozšíření jazyka Java označované jako Generics Java, které se následně stalo součástí standardu.

    Postupem času také vzniklo několik dialektů Pascalu, různých LISPů apod. V assembleru existují ustálené názvy instrukcí – taky se na nějaké architektuře nezačne jmp říkat go, protože to někomu přijde víc cool.

    Přijde mi divné „vygenerovat“ úplně nový jazyk a očekávat, že se všichni budou učit další bezvýznamnou mutaci existujícího konceptu. Něco jako kdyby Odersky v té Generics Javě náhodně zavedl, že pro stringy se používají prosté uvozovky místo dvojitých, přejmenoval pár typů a přidal pár nějakých dalších quirků.

    Nechci to V příliš hanět, protože takhle od stolu nedokážu posoudit, jak moc to dává nebo nedává smysl, ale poslední dobou mi opravdu připadá, že kam se podívám, tam se pracuje na nějakém novém jazyku, který konečně vyřeší veškeré problémy lidstva (a přidá 10 nových). Přitom to ale právě není úzce vymezené jako hobby, výzkum a nebo snaha rozšířit nějaký existující jazyk. Spíš je snem, přáním a ultimátním cílem ten jazyk zpropagovat pro masové použití.
    7.2.2021 23:55 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Myslel jsem to tak, že můžeš vytvořit úplně nový jazyk, který bude modifikací nějakého již existujícího (resp. jeho subsetu, protože v praxi ty jazyky často jsou zatížené balastem, který tam třeba nechceš). Takto např. byly do Javy přidány generika – vzniklo rozšíření jazyka Java označované jako Generics Java, které se následně stalo součástí standardu.
    Tak něco takovýho je třeba TypeScript coby superset JS.
    Přijde mi divné „vygenerovat“ úplně nový jazyk a očekávat, že se všichni budou učit další bezvýznamnou mutaci existujícího konceptu. Něco jako kdyby Odersky v té Generics Javě náhodně zavedl, že pro stringy se používají prosté uvozovky místo dvojitých, přejmenoval pár typů a přidal pár nějakých dalších quirků.
    Souhlasim, že není moc přínosný, když se tohle děje. Nicméně posoudit, kdy to tak je a kdy je, je celkem těžký a do značný míry subjektivní.

    Viděl bych to asi takhle:
    • Jazyky, které mají smysl (vč. toho, že to je samostatný jazyk): Rust, Go, Kotlin, Swift, TypeScript, Julia, ...
    • Jazyky, které mají zajímavé vlastnosti, nicméně celkově se jim přínos nepodařil: D, Scala, Elm, Vala, ...
    • Jazyky, kde nevidim ani zajímavé vlastnosti ani přínos: Dart, CoffeScript, Crystal, V-lang, ...
    • Jazyky, které neznám natolik, abych měl názor: Nim, Elixir, nové lispy, nové selfy, Raku ... a mnoho dalších ...
    Samozřejmě výše uvedené je můj osobní názor a je mi jasný, že mnoho lidí bude nesouhlasit :-)
    8.2.2021 00:35 Bherzet | skóre: 19 | blog: Bherzetův blog
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Tak něco takovýho je třeba TypeScript coby superset JS.
    Ano, jazyky postavené nad stejnou platformou (JS, JVM, resp. GraalVM, teoreticky CPython, …) a plně interoperabilní s tím hlavním jazykem, mi přijdou jako menší zlo. Tím spíš, pokud jsou od toho jazyka navíc odvozené tak, aby se vstupní bariéra zbytečně a uměle nezvyšovala. Pak tomu nemám až tak moc co vytknout.
    Nicméně posoudit, kdy to tak je a kdy je, je celkem těžký a do značný míry subjektivní.
    Je to hodně subjektivní a nechtěl bych posuzovat, který jazyk má nebo nemá smysl, už jen proto, že se to v čase nutně muselo měnit. Jen když se na to podívám víc globálně, tak mi opravdu přijde, jako by se s těmi jazyky roztrhl pytel a začalo se to řídit víc módou než rozumem.
    Gréta avatar 8.2.2021 17:21 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    6.2.2021 15:46    
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Proč to nemá tučňáka?

    Edit: no proto...:
    7.2.2021 16:48 tom11111
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    ASAN detekuje i memory leaky a bohužel detekuje spoustu leaků z Pythonu.
    Co to vlastně znamená? Že má Python v sobě chyby, nebo že sanitizer nemá o Pythonu dost informací a hlásí falešné detekce nebo ještě něco jiného? Jak je vidět, nejsem v této oblasti zrovna odborník :-) Díky.
    Jendа avatar 7.2.2021 17:15 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Podle mě to jsou věci, které alokuje jednou a pak je neuvolní před ukončením (což je asi v pořádku, protože když se ukončuješ, tak už je to jedno).
    xkucf03 avatar 7.2.2021 22:18 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše ASan a falnešné poplachy

    Tohle bych považoval za chybu – už jen kvůli tomu, že to způsobuje falešné poplachy a brání lidem používat ASan. Já na tenhle problém narazil zatím jen u Qt grafů – zatímco Qt jako takové problém nemá, tak ta komponenta pro kreslení grafů ty falešné poplachy generuje.

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    8.2.2021 15:26 okbobcz | skóre: 8
    Rozbalit Rozbalit vše Re: ASan a falnešné poplachy
    Například takto se chová ncurses. Nicméně lze ji přeložit s nastavením, kdy se paměť poctivě čistí. To ale není default.
    limit_false avatar 8.2.2021 22:29 limit_false | skóre: 23 | blog: limit_false
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    CFFI - good to know, vím že něco takového existuje, ale nikdy jsem to úplně neměl potřebu použít. Na prototypování se to ale může hodit.

    Když už tak SWIG. Je to víc práce, někdy jsou ty syntaktické inkantace dost magické než je člověk pochopí a správně použije, ale pak to obalí správně exceptiony, objekty atd. Lze správně ošetřit alloc/dealloc.

    Na to, že funkce/metoda neblokuje GIL je potřeba nějaké explicitní makro, co mi ale přijde možná lepší než když se to předpokládá automaticky, že je funkce bez vedlejších efektů (pokud třeba je předáván složitější objekt, co není copy-by-value).

    When people want prime order group, give them prime order group.
    Jendа avatar 9.2.2021 03:19 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Když už tak SWIG. Je to víc práce, někdy jsou ty syntaktické inkantace dost magické než je člověk pochopí a správně použije
    SWIG jsem kdysi používal a právě z uvedených důvodů mi přišlo CFFI jednodušší. Ale může to být tím, že nepředávám pythoní objekty, moje Cčkové funkce jsou především na DSP a pracují se syrovými poli floatů/intů.
    13.2.2021 17:15 mln
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Pokračovanie blogu o Radare nebude ?
    Jendа avatar 14.2.2021 05:35 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Já bych se chtěl zeptat k tomu Numpy, kterým jsem začal. Dejme tomu, že dělám tohle:
    # mějme pole A
    output = np.fft.fftshift(np.log10((np.square(np.real(A))+np.square(np.imag(A)))/fftsize))
    
    Když bych to psal normálně jako cyklus po prvcích, tak se vždycky vezme prvek, aplikují se na něj ty operace, a uloží se na správnou pozici (fftshift cyklicky posunuje indexy) do pole output. S trochou štěstí to kompilátor zvládne udělat tak, že vždycky natáhne 4 prvky do SSE registrů, udělá to nad nima a všechny 4 je uloží.

    Dá se tohle v numpy nějak zfůzovat? Nebo to jako fakt přečte celé A (čímž se vysype L1 cache), vezme to reálnou složku a uloží někam do tempu. Pak ho to znova přečte a vezme imaginární složku. Pak to dvakrát přečte mezivýsledky a udělá z nich druhé mocniny. Pak je to sečte. Pak zlogaritmuje. A na konci to ještě vezme půlky toho pole a prohodí je. Takže to asi 15x překopíruje velké pole v paměti, i když to celé šlo provést lokálně a rovnou kropit ven výsledky?
    1.3.2021 07:38 Milan Straka
    Rozbalit Rozbalit vše Re: Python, C a CFFI
    Ano, ten kód výše to udělá jak píšeš (pomocí spousty průchodů).

    Osobně jsem s tím moc nepracoval, ale existuje Numba, která se pokouší JITovat numerické kompilace v Pythonu, takže pak jdou dělat věci jako
    @numba.vectorize
    def abs2(x):
        return x.real**2 + x.imag**2
    
    Tohle se pokusí JITnout (pomocí LLVM) vektorizovanou verzi; pomocí numba.jit by to šlo napsat jako
    @numba.jit
    def abs2b(x):
        return np.square(np.real(x))+np.square(np.imag(x))
    
    ale tam už toho kompilátor asi nedokáže dost přeskládat.

    Když se to pak změří pomocí
    x = np.random.normal(size=16384).astype(np.complex128)
    _ = abs2(x), abs2b(x)
    %timeit np.abs(x)**2
    %timeit np.square(np.real(x))+np.square(np.imag(x))
    %timeit abs2(x)
    %timeit abs2b(x)
    
    tak u sebe dostanu
    102 µs ± 1.26 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    30.3 µs ± 274 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    8.68 µs ± 42.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    13.7 µs ± 82.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.