FP a error handling

FP a error handling
« kdy: 02. 12. 2025, 18:31:29 »
Nechápem, prečo keď FP zavrhuje výnimky a namiesto toho odporúča používať union typy ako Result alebo Option, tak F# aj tak podporuje klasické výnimky z .NET-u a dokonca má aj vlastné, neobjektové výnimky nazývané exception (čo je špecialita F#, v C# ani v iných jazykoch to nefunguje):

.NET exceptions:
Kód: [Vybrat]
open System
raise(Exception(message = "Klasicka .NET exception"))

F# exceptions:
Kód: [Vybrat]
exception Chyba of string
raise(Chyba "Typovo cista F# exception")

typ result:
Kód: [Vybrat]
let (/) x y =
    match y with
    | 0 -> Error("Delenie nulou neni povolene")
    | _ -> Ok (x / y)

Okrem toho má ešte aj asynchrónne výnimky cez Async.Catch, a zároveň poskytuje typy Result aj Option. Nehovorím, že je to blbosť – z pohľadu výkonu je Result lepší ako výnimky. Ale aj tak nechápem, prečo sa vo F# dá robiť jedna vec piatimi rôznymi spôsobmi. Začína to pôsobiť, akoby F# bobtnal podobne ako C++.

Aký spôsob error handlingu používate v FP jazykoch?


BoneFlute

  • *****
  • 2 095
    • Zobrazit profil
Re:FP a error handling
« Odpověď #1 kdy: 03. 12. 2025, 03:30:56 »
Nemůže to být tím, že hodně FP jazyků směřuje ke statickému typování a tam jsou výjimky tak nějak komplikací - jiný kanál?

Co se týče syntaxe, tak třeba Rust se svýma "?" je docela zkousnutelný.

Kód: [Vybrat]
(a div (b - c))? + 4

Re:FP a error handling
« Odpověď #2 kdy: 03. 12. 2025, 08:01:31 »
(Předesílám, že F# ani .NET svět vůbec neznám)
Proč podporuje .NETové výjimky bych chápal, prostě to běží na .NET a musí to s ním nějak fungovat.
Z rychlého googlení ty "neobjektové výjimky" jsou klasické .NET výjimky (dědí od System.Exception), takhle se prostě v F# deklarujou.
A Result prý existuje až od F# 4.0, předtím se asi používaly výjimky i ve "funkcionálním" jazyce (prostě z toho tehdy ten .NET víc trčel).

Re:FP a error handling
« Odpověď #3 kdy: 03. 12. 2025, 08:14:04 »
Ono i historicky F# vychází z OCamlu, který používal výjimky mnohem více než .NET - např. i funkce find pro hledání v Hashtbl vyhazovala výjimku Not_found, když klíč nenašla (find_opt tehdy neexistovala).

Výjimky jde pak přirozeně zobecnit na algebraické efekty, což udělal OCaml 5. Takže po vyhození a zpracování se můžete vrátit do místa vyhození (např. ošetříte chybu a pokračujete z místa, kde vznikla) třeba s náhradní hodnotou.

Jinak bych řekl, že výkon Result v .NET bude horší než v případě výjimek, pokud chyba moc často nenastává. Důvodem je, že výsledek zbytečně obalujete a pak ho musíte vybalit.

BoneFlute

  • *****
  • 2 095
    • Zobrazit profil
Re:FP a error handling
« Odpověď #4 kdy: 04. 12. 2025, 18:50:04 »
algebraické efekty

Algebraické efekty jsou super věc. Další z těch, které teprve čekají na objevení v mainstreimových jazycích. A taky GADTs, toho se taky jen tak nedočkáme.


Re:FP a error handling
« Odpověď #5 kdy: 05. 12. 2025, 09:12:14 »
V ryzím FP nemá chytání výjimek svoje místo. Házení výjimek problém není – každý výraz se může buď vyhodnotit, nebo jeho vyhodnocení může selhat (např. skončit nekonečnou sérií tail callů – každý Turing-complete jazyk musí něco podobného umožnit), a výjimky jsou jen jiným druhem selhání. A kde o užitečnější druh selhání než nikdy nekončící výpočet. Ale chytání výjimek je teoreticky problematické – když se nějaký podvýraz není schopen vyhodnotit, najednou to může způsobit úplně jiný výsledek.

V reálných jazycích bývá typicky snaha o nějaký pragmatický přístup k FP, ne o ryzí FP. Jo, je to rozdíl mezi Haskellem a F#. A jak bylo zmíněno, F# má fungovat na platformě .NET s dalšími jazyky, a tyto jazyky mohou házet výjimky, takže F# je umí házet a nejspíš i chytat.

Disclaimer: F# jsem viděl jen z rychlíku (s Haskellem jsem na tom lépe), nicméně ten dotaz je celkem obecný, tak jsem si na něj troufl odpovědět.