abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
dnes 15:11 | Zajímavý článek

Softwarový syntezátor pro Linux Yoshimi (fork ZynAddSubFX) byl vydán ve verzi 2.0. Lukáš Růžička představuje Yoshimi v článku Hahaha Yamaha aneb Jak si z notebooku udělat synťák? na MojeFedora.cz.

Ladislav Hagara | Komentářů: 0
dnes 09:00 | Nová verze

Byla vydána nová verze 21.0 komunitní edice multiplatformního v Javě naprogramovaného univerzálního SQL klienta a nástroje pro správu databází DBeaver (Wikipedie). Proběhla změna číslování. Verze 21.0 vychází po verzi 7.3. Zdrojové kódy jsou k dispozici na GitHubu pod licencí Apache 2.0.

Ladislav Hagara | Komentářů: 0
včera 09:00 | Zajímavý článek

Nová čísla časopisů od nakladatelství Raspberry Pi: MagPi 103 (pdf), HackSpace 40 (pdf), Wireframe 47 (pdf) a Hello World 15 (pdf).

Ladislav Hagara | Komentářů: 1
27.2. 16:22 | IT novinky

Google na svém blogu věnovaném AI představil nový hlasový kodek Lyra. Kvalitou je kodek Lyra s datovým tokem 3 kbps srovnatelný s kodekem Opus s datovým tokem 8 kbps.

Ladislav Hagara | Komentářů: 14
27.2. 10:00 | Nová verze

Po šestnácti měsících byla vydána nová verze 2.3 a krátce na to opravná verze 2.3.1 open source nástroje OnionShare pro přenos souborů, hostování webů a chatování přes Tor. Přehled novinek v příspěvku na blogu. Pro Linux je OnionShare k dispozici také ve formátech Flatpak a Snap.

Ladislav Hagara | Komentářů: 2
27.2. 08:00 | Nová verze

Bola vydaná nová verzia komunitnej distribúcie Mageia 8, ktorá je priamym nasledovníkom niekdajšej Mandrake/Mandrivy. Prináša podporu pre architektúru ARM, novšie prostredie GNOME 3.38.3 a KDE Plasma 20.12.0 a prechod na Python 3. Viac info sa dozviete v poznámkach k vydaniu, ináč Mageia je plne lokalizovaná do národných jazykov a poskytuje tak ako klasické aj živé inštalačné obrazy.

lukve | Komentářů: 0
26.2. 14:22 | Zajímavý software

GNU poke dospěl po třech letech vývoje do verze 1.0. Jedná se o interaktivní rozšiřovatelný editor pro práci se strukturovanými binárním daty. Přednáška věnovaná GNU poke na konferenci Kernel Recipes 2019.

Ladislav Hagara | Komentářů: 0
26.2. 09:00 | Komunita

Počet sad změn v OpenStreetMap dosáhl 100 milionů. Uživatel Lamine Ndiaye přidal budovy ve vesnici Nianiane v Senegalu.

Ladislav Hagara | Komentářů: 4
26.2. 08:00 | Nová verze

Byla vydána nová stabilní verze 2.92 svobodného 3D softwaru Blender. Přehled novinek v oznámení o vydání a na YouTube.

Ladislav Hagara | Komentářů: 0
26.2. 07:00 | IT novinky

Společnost Framework představila svůj první produkt: Framework Laptop. Jedná se o modulární notebook, který bude možné "libovolně" konfigurovat, upgradovat a opravovat. Podrobnosti budou zveřejňovány postupně. V prodeji by měl být v létě [Hacker News].

Ladislav Hagara | Komentářů: 1
Co používáte k zaznamenávání úkolů či poznámek?
 (35%)
 (15%)
 (34%)
 (9%)
 (22%)
 (21%)
 (22%)
Celkem 350 hlasů
 Komentářů: 14, poslední 19.2. 10:41
Rozcestník

Python, C a CFFI

6.2. 00:36 | Přečteno: 2185× | Linux | Výběrový blog | poslední úprava: 6.2. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 01:04 plostenka
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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 10:02 okbobcz | skóre: 2
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. 11:07 debian+ | skóre: 23 | 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 16:31 Jendа | skóre: 76 | 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. 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. 01:04 Jendа | skóre: 76 | 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. 21:30 Jendа | skóre: 76 | 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. 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. 21:17 Michal Kubeček | skóre: 71 | 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. 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. 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. 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. 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. 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. 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. 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. 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. 17:21 Gréta | skóre: 30 | blog: Grétin blogísek | Stockholm
Rozbalit Rozbalit vše Re: Python, C a CFFI

nebo v odinoj hele :O ;D

pražáci chraňte svý zdraví a zustaňte v bezpečí paneláků hele, hele a hele!!☃ slíkací doktor fylosofie🤡
6.2. 15:46    
Rozbalit Rozbalit vše Re: Python, C a CFFI
Proč to nemá tučňáka?

Edit: no proto...:
7.2. 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. 17:15 Jendа | skóre: 76 | 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. 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. 15:26 okbobcz | skóre: 2
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. 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. 03:19 Jendа | skóre: 76 | 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. 17:15 mln
Rozbalit Rozbalit vše Re: Python, C a CFFI
Pokračovanie blogu o Radare nebude ?
Jendа avatar 14.2. 05:35 Jendа | skóre: 76 | 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?
dnes 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.