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 094
    • Zobrazit profil
Re:FP a error handling
« Odpověď #1 kdy: Dnes v 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: Dnes v 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: Dnes v 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.