{"id":18097,"date":"2024-05-02T09:12:29","date_gmt":"2024-05-02T07:12:29","guid":{"rendered":"https:\/\/vived.io\/?p=18097"},"modified":"2024-05-02T09:18:30","modified_gmt":"2024-05-02T07:18:30","slug":"o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172","status":"publish","type":"post","link":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/","title":{"rendered":"O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber &#8211; JVM Weekly vol. 172"},"content":{"rendered":"\n<p>Dzisiaj b\u0119dzie o podej\u015bciach do obs\u0142ugi b\u0142\u0119d\u00f3w &#8211; zar\u00f3wno w bran\u017cy jako takiej, jak i nowych propozycjach dla Javy. A wszystko zaczniemy sobie od Monad.<\/p>\n\n\n\n<p>Co to jest Monada? Niekt\u00f3rzy m\u00f3wi\u0105, \u017ce to monoid w kategorii endofunktor\u00f3w, <a href=\"https:\/\/blog.plover.com\/prog\/burritos.html\">co odwa\u017aniejsi \u017ce buritto<\/a>. W uproszczeniu Monada to poj\u0119cie matematyczne, kt\u00f3re s\u0142u\u017cy do modelowania operacji, kt\u00f3re mog\u0105 by\u0107 komponowane sekwencyjnie, wywodz\u0105ce si\u0119 z w teorii kategorii (bardzo ciekawy temat &#8211; je\u015bli kiedykolwiek mieli\u015bcie ci\u0105goty do bardziej akademickiego IT, bardzo polecam <a href=\"https:\/\/github.com\/hmemcpy\/milewski-ctfp-pdf\">Category Theory For Programmers<\/a> od Bartosz Milewskiego). W programowaniu funkcyjnym, monady s\u0105 u\u017cywane do obs\u0142ugi efekt\u00f3w ubocznych (jak operacje IO, czy obs\u0142uga b\u0142\u0119d\u00f3w) i struktur danych w spos\u00f3b, kt\u00f3ry pozwala na zwi\u0119z\u0142e i elastyczne zarz\u0105dzanie przep\u0142ywem danych i operacji (ponownie &#8211; min. obs\u0142uga b\u0142\u0119d\u00f3w). Powszechnie u\u017cywan\u0105 przez wi\u0119kszo\u015b\u0107 z Was w Javie monad\u0105 jest klasa Optional, b\u0119d\u0105ca sposobem na obs\u0142ug\u0119 obecno\u015bci warto\u015bci lub jej braku. Zasadniczo opakowuje warto\u015b\u0107, kt\u00f3ra mo\u017ce by\u0107 lub nie by\u0107 null, dostarczaj\u0105c metody do bezpiecznego przetwarzania jej bez ryzyka wyst\u0105pienia <code>NullPointerException<\/code>. R\u00f3\u017cnego rodzaju Monad jest bardzo wiele, \u017ceby wymieni\u0107 tutaj cho\u0107by np. Monad\u0119 IO czy Monada Try (kt\u00f3ra jeszcze wr\u00f3ci dzisiaj w naszej opowie\u015bci).<\/p>\n\n\n\n<p>Przy czym jest to termin, o kt\u00f3rym pisze si\u0119 bardzo trudno, poniewa\u017c jak kiedy\u015b stwierdzi\u0142 znany w \u015brodowisku JavaScriptu <strong>Douglas Crockford<\/strong>:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>In addition to it begin useful, it is also cursed and the curse of the monad is that once you get the epiphany, once you understand &#8211; &#8222;oh that&#8217;s what it is&#8221; &#8211; you lose the ability to explain it to anybody.<\/p>\n<\/blockquote>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-1024x576.png\" alt=\"\" class=\"wp-image-18102\" srcset=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-1024x576.png 1024w, https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-300x169.png 300w, https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-768x432.png 768w, https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image.png 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Powy\u017csz\u0105 grafik\u0119 ukrad\u0142em z miniaturki pierwszego z naszych dzisiejszego bohatera &#8211; filmiku <a href=\"https:\/\/www.youtube.com\/watch?v=GaAe7zGq1zM\">The Death of Monads? Direct Style Algebraic Effects<\/a>, kt\u00f3ry to w wiralowy spos\u00f3b kr\u0105\u017cy ostatnio po r\u00f3\u017cnego rodzaju programistycznych agregatorach i ma kilka ciekawych, kontrowersyjnych opinii &#8211; autor twierdzi bowiem \u017ce Monady, mimo \u017ce pot\u0119\u017cne, bywaj\u0105 niezgrabne jako narz\u0119dzie do zarz\u0105dzania efektami ubocznymi w programowaniu funkcyjnym. Film argumentuje, \u017ce bezpo\u015brednie efekty algebraiczne oferuj\u0105 prostsz\u0105 i czystsz\u0105 alternatyw\u0119, aby osi\u0105gn\u0105\u0107 podobne wyniki&#8230; i s\u0105 znacznie \u0142atwiejsze do zrozumienia.<\/p>\n\n\n\n<p>Wyobra\u017a sobie, \u017ce pracujesz nad projektem, kt\u00f3ry wymaga korzystania z r\u00f3\u017cnych narz\u0119dzi i zasob\u00f3w, takich jak pliki, po\u0142\u0105czenia z internetem, czy dost\u0119p do bazy danych. Ka\u017cde z tych dzia\u0142a\u0144 wprowadza pewne komplikacje, kt\u00f3re w programowaniu nazywamy &#8222;efektami ubocznymi&#8221;. Monady s\u0105 skuteczne w ich obs\u0142udze, ale mog\u0105 te\u017c by\u0107 skomplikowane w u\u017cyciu i zrozumieniu, poniewa\u017c ka\u017cdy krok zwi\u0105zany z efektem ubocznym wymaga dok\u0142adnej obs\u0142ugi.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class MonadExample {\n    public static void main(String&#091;] args) {\n        Optional&lt;String&gt; email = getUserEmail(&quot;123&quot;);\n\n        \/\/ U\u017cycie monady Optional do przetworzenia warto\u015bci\n        email.ifPresent(System.out::println);\n    }\n}<\/code><\/pre>\n\n\n\n<p>Bezpo\u015brednie efekty algebraiczne to nowsze podej\u015bcie, kt\u00f3re pozwala na bardziej zrozumia\u0142e i elastyczne zarz\u0105dzanie efektami ubocznymi. Zamiast otacza\u0107 ka\u017cdy efekt uboczny warstw\u0105 kontroli, jak w przypadku monad, bezpo\u015brednie efekty algebraiczne umo\u017cliwiaj\u0105 ich deklarowanie w bardziej naturalny i czytelny spos\u00f3b.<\/p>\n\n\n\n<p>Pracuj\u0105c z bezpo\u015brednimi efektami algebraicznymi, deklarujesz efekty uboczne jako cz\u0119\u015b\u0107 logiki programu, ale ich faktyczne wykonanie jest odroczone do specjalnych funkcji nazywanych &#8222;uchwytami efekt\u00f3w&#8221; (effect handlers). Uchwyty te mo\u017cna dostosowa\u0107 w zale\u017cno\u015bci od kontekstu, na przyk\u0142ad inne uchwyty mog\u0105 by\u0107 u\u017cywane podczas testowania, a inne w produkcji.<\/p>\n\n\n\n<p>Pseudo przyk\u0142ad tego, jak ca\u0142o\u015b\u0107 wygl\u0105da po stronie logiki:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class AlgebraicEffectsExample {\n    public static void main(String&#091;] args) {\n        String email = perform(getUserEmail(&quot;123&quot;));\n        System.out.println(email);\n    }\n\n    public static String getUserEmail(String userId) throws Effect {\n        User user = findUserById(userId);\n        if (user != null) {\n            return user.getEmail();\n        } else {\n            throw new Effect(&quot;User not found&quot;);\n        }\n    }\n\n    static class Effect extends Exception {}\n}<\/code><\/pre>\n\n\n\n<p>Obs\u0142uga efektu wywo\u0142ywanego w funkcji <code>perform<\/code> m\u00f3g\u0142by by\u0107 obs\u0142u\u017cony w taki spos\u00f3b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>try {\n    String email = perform(getUserEmail(&quot;123&quot;));\n    System.out.println(email);\n} catch (Effect e) {\n    handleEffect(e);\n}\n\npublic static void handleEffect(Effect effect) {\n    if (effect.getMessage().equals(&quot;User not found&quot;)) {\n        System.out.println(&quot;No user found with the specified ID.&quot;);\n    } else {\n        System.out.println(&quot;An unknown error occurred.&quot;);\n    }\n}<\/code><\/pre>\n\n\n\n<p>tylko pami\u0119tajcie, \u017ce poni\u017csze odbywa\u0107 si\u0119 powinno w spos\u00f3b niewidoczny dla u\u017cytkownika, po prostu Java nie umo\u017cliwi implementacji. Niestety, efekty nie s\u0105 czym\u015b, co da si\u0119 \u0142atwo zasymulowa\u0107 i j\u0119zyk musi je wspiera\u0107 \ud83d\ude41<\/p>\n\n\n\n<p>To podej\u015bcie sprawia, \u017ce kod staje si\u0119 czystszy i \u0142atwiejszy do zrozumienia, poniewa\u017c oddziela logik\u0119 programu od bezpo\u015bredniej obs\u0142ugi efekt\u00f3w ubocznych. Umo\u017cliwia te\u017c \u0142atwiejsz\u0105 zmian\u0119 i testowanie kodu, poniewa\u017c mo\u017cesz manipulowa\u0107 sposobem obs\u0142ugi efekt\u00f3w bez modyfikacji g\u0142\u00f3wnej logiki programu. Tak jak jednak wspomnia\u0142em, cz\u0119\u015b\u0107 rzeczy jest bardzo trudno zasymulowa\u0107 (zw\u0142aszcza w wygodny spos\u00f3b, nie wydaj\u0105cy si\u0119 by\u0107 sztucznym).<\/p>\n\n\n\n<p>Dlatego te\u017c przejdziemy sobie wreszcie do g\u0142\u00f3wnej cz\u0119\u015bci dzisiejszej edycji. Ostatnio pojawi\u0142o si\u0119 bowiem sporo interesuj\u0105cych JEP-\u00f3w (temat, do kt\u00f3rego jeszcze b\u0119d\u0119 wraca\u0107), ale jeden z nich bardzo \u0142adnie wpisuje si\u0119 w temat dzisiejszej edycji. O ile bowiem efekty algebraiczne jeszcze przed nami (cho\u0107 nie da\u0142bym sobie r\u0119ki uci\u0105\u0107, \u017ce kiedy\u015b si\u0119 nie pojawi\u0105), to Tw\u00f3rcy Java na kt\u00f3rym\u015b etapie rozwa\u017cali (i dalej mo\u017ce rozwa\u017caj\u0105) Monad\u0119 <code>Try<\/code>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"804\" height=\"349\" src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-1.png\" alt=\"\" class=\"wp-image-18105\" srcset=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-1.png 804w, https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-1-300x130.png 300w, https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-1-768x333.png 768w\" sizes=\"auto, (max-width: 804px) 100vw, 804px\" \/><figcaption class=\"wp-element-caption\">Cho\u0107 powy\u017csze nag\u0142\u00f3wki z Reddita r\/java uzna\u0142bym za nieco&#8230; hurraoptymistyczne<\/figcaption><\/figure><\/div>\n\n\n<p>Monada <code>Try<\/code> to struktura w programowaniu funkcyjnym, kt\u00f3ra pomaga w obs\u0142udze operacji, kt\u00f3re mog\u0105 zako\u0144czy\u0107 si\u0119 b\u0142\u0119dem. Otacza ona wykonanie kodu, kt\u00f3re mo\u017ce rzuci\u0107 wyj\u0105tek, i zwraca wynik w formie Success z warto\u015bci\u0105, je\u015bli operacja si\u0119 powiedzie, lub Failure z wyj\u0105tkiem, je\u015bli wyst\u0105pi b\u0142\u0105d. Mo\u017cecie j\u0105 zna\u0107 z biblioteki Vavr:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import io.vavr.control.Try;\n\npublic class TryMonadExample {\n    public static void main(String&#091;] args) {\n        Try&lt;Integer&gt; result = Try.of(() -&gt; Integer.parseInt(&quot;123&quot;));\n\n        result.map(value -&gt; value * 2)\n              .onSuccess(System.out::println)\n              .onFailure(ex -&gt; System.out.println(&quot;Error occurred: &quot; + ex.getMessage()));\n\n        Try&lt;Integer&gt; resultWithFailure = Try.of(() -&gt; Integer.parseInt(&quot;abc&quot;));\n        int recoveredValue = resultWithFailure.getOrElse(0);\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>Ca\u0142o\u015b\u0107 nie jest jaka\u015b bardzo trudna do zaimplementowania (polecam sobie spr\u00f3bowa\u0107 w formie treningu), ale tak naprawd\u0119 powy\u017csze rozwi\u0105zanie bardzo traci na tym, \u017ce j\u0119zyk nie posiada specjalnych struktur do jej obs\u0142ugi, przez co ca\u0142o\u015b\u0107 jest bardzo &#8222;verbose&#8221;. Mo\u017ce si\u0119 jednak okaza\u0107, \u017ce ju\u017c nied\u0142ugo, poniewa\u017c tw\u00f3rcy JDK wraz z rozwojem Pattern Matchingu i ewolucji <code>switch<\/code> szukaj\u0105 dobrego sposobu na obs\u0142ug\u0119 wyj\u0105tk\u00f3w w takowych i jako rozwi\u0105zanie w JEPie <a href=\"https:\/\/bugs.openjdk.org\/browse\/JDK-8323658\">Exception handling in switch (Preview)<\/a>.<\/p>\n\n\n\n<p>Ulepszenie na obs\u0142udze wyj\u0105tk\u00f3w rzucanych przez selektor (czyli <code>e<\/code> w <code>switch (e) ...<\/code>), kt\u00f3re mog\u0105 by\u0107 teraz obs\u0142ugiwane bezpo\u015brednio w bloku <code>switch<\/code>. Zademonstrujmy to poprzez przytoczone u\u017cycie <code>Future.get()<\/code>. Aby obs\u0142u\u017cy\u0107 r\u00f3\u017cne sytuacje, historycznie musieli\u015bmy otacza\u0107 <code>switch<\/code> blokiem try-catch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;code&gt;Future&lt;Box&gt; f = ...;\n\ntry {\n    switch (f.get()) {\n        case Box(String s) when isGoodString(s) -&gt; score(100);\n        case Box(String s) -&gt; score(50);\n        case null -&gt; score(0);\n    }\n} catch (CancellationException ce) {\n    ...\n} catch (ExecutionException ee) {\n    ...\n} catch (InterruptedException ie) {\n    ...\n}\n<\/code><\/code><\/pre>\n\n\n\n<p>Wprowadzenie nowego przypadku obs\u0142ugi wyj\u0105tk\u00f3w, zapisywanego jako <code>case throws<\/code>, pozwala na bezpo\u015brednie ich przechwytywanie wewn\u0105trz bloku <code>switch<\/code>, co eliminuje konieczno\u015b\u0107 stosowania zewn\u0119trznego try-catch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Future&lt;Box&gt; f = ...\nswitch (f.get()) {\n    case Box(String s) when isGoodString(s) -&gt; score(100);\n    case Box(String s)                      -&gt; score(50);\n    case null                               -&gt; score(0);\n    case throws CancellationException ce    -&gt; ...ce...\n    case throws ExecutionException ee       -&gt; ...ee...\n    case throws InterruptedException ie     -&gt; ...ie...\n}\n<\/code><\/pre>\n\n\n\n<p>Wprowadzenie <code>case throws<\/code> (i obs\u0142ugi nulli) pozwala na zastosowanie <code>switch<\/code> jako uniwersalnej maszyny obliczeniowej w kontekstach programowania opartego na wyra\u017ceniach, jak w strumieniach API. Na przyk\u0142ad:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>stream.map(Future&lt;Box&gt; f -&gt; switch (f.get()) {\n    case Box(String s) when isGoodString(s) -&gt; score(100);\n    case Box(String s) -&gt; score(50);\n    case null -&gt; score(0);\n    case throws Exception e -&gt; { log(e); return score(0); }\n}).reduce(0, Integer::sum);\n<\/code><\/pre>\n\n\n\n<p>Dzi\u0119ki temu podej\u015bciu <code>switch<\/code> mo\u017ce bezpo\u015brednio obs\u0142ugiwa\u0107 zar\u00f3wno warto\u015bci null, jak i r\u00f3\u017cne typy wyj\u0105tk\u00f3w bez dodatkowych klauzul <code>catch<\/code>.<\/p>\n\n\n\n<p>No dobra, ale co ma do tego Monada <code>Try<\/code>? Ot\u00f3\u017c na <a href=\"https:\/\/mail.openjdk.org\/pipermail\/amber-spec-experts\/2024-April\/004117.html\">li\u015bcie mailingowej JDK pojawi\u0142a si\u0119 dyskusja na temat dalszej ewolucji tego rozwi\u0105zania<\/a>. Tw\u00f3rcy Javy rozwa\u017cali bowiem wprowadzenie nowych konstrukcji takich jak chainowanie wyj\u0105tk\u00f3w i monady <code>Try<\/code>, jednak opinie na temat ich potrzeby s\u0105 mieszane. Obecnie w Javie stosuje si\u0119 tradycyjne bloki try-catch do zarz\u0105dzania wyj\u0105tkami, co jest proste, ale mo\u017ce by\u0107 uci\u0105\u017cliwe przy u\u017cyciu metod, kt\u00f3re zar\u00f3wno zwracaj\u0105 warto\u015bci, jak i wyrzucaj\u0105 wyj\u0105tki &#8211; jak ma to miejsce w opisywanych w tek\u015bcie przypadkach. Jako, \u017ce try catch nie jest wyra\u017ceniem (nie zwraca warto\u015bci) powoduje, \u017ce kod jest mniej komponowalny i bardziej podatny na b\u0142\u0119dy. Propozycja przekszta\u0142cenia try-catch w wyra\u017cenie okaza\u0142a si\u0119 zbyt ograniczona, poniewa\u017c wymaga\u0142a, aby bloki try i catch generowa\u0142y ten sam typ, co zbytnio ogranicza\u0142o mo\u017cliwo\u015bci obs\u0142ugi r\u00f3\u017cnych wynik\u00f3w wyj\u0105tk\u00f3w.<\/p>\n\n\n\n<p>Z drugiej strony, integracja natywnej monady <code>Try<\/code> mog\u0142aby zaoferowa\u0107 bardziej uniwersalne rozwi\u0105zanie, osadzaj\u0105c wyj\u0105tki w konstrukcie funkcyjnym, kt\u00f3ry m\u00f3g\u0142by by\u0107 przetwarzany w innym miejscu. Pomys\u0142 ten pozwoli\u0142by na operacje takie jak kolejkowanie lub przekazywanie monady Try do przetwarzania w r\u00f3\u017cnych kontekstach, umo\u017cliwiaj\u0105c bardziej jednolite zarz\u0105dzanie wyj\u0105tkami. Jednak\u017ce, pomimo potencjalnych korzy\u015bci, to podej\u015bcie r\u00f3wnie\u017c zosta\u0142o odrzucone, sugeruj\u0105c, \u017ce cho\u0107 Java mog\u0142aby w\u0142\u0105czy\u0107 bardziej zaawansowane konstrukty (takie jak Monada Try z natywn\u0105 obs\u0142ug\u0105 w strukturach j\u0119zyka) czy rozbudowa\u0107 konstrukcje switch-case dla wyj\u0105tk\u00f3w, obecne preferencje sk\u0142aniaj\u0105 si\u0119 ku utrzymaniu lub nieznacznemu udoskonaleniu istniej\u0105cych struktur, zamiast gruntownej przebudowy. Dyskusja wskazuje bowiem na z\u0142o\u017cono\u015b\u0107 i potencjalne ograniczenia wprowadzenia nowych abstrakcji do j\u0119zyka, kt\u00f3re mog\u0142yby zar\u00f3wno poprawi\u0107 obs\u0142ug\u0119 b\u0142\u0119d\u00f3w, jak i jednocze\u015bnie wprowadzi\u0107 nowe wyzwania w zarz\u0105dzaniu wyj\u0105tkami.<\/p>\n\n\n\n<p>Wszystko jednak ma\u0142ymi kroczkami. Wida\u0107 jednak, \u017ce Pattern Matching pcha ewolucj\u0119 j\u0119zyka do przodu. Ca\u0142\u0105 sytuacje przywo\u0142uje dlatego, \u017ce po raz kolejny pokazuje, jak wa\u017cna jest ewolucja j\u0119zyka&#8230; i jak wa\u017cnym dla nas wszystkich jest to, \u017ce jest ona tak starannie przeprowadzana w jednak &#8222;mainstreamowym&#8221; j\u0119zyku jakim jest Java.<\/p>\n\n\n\n<p>Mo\u017ce jednak kiedy\u015b Efekty? Loom pod spodem <a href=\"https:\/\/www.infoq.com\/presentations\/continuations-java\/\">wprowadzi\u0142 tak zwane &#8222;delimited continuations&#8221;<\/a> (mechanizm umo\u017cliwiaj\u0105cy kontrol\u0119 nad przep\u0142ywem wykonania programu poprzez zapisywanie, przechowywanie i p\u00f3\u017aniejsze przywracanie okre\u015blonych punkt\u00f3w w kodzie, co pozwala na bardziej elastyczn\u0105 manipulacj\u0119 stosami wywo\u0142a\u0144), a te w <a href=\"https:\/\/blog.poisson.chat\/posts\/2023-01-02-del-cont-examples.html\">Haskellu stanowi\u0105 w\u0142a\u015bnie krok po\u015bredni do wprowadzenia systemu effect\u00f3w<\/a>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"625\" height=\"412\" src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-4.png\" alt=\"\" class=\"wp-image-18116\" srcset=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-4.png 625w, https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-4-300x198.png 300w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><figcaption class=\"wp-element-caption\">Absolutnie nie sugeruje, \u017ceby z Javy zrobi\u0107 Haskella &#8211; ja nie z tych. Ale po prostu g\u0142owa mi zabrn\u0119\u0142a w takim dziwnym kierunku.<\/figcaption><\/figure><\/div>\n\n\n<p>A je\u015bli spodoba\u0142y Wam si\u0119 tego typu rozwa\u017cania nad r\u00f3\u017cnymi typami i strukturami, to par\u0119 dni temu (idealny timing) ukaza\u0142 si\u0119 artyku\u0142 zatytu\u0142owany <a href=\"https:\/\/ifesunmola.com\/sum-types-in-java\/\">Sum types in Java<\/a> od <a href=\"https:\/\/www.linkedin.com\/in\/ifesunmola\/\">Ife Sunmola<\/a> oferuje wprowadzenie do typ\u00f3w Sumy w Javie (czyli de facto Union types) wraz przyk\u0142adow\u0105 implementacj\u0119, analizuj\u0105c ich przydatno\u015b\u0107 w rozwi\u0105zywaniu typowych problem\u00f3w programistycznych, kt\u00f3re wymagaj\u0105 zarz\u0105dzania r\u00f3\u017cnymi, ale okre\u015blonymi typami. Ot, taka wisienka na torcie.<\/p>\n\n\n\n<p>Mia\u0142o by\u0107 kr\u00f3tko, wysz\u0142o d\u0142ugo &#8211; ale mam nadzieje, \u017ce si\u0119 podoba\u0142o.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>PS1: Tak jak obieca\u0142em we wst\u0119pie, za tydzie\u0144 ju\u017c bardziej standardowa edycja. Ale dajcie te\u017c zna\u0107 czy Wam si\u0119 takie jednotematyczne podobaj\u0105, ja si\u0119 przy nich bardzo dobrze bawi\u0119.<\/p>\n\n\n\n<p>PS: Je\u015bli znacie Polski, zapraszam 9 Maja na konferencje <a href=\"http:\/\/javeloper.pl\">javeloper.pl<\/a>. O godzinie 16 opowiem bowiem podczas niej o GraalVM, a konkretnie Truffle i czym si\u0119 go je (pun intended).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"574\" src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-3-1024x574.png\" alt=\"\" class=\"wp-image-18111\" srcset=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-3-1024x574.png 1024w, https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-3-300x168.png 300w, https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-3-768x431.png 768w, https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-3.png 1432w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Jakby kto\u015b jeszcze nie by\u0142 przekonany &#8211; <a href=\"https:\/\/www.linkedin.com\/feed\/update\/urn:li:activity:7186730329020239872\/\">slajdy znajdziecie tutaj<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Jako, \u017ce mamy wakacyjny d\u0142ugi weekend w Polsce, dzisiaj znowu mam tylko jeden temat, aczkolwiek my\u015bl\u0119, \u017ce dosy\u0107 ciekawy. Podejrzewam, \u017ce za tydzie\u0144 wr\u00f3cimy ju\u017c sobie do zwyczajnej formu\u0142y, aby jeszcze przynajmniej raz j\u0105 w maju z\u0142ama\u0107&#8230; bo szykuje par\u0119 niespodzianek.<\/p>\n","protected":false},"author":10,"featured_media":18118,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[23,259],"tags":[],"class_list":["post-18097","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-jvm","category-jvm-pl"],"acf":{"estimated_reading_time":"10","feature_image_blog":false,"weekly_summary":true,"push_notification_image":false,"feature_image_visible":false},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber - JVM Weekly vol. 172 - Vived<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/\" \/>\n<meta property=\"og:locale\" content=\"pl_PL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber - JVM Weekly vol. 172 - Vived\" \/>\n<meta property=\"og:description\" content=\"Jako, \u017ce mamy wakacyjny d\u0142ugi weekend w Polsce, dzisiaj znowu mam tylko jeden temat, aczkolwiek my\u015bl\u0119, \u017ce dosy\u0107 ciekawy. Podejrzewam, \u017ce za tydzie\u0144 wr\u00f3cimy ju\u017c sobie do zwyczajnej formu\u0142y, aby jeszcze przynajmniej raz j\u0105 w maju z\u0142ama\u0107... bo szykuje par\u0119 niespodzianek.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/\" \/>\n<meta property=\"og:site_name\" content=\"Vived\" \/>\n<meta property=\"article:published_time\" content=\"2024-05-02T07:12:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-02T07:18:30+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.vived.io\/wp-content\/uploads\/2024\/05\/Group-780-1-1024x560.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"560\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Artur Skowro\u0144ski\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/\"},\"author\":{\"name\":\"Artur Skowro\u0144ski\",\"@id\":\"https:\/\/vived.io\/pl\/#\/schema\/person\/0eb0878110cb27edfbfe46e841fe6db3\"},\"headline\":\"O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber &#8211; JVM Weekly vol. 172\",\"datePublished\":\"2024-05-02T07:12:29+00:00\",\"dateModified\":\"2024-05-02T07:18:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/\"},\"wordCount\":1727,\"publisher\":{\"@id\":\"https:\/\/vived.io\/pl\/#organization\"},\"image\":{\"@id\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/Group-780-1.png\",\"articleSection\":[\"JVM\",\"JVM\"],\"inLanguage\":\"pl-PL\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/\",\"url\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/\",\"name\":\"O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber - JVM Weekly vol. 172 - Vived\",\"isPartOf\":{\"@id\":\"https:\/\/vived.io\/pl\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/Group-780-1.png\",\"datePublished\":\"2024-05-02T07:12:29+00:00\",\"dateModified\":\"2024-05-02T07:18:30+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#breadcrumb\"},\"inLanguage\":\"pl-PL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#primaryimage\",\"url\":\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/Group-780-1.png\",\"contentUrl\":\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/Group-780-1.png\",\"width\":1976,\"height\":1080},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Strona g\u0142\u00f3wna\",\"item\":\"https:\/\/vived.io\/pl\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber &#8211; JVM Weekly vol. 172\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/vived.io\/pl\/#website\",\"url\":\"https:\/\/vived.io\/pl\/\",\"name\":\"Vived\",\"description\":\"platform empowering IT people and technology companies to synergic growth\",\"publisher\":{\"@id\":\"https:\/\/vived.io\/pl\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/vived.io\/pl\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pl-PL\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/vived.io\/pl\/#organization\",\"name\":\"Vived\",\"url\":\"https:\/\/vived.io\/pl\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\/\/vived.io\/pl\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/vived.io\/wp-content\/uploads\/2020\/03\/logo_vived_color.png\",\"contentUrl\":\"https:\/\/vived.io\/wp-content\/uploads\/2020\/03\/logo_vived_color.png\",\"width\":136,\"height\":45,\"caption\":\"Vived\"},\"image\":{\"@id\":\"https:\/\/vived.io\/pl\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/vived.io\/pl\/#\/schema\/person\/0eb0878110cb27edfbfe46e841fe6db3\",\"name\":\"Artur Skowro\u0144ski\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\/\/vived.io\/pl\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/29055786486c8b9dc1507f2744221c5bdb8d7ef6e6217ced0326dd3296aea6ed?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/29055786486c8b9dc1507f2744221c5bdb8d7ef6e6217ced0326dd3296aea6ed?s=96&d=mm&r=g\",\"caption\":\"Artur Skowro\u0144ski\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber - JVM Weekly vol. 172 - Vived","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/","og_locale":"pl_PL","og_type":"article","og_title":"O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber - JVM Weekly vol. 172 - Vived","og_description":"Jako, \u017ce mamy wakacyjny d\u0142ugi weekend w Polsce, dzisiaj znowu mam tylko jeden temat, aczkolwiek my\u015bl\u0119, \u017ce dosy\u0107 ciekawy. Podejrzewam, \u017ce za tydzie\u0144 wr\u00f3cimy ju\u017c sobie do zwyczajnej formu\u0142y, aby jeszcze przynajmniej raz j\u0105 w maju z\u0142ama\u0107... bo szykuje par\u0119 niespodzianek.","og_url":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/","og_site_name":"Vived","article_published_time":"2024-05-02T07:12:29+00:00","article_modified_time":"2024-05-02T07:18:30+00:00","og_image":[{"width":1024,"height":560,"url":"https:\/\/blog.vived.io\/wp-content\/uploads\/2024\/05\/Group-780-1-1024x560.png","type":"image\/png"}],"author":"Artur Skowro\u0144ski","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#article","isPartOf":{"@id":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/"},"author":{"name":"Artur Skowro\u0144ski","@id":"https:\/\/vived.io\/pl\/#\/schema\/person\/0eb0878110cb27edfbfe46e841fe6db3"},"headline":"O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber &#8211; JVM Weekly vol. 172","datePublished":"2024-05-02T07:12:29+00:00","dateModified":"2024-05-02T07:18:30+00:00","mainEntityOfPage":{"@id":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/"},"wordCount":1727,"publisher":{"@id":"https:\/\/vived.io\/pl\/#organization"},"image":{"@id":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#primaryimage"},"thumbnailUrl":"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/Group-780-1.png","articleSection":["JVM","JVM"],"inLanguage":"pl-PL"},{"@type":"WebPage","@id":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/","url":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/","name":"O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber - JVM Weekly vol. 172 - Vived","isPartOf":{"@id":"https:\/\/vived.io\/pl\/#website"},"primaryImageOfPage":{"@id":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#primaryimage"},"image":{"@id":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#primaryimage"},"thumbnailUrl":"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/Group-780-1.png","datePublished":"2024-05-02T07:12:29+00:00","dateModified":"2024-05-02T07:18:30+00:00","breadcrumb":{"@id":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#breadcrumb"},"inLanguage":"pl-PL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/"]}]},{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#primaryimage","url":"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/Group-780-1.png","contentUrl":"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/Group-780-1.png","width":1976,"height":1080},{"@type":"BreadcrumbList","@id":"https:\/\/vived.io\/pl\/o-nowoczesnym-error-handlingu-tez-nie-tylko-w-javie-monady-efekty-i-project-amber-jvm-weekly-vol-172\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Strona g\u0142\u00f3wna","item":"https:\/\/vived.io\/pl\/"},{"@type":"ListItem","position":2,"name":"O nowoczesnym Error Handlingu (te\u017c, nie tylko w Javie): Monady, Efekty i Project Amber &#8211; JVM Weekly vol. 172"}]},{"@type":"WebSite","@id":"https:\/\/vived.io\/pl\/#website","url":"https:\/\/vived.io\/pl\/","name":"Vived","description":"platform empowering IT people and technology companies to synergic growth","publisher":{"@id":"https:\/\/vived.io\/pl\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/vived.io\/pl\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pl-PL"},{"@type":"Organization","@id":"https:\/\/vived.io\/pl\/#organization","name":"Vived","url":"https:\/\/vived.io\/pl\/","logo":{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/vived.io\/pl\/#\/schema\/logo\/image\/","url":"https:\/\/vived.io\/wp-content\/uploads\/2020\/03\/logo_vived_color.png","contentUrl":"https:\/\/vived.io\/wp-content\/uploads\/2020\/03\/logo_vived_color.png","width":136,"height":45,"caption":"Vived"},"image":{"@id":"https:\/\/vived.io\/pl\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/vived.io\/pl\/#\/schema\/person\/0eb0878110cb27edfbfe46e841fe6db3","name":"Artur Skowro\u0144ski","image":{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/vived.io\/pl\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/29055786486c8b9dc1507f2744221c5bdb8d7ef6e6217ced0326dd3296aea6ed?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/29055786486c8b9dc1507f2744221c5bdb8d7ef6e6217ced0326dd3296aea6ed?s=96&d=mm&r=g","caption":"Artur Skowro\u0144ski"}}]}},"blocks_vived":[{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Dzisiaj b\u0119dzie o podej\u015bciach do obs\u0142ugi b\u0142\u0119d\u00f3w - zar\u00f3wno w bran\u017cy jako takiej, jak i nowych propozycjach dla Javy. A wszystko zaczniemy sobie od Monad.<\/p>\n","innerContent":["\n<p>Dzisiaj b\u0119dzie o podej\u015bciach do obs\u0142ugi b\u0142\u0119d\u00f3w - zar\u00f3wno w bran\u017cy jako takiej, jak i nowych propozycjach dla Javy. A wszystko zaczniemy sobie od Monad.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Co to jest Monada? Niekt\u00f3rzy m\u00f3wi\u0105, \u017ce to monoid w kategorii endofunktor\u00f3w, <a href=\"https:\/\/blog.plover.com\/prog\/burritos.html\">co odwa\u017aniejsi \u017ce buritto<\/a>. W uproszczeniu Monada to poj\u0119cie matematyczne, kt\u00f3re s\u0142u\u017cy do modelowania operacji, kt\u00f3re mog\u0105 by\u0107 komponowane sekwencyjnie, wywodz\u0105ce si\u0119 z w teorii kategorii (bardzo ciekawy temat - je\u015bli kiedykolwiek mieli\u015bcie ci\u0105goty do bardziej akademickiego IT, bardzo polecam <a href=\"https:\/\/github.com\/hmemcpy\/milewski-ctfp-pdf\">Category Theory For Programmers<\/a> od Bartosz Milewskiego). W programowaniu funkcyjnym, monady s\u0105 u\u017cywane do obs\u0142ugi efekt\u00f3w ubocznych (jak operacje IO, czy obs\u0142uga b\u0142\u0119d\u00f3w) i struktur danych w spos\u00f3b, kt\u00f3ry pozwala na zwi\u0119z\u0142e i elastyczne zarz\u0105dzanie przep\u0142ywem danych i operacji (ponownie - min. obs\u0142uga b\u0142\u0119d\u00f3w). Powszechnie u\u017cywan\u0105 przez wi\u0119kszo\u015b\u0107 z Was w Javie monad\u0105 jest klasa Optional, b\u0119d\u0105ca sposobem na obs\u0142ug\u0119 obecno\u015bci warto\u015bci lub jej braku. Zasadniczo opakowuje warto\u015b\u0107, kt\u00f3ra mo\u017ce by\u0107 lub nie by\u0107 null, dostarczaj\u0105c metody do bezpiecznego przetwarzania jej bez ryzyka wyst\u0105pienia <code>NullPointerException<\/code>. R\u00f3\u017cnego rodzaju Monad jest bardzo wiele, \u017ceby wymieni\u0107 tutaj cho\u0107by np. Monad\u0119 IO czy Monada Try (kt\u00f3ra jeszcze wr\u00f3ci dzisiaj w naszej opowie\u015bci).<\/p>\n","innerContent":["\n<p>Co to jest Monada? Niekt\u00f3rzy m\u00f3wi\u0105, \u017ce to monoid w kategorii endofunktor\u00f3w, <a href=\"https:\/\/blog.plover.com\/prog\/burritos.html\">co odwa\u017aniejsi \u017ce buritto<\/a>. W uproszczeniu Monada to poj\u0119cie matematyczne, kt\u00f3re s\u0142u\u017cy do modelowania operacji, kt\u00f3re mog\u0105 by\u0107 komponowane sekwencyjnie, wywodz\u0105ce si\u0119 z w teorii kategorii (bardzo ciekawy temat - je\u015bli kiedykolwiek mieli\u015bcie ci\u0105goty do bardziej akademickiego IT, bardzo polecam <a href=\"https:\/\/github.com\/hmemcpy\/milewski-ctfp-pdf\">Category Theory For Programmers<\/a> od Bartosz Milewskiego). W programowaniu funkcyjnym, monady s\u0105 u\u017cywane do obs\u0142ugi efekt\u00f3w ubocznych (jak operacje IO, czy obs\u0142uga b\u0142\u0119d\u00f3w) i struktur danych w spos\u00f3b, kt\u00f3ry pozwala na zwi\u0119z\u0142e i elastyczne zarz\u0105dzanie przep\u0142ywem danych i operacji (ponownie - min. obs\u0142uga b\u0142\u0119d\u00f3w). Powszechnie u\u017cywan\u0105 przez wi\u0119kszo\u015b\u0107 z Was w Javie monad\u0105 jest klasa Optional, b\u0119d\u0105ca sposobem na obs\u0142ug\u0119 obecno\u015bci warto\u015bci lub jej braku. Zasadniczo opakowuje warto\u015b\u0107, kt\u00f3ra mo\u017ce by\u0107 lub nie by\u0107 null, dostarczaj\u0105c metody do bezpiecznego przetwarzania jej bez ryzyka wyst\u0105pienia <code>NullPointerException<\/code>. R\u00f3\u017cnego rodzaju Monad jest bardzo wiele, \u017ceby wymieni\u0107 tutaj cho\u0107by np. Monad\u0119 IO czy Monada Try (kt\u00f3ra jeszcze wr\u00f3ci dzisiaj w naszej opowie\u015bci).<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Przy czym jest to termin, o kt\u00f3rym pisze si\u0119 bardzo trudno, poniewa\u017c jak kiedy\u015b stwierdzi\u0142 znany w \u015brodowisku JavaScriptu <strong>Douglas Crockford<\/strong>:<\/p>\n","innerContent":["\n<p>Przy czym jest to termin, o kt\u00f3rym pisze si\u0119 bardzo trudno, poniewa\u017c jak kiedy\u015b stwierdzi\u0142 znany w \u015brodowisku JavaScriptu <strong>Douglas Crockford<\/strong>:<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/quote","attrs":[],"innerBlocks":[{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>In addition to it begin useful, it is also cursed and the curse of the monad is that once you get the epiphany, once you understand - \"oh that's what it is\" - you lose the ability to explain it to anybody.<\/p>\n","innerContent":["\n<p>In addition to it begin useful, it is also cursed and the curse of the monad is that once you get the epiphany, once you understand - \"oh that's what it is\" - you lose the ability to explain it to anybody.<\/p>\n"]}],"innerHTML":"\n<blockquote class=\"wp-block-quote\"><\/blockquote>\n","innerContent":["\n<blockquote class=\"wp-block-quote\">",null,"<\/blockquote>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/image","attrs":{"id":18102,"sizeSlug":"large","linkDestination":"none"},"innerBlocks":[],"innerHTML":"\n<figure class=\"wp-block-image size-large\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-1024x576.png\" alt=\"\" class=\"wp-image-18102\"\/><\/figure>\n","innerContent":["\n<figure class=\"wp-block-image size-large\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-1024x576.png\" alt=\"\" class=\"wp-image-18102\"\/><\/figure>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Powy\u017csz\u0105 grafik\u0119 ukrad\u0142em z miniaturki pierwszego z naszych dzisiejszego bohatera - filmiku <a href=\"https:\/\/www.youtube.com\/watch?v=GaAe7zGq1zM\">The Death of Monads? Direct Style Algebraic Effects<\/a>, kt\u00f3ry to w wiralowy spos\u00f3b kr\u0105\u017cy ostatnio po r\u00f3\u017cnego rodzaju programistycznych agregatorach i ma kilka ciekawych, kontrowersyjnych opinii - autor twierdzi bowiem \u017ce Monady, mimo \u017ce pot\u0119\u017cne, bywaj\u0105 niezgrabne jako narz\u0119dzie do zarz\u0105dzania efektami ubocznymi w programowaniu funkcyjnym. Film argumentuje, \u017ce bezpo\u015brednie efekty algebraiczne oferuj\u0105 prostsz\u0105 i czystsz\u0105 alternatyw\u0119, aby osi\u0105gn\u0105\u0107 podobne wyniki... i s\u0105 znacznie \u0142atwiejsze do zrozumienia.<\/p>\n","innerContent":["\n<p>Powy\u017csz\u0105 grafik\u0119 ukrad\u0142em z miniaturki pierwszego z naszych dzisiejszego bohatera - filmiku <a href=\"https:\/\/www.youtube.com\/watch?v=GaAe7zGq1zM\">The Death of Monads? Direct Style Algebraic Effects<\/a>, kt\u00f3ry to w wiralowy spos\u00f3b kr\u0105\u017cy ostatnio po r\u00f3\u017cnego rodzaju programistycznych agregatorach i ma kilka ciekawych, kontrowersyjnych opinii - autor twierdzi bowiem \u017ce Monady, mimo \u017ce pot\u0119\u017cne, bywaj\u0105 niezgrabne jako narz\u0119dzie do zarz\u0105dzania efektami ubocznymi w programowaniu funkcyjnym. Film argumentuje, \u017ce bezpo\u015brednie efekty algebraiczne oferuj\u0105 prostsz\u0105 i czystsz\u0105 alternatyw\u0119, aby osi\u0105gn\u0105\u0107 podobne wyniki... i s\u0105 znacznie \u0142atwiejsze do zrozumienia.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Wyobra\u017a sobie, \u017ce pracujesz nad projektem, kt\u00f3ry wymaga korzystania z r\u00f3\u017cnych narz\u0119dzi i zasob\u00f3w, takich jak pliki, po\u0142\u0105czenia z internetem, czy dost\u0119p do bazy danych. Ka\u017cde z tych dzia\u0142a\u0144 wprowadza pewne komplikacje, kt\u00f3re w programowaniu nazywamy \"efektami ubocznymi\". Monady s\u0105 skuteczne w ich obs\u0142udze, ale mog\u0105 te\u017c by\u0107 skomplikowane w u\u017cyciu i zrozumieniu, poniewa\u017c ka\u017cdy krok zwi\u0105zany z efektem ubocznym wymaga dok\u0142adnej obs\u0142ugi.<\/p>\n","innerContent":["\n<p>Wyobra\u017a sobie, \u017ce pracujesz nad projektem, kt\u00f3ry wymaga korzystania z r\u00f3\u017cnych narz\u0119dzi i zasob\u00f3w, takich jak pliki, po\u0142\u0105czenia z internetem, czy dost\u0119p do bazy danych. Ka\u017cde z tych dzia\u0142a\u0144 wprowadza pewne komplikacje, kt\u00f3re w programowaniu nazywamy \"efektami ubocznymi\". Monady s\u0105 skuteczne w ich obs\u0142udze, ale mog\u0105 te\u017c by\u0107 skomplikowane w u\u017cyciu i zrozumieniu, poniewa\u017c ka\u017cdy krok zwi\u0105zany z efektem ubocznym wymaga dok\u0142adnej obs\u0142ugi.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/code","attrs":[],"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-code\"><code>public class MonadExample {\n    public static void main(String&#91;] args) {\n        Optional&lt;String> email = getUserEmail(\"123\");\n\n        \/\/ U\u017cycie monady Optional do przetworzenia warto\u015bci\n        email.ifPresent(System.out::println);\n    }\n}<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-code\"><code>public class MonadExample {\n    public static void main(String&#91;] args) {\n        Optional&lt;String> email = getUserEmail(\"123\");\n\n        \/\/ U\u017cycie monady Optional do przetworzenia warto\u015bci\n        email.ifPresent(System.out::println);\n    }\n}<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Bezpo\u015brednie efekty algebraiczne to nowsze podej\u015bcie, kt\u00f3re pozwala na bardziej zrozumia\u0142e i elastyczne zarz\u0105dzanie efektami ubocznymi. Zamiast otacza\u0107 ka\u017cdy efekt uboczny warstw\u0105 kontroli, jak w przypadku monad, bezpo\u015brednie efekty algebraiczne umo\u017cliwiaj\u0105 ich deklarowanie w bardziej naturalny i czytelny spos\u00f3b.<\/p>\n","innerContent":["\n<p>Bezpo\u015brednie efekty algebraiczne to nowsze podej\u015bcie, kt\u00f3re pozwala na bardziej zrozumia\u0142e i elastyczne zarz\u0105dzanie efektami ubocznymi. Zamiast otacza\u0107 ka\u017cdy efekt uboczny warstw\u0105 kontroli, jak w przypadku monad, bezpo\u015brednie efekty algebraiczne umo\u017cliwiaj\u0105 ich deklarowanie w bardziej naturalny i czytelny spos\u00f3b.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Pracuj\u0105c z bezpo\u015brednimi efektami algebraicznymi, deklarujesz efekty uboczne jako cz\u0119\u015b\u0107 logiki programu, ale ich faktyczne wykonanie jest odroczone do specjalnych funkcji nazywanych \"uchwytami efekt\u00f3w\" (effect handlers). Uchwyty te mo\u017cna dostosowa\u0107 w zale\u017cno\u015bci od kontekstu, na przyk\u0142ad inne uchwyty mog\u0105 by\u0107 u\u017cywane podczas testowania, a inne w produkcji.<\/p>\n","innerContent":["\n<p>Pracuj\u0105c z bezpo\u015brednimi efektami algebraicznymi, deklarujesz efekty uboczne jako cz\u0119\u015b\u0107 logiki programu, ale ich faktyczne wykonanie jest odroczone do specjalnych funkcji nazywanych \"uchwytami efekt\u00f3w\" (effect handlers). Uchwyty te mo\u017cna dostosowa\u0107 w zale\u017cno\u015bci od kontekstu, na przyk\u0142ad inne uchwyty mog\u0105 by\u0107 u\u017cywane podczas testowania, a inne w produkcji.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Pseudo przyk\u0142ad tego, jak ca\u0142o\u015b\u0107 wygl\u0105da po stronie logiki:<\/p>\n","innerContent":["\n<p>Pseudo przyk\u0142ad tego, jak ca\u0142o\u015b\u0107 wygl\u0105da po stronie logiki:<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/code","attrs":[],"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-code\"><code>public class AlgebraicEffectsExample {\n    public static void main(String&#91;] args) {\n        String email = perform(getUserEmail(\"123\"));\n        System.out.println(email);\n    }\n\n    public static String getUserEmail(String userId) throws Effect {\n        User user = findUserById(userId);\n        if (user != null) {\n            return user.getEmail();\n        } else {\n            throw new Effect(\"User not found\");\n        }\n    }\n\n    static class Effect extends Exception {}\n}<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-code\"><code>public class AlgebraicEffectsExample {\n    public static void main(String&#91;] args) {\n        String email = perform(getUserEmail(\"123\"));\n        System.out.println(email);\n    }\n\n    public static String getUserEmail(String userId) throws Effect {\n        User user = findUserById(userId);\n        if (user != null) {\n            return user.getEmail();\n        } else {\n            throw new Effect(\"User not found\");\n        }\n    }\n\n    static class Effect extends Exception {}\n}<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Obs\u0142uga efektu wywo\u0142ywanego w funkcji <code>perform<\/code> m\u00f3g\u0142by by\u0107 obs\u0142u\u017cony w taki spos\u00f3b:<\/p>\n","innerContent":["\n<p>Obs\u0142uga efektu wywo\u0142ywanego w funkcji <code>perform<\/code> m\u00f3g\u0142by by\u0107 obs\u0142u\u017cony w taki spos\u00f3b:<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/code","attrs":[],"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-code\"><code>try {\n    String email = perform(getUserEmail(\"123\"));\n    System.out.println(email);\n} catch (Effect e) {\n    handleEffect(e);\n}\n\npublic static void handleEffect(Effect effect) {\n    if (effect.getMessage().equals(\"User not found\")) {\n        System.out.println(\"No user found with the specified ID.\");\n    } else {\n        System.out.println(\"An unknown error occurred.\");\n    }\n}<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-code\"><code>try {\n    String email = perform(getUserEmail(\"123\"));\n    System.out.println(email);\n} catch (Effect e) {\n    handleEffect(e);\n}\n\npublic static void handleEffect(Effect effect) {\n    if (effect.getMessage().equals(\"User not found\")) {\n        System.out.println(\"No user found with the specified ID.\");\n    } else {\n        System.out.println(\"An unknown error occurred.\");\n    }\n}<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>tylko pami\u0119tajcie, \u017ce poni\u017csze odbywa\u0107 si\u0119 powinno w spos\u00f3b niewidoczny dla u\u017cytkownika, po prostu Java nie umo\u017cliwi implementacji. Niestety, efekty nie s\u0105 czym\u015b, co da si\u0119 \u0142atwo zasymulowa\u0107 i j\u0119zyk musi je wspiera\u0107 :(<\/p>\n","innerContent":["\n<p>tylko pami\u0119tajcie, \u017ce poni\u017csze odbywa\u0107 si\u0119 powinno w spos\u00f3b niewidoczny dla u\u017cytkownika, po prostu Java nie umo\u017cliwi implementacji. Niestety, efekty nie s\u0105 czym\u015b, co da si\u0119 \u0142atwo zasymulowa\u0107 i j\u0119zyk musi je wspiera\u0107 :(<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>To podej\u015bcie sprawia, \u017ce kod staje si\u0119 czystszy i \u0142atwiejszy do zrozumienia, poniewa\u017c oddziela logik\u0119 programu od bezpo\u015bredniej obs\u0142ugi efekt\u00f3w ubocznych. Umo\u017cliwia te\u017c \u0142atwiejsz\u0105 zmian\u0119 i testowanie kodu, poniewa\u017c mo\u017cesz manipulowa\u0107 sposobem obs\u0142ugi efekt\u00f3w bez modyfikacji g\u0142\u00f3wnej logiki programu. Tak jak jednak wspomnia\u0142em, cz\u0119\u015b\u0107 rzeczy jest bardzo trudno zasymulowa\u0107 (zw\u0142aszcza w wygodny spos\u00f3b, nie wydaj\u0105cy si\u0119 by\u0107 sztucznym).<\/p>\n","innerContent":["\n<p>To podej\u015bcie sprawia, \u017ce kod staje si\u0119 czystszy i \u0142atwiejszy do zrozumienia, poniewa\u017c oddziela logik\u0119 programu od bezpo\u015bredniej obs\u0142ugi efekt\u00f3w ubocznych. Umo\u017cliwia te\u017c \u0142atwiejsz\u0105 zmian\u0119 i testowanie kodu, poniewa\u017c mo\u017cesz manipulowa\u0107 sposobem obs\u0142ugi efekt\u00f3w bez modyfikacji g\u0142\u00f3wnej logiki programu. Tak jak jednak wspomnia\u0142em, cz\u0119\u015b\u0107 rzeczy jest bardzo trudno zasymulowa\u0107 (zw\u0142aszcza w wygodny spos\u00f3b, nie wydaj\u0105cy si\u0119 by\u0107 sztucznym).<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Dlatego te\u017c przejdziemy sobie wreszcie do g\u0142\u00f3wnej cz\u0119\u015bci dzisiejszej edycji. Ostatnio pojawi\u0142o si\u0119 bowiem sporo interesuj\u0105cych JEP-\u00f3w (temat, do kt\u00f3rego jeszcze b\u0119d\u0119 wraca\u0107), ale jeden z nich bardzo \u0142adnie wpisuje si\u0119 w temat dzisiejszej edycji. O ile bowiem efekty algebraiczne jeszcze przed nami (cho\u0107 nie da\u0142bym sobie r\u0119ki uci\u0105\u0107, \u017ce kiedy\u015b si\u0119 nie pojawi\u0105), to Tw\u00f3rcy Java na kt\u00f3rym\u015b etapie rozwa\u017cali (i dalej mo\u017ce rozwa\u017caj\u0105) Monad\u0119 <code>Try<\/code>.<\/p>\n","innerContent":["\n<p>Dlatego te\u017c przejdziemy sobie wreszcie do g\u0142\u00f3wnej cz\u0119\u015bci dzisiejszej edycji. Ostatnio pojawi\u0142o si\u0119 bowiem sporo interesuj\u0105cych JEP-\u00f3w (temat, do kt\u00f3rego jeszcze b\u0119d\u0119 wraca\u0107), ale jeden z nich bardzo \u0142adnie wpisuje si\u0119 w temat dzisiejszej edycji. O ile bowiem efekty algebraiczne jeszcze przed nami (cho\u0107 nie da\u0142bym sobie r\u0119ki uci\u0105\u0107, \u017ce kiedy\u015b si\u0119 nie pojawi\u0105), to Tw\u00f3rcy Java na kt\u00f3rym\u015b etapie rozwa\u017cali (i dalej mo\u017ce rozwa\u017caj\u0105) Monad\u0119 <code>Try<\/code>.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/image","attrs":{"id":18105,"sizeSlug":"full","linkDestination":"none","align":"center"},"innerBlocks":[],"innerHTML":"\n<figure class=\"wp-block-image aligncenter size-full\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-1.png\" alt=\"\" class=\"wp-image-18105\"\/><figcaption class=\"wp-element-caption\">Cho\u0107 powy\u017csze nag\u0142\u00f3wki z Reddita r\/java uzna\u0142bym za nieco... hurraoptymistyczne<\/figcaption><\/figure>\n","innerContent":["\n<figure class=\"wp-block-image aligncenter size-full\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-1.png\" alt=\"\" class=\"wp-image-18105\"\/><figcaption class=\"wp-element-caption\">Cho\u0107 powy\u017csze nag\u0142\u00f3wki z Reddita r\/java uzna\u0142bym za nieco... hurraoptymistyczne<\/figcaption><\/figure>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Monada <code>Try<\/code> to struktura w programowaniu funkcyjnym, kt\u00f3ra pomaga w obs\u0142udze operacji, kt\u00f3re mog\u0105 zako\u0144czy\u0107 si\u0119 b\u0142\u0119dem. Otacza ona wykonanie kodu, kt\u00f3re mo\u017ce rzuci\u0107 wyj\u0105tek, i zwraca wynik w formie Success z warto\u015bci\u0105, je\u015bli operacja si\u0119 powiedzie, lub Failure z wyj\u0105tkiem, je\u015bli wyst\u0105pi b\u0142\u0105d. Mo\u017cecie j\u0105 zna\u0107 z biblioteki Vavr:<\/p>\n","innerContent":["\n<p>Monada <code>Try<\/code> to struktura w programowaniu funkcyjnym, kt\u00f3ra pomaga w obs\u0142udze operacji, kt\u00f3re mog\u0105 zako\u0144czy\u0107 si\u0119 b\u0142\u0119dem. Otacza ona wykonanie kodu, kt\u00f3re mo\u017ce rzuci\u0107 wyj\u0105tek, i zwraca wynik w formie Success z warto\u015bci\u0105, je\u015bli operacja si\u0119 powiedzie, lub Failure z wyj\u0105tkiem, je\u015bli wyst\u0105pi b\u0142\u0105d. Mo\u017cecie j\u0105 zna\u0107 z biblioteki Vavr:<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/code","attrs":[],"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-code\"><code>import io.vavr.control.Try;\n\npublic class TryMonadExample {\n    public static void main(String&#91;] args) {\n        Try&lt;Integer> result = Try.of(() -> Integer.parseInt(\"123\"));\n\n        result.map(value -> value * 2)\n              .onSuccess(System.out::println)\n              .onFailure(ex -> System.out.println(\"Error occurred: \" + ex.getMessage()));\n\n        Try&lt;Integer> resultWithFailure = Try.of(() -> Integer.parseInt(\"abc\"));\n        int recoveredValue = resultWithFailure.getOrElse(0);\n    }\n}\n<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-code\"><code>import io.vavr.control.Try;\n\npublic class TryMonadExample {\n    public static void main(String&#91;] args) {\n        Try&lt;Integer> result = Try.of(() -> Integer.parseInt(\"123\"));\n\n        result.map(value -> value * 2)\n              .onSuccess(System.out::println)\n              .onFailure(ex -> System.out.println(\"Error occurred: \" + ex.getMessage()));\n\n        Try&lt;Integer> resultWithFailure = Try.of(() -> Integer.parseInt(\"abc\"));\n        int recoveredValue = resultWithFailure.getOrElse(0);\n    }\n}\n<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Ca\u0142o\u015b\u0107 nie jest jaka\u015b bardzo trudna do zaimplementowania (polecam sobie spr\u00f3bowa\u0107 w formie treningu), ale tak naprawd\u0119 powy\u017csze rozwi\u0105zanie bardzo traci na tym, \u017ce j\u0119zyk nie posiada specjalnych struktur do jej obs\u0142ugi, przez co ca\u0142o\u015b\u0107 jest bardzo \"verbose\". Mo\u017ce si\u0119 jednak okaza\u0107, \u017ce ju\u017c nied\u0142ugo, poniewa\u017c tw\u00f3rcy JDK wraz z rozwojem Pattern Matchingu i ewolucji <code>switch<\/code> szukaj\u0105 dobrego sposobu na obs\u0142ug\u0119 wyj\u0105tk\u00f3w w takowych i jako rozwi\u0105zanie w JEPie <a href=\"https:\/\/bugs.openjdk.org\/browse\/JDK-8323658\">Exception handling in switch (Preview)<\/a>.<\/p>\n","innerContent":["\n<p>Ca\u0142o\u015b\u0107 nie jest jaka\u015b bardzo trudna do zaimplementowania (polecam sobie spr\u00f3bowa\u0107 w formie treningu), ale tak naprawd\u0119 powy\u017csze rozwi\u0105zanie bardzo traci na tym, \u017ce j\u0119zyk nie posiada specjalnych struktur do jej obs\u0142ugi, przez co ca\u0142o\u015b\u0107 jest bardzo \"verbose\". Mo\u017ce si\u0119 jednak okaza\u0107, \u017ce ju\u017c nied\u0142ugo, poniewa\u017c tw\u00f3rcy JDK wraz z rozwojem Pattern Matchingu i ewolucji <code>switch<\/code> szukaj\u0105 dobrego sposobu na obs\u0142ug\u0119 wyj\u0105tk\u00f3w w takowych i jako rozwi\u0105zanie w JEPie <a href=\"https:\/\/bugs.openjdk.org\/browse\/JDK-8323658\">Exception handling in switch (Preview)<\/a>.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Ulepszenie na obs\u0142udze wyj\u0105tk\u00f3w rzucanych przez selektor (czyli <code>e<\/code> w <code>switch (e) ...<\/code>), kt\u00f3re mog\u0105 by\u0107 teraz obs\u0142ugiwane bezpo\u015brednio w bloku <code>switch<\/code>. Zademonstrujmy to poprzez przytoczone u\u017cycie <code>Future.get()<\/code>. Aby obs\u0142u\u017cy\u0107 r\u00f3\u017cne sytuacje, historycznie musieli\u015bmy otacza\u0107 <code>switch<\/code> blokiem try-catch:<\/p>\n","innerContent":["\n<p>Ulepszenie na obs\u0142udze wyj\u0105tk\u00f3w rzucanych przez selektor (czyli <code>e<\/code> w <code>switch (e) ...<\/code>), kt\u00f3re mog\u0105 by\u0107 teraz obs\u0142ugiwane bezpo\u015brednio w bloku <code>switch<\/code>. Zademonstrujmy to poprzez przytoczone u\u017cycie <code>Future.get()<\/code>. Aby obs\u0142u\u017cy\u0107 r\u00f3\u017cne sytuacje, historycznie musieli\u015bmy otacza\u0107 <code>switch<\/code> blokiem try-catch:<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/code","attrs":[],"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-code\"><code><code>Future&lt;Box> f = ...;\n\ntry {\n    switch (f.get()) {\n        case Box(String s) when isGoodString(s) -> score(100);\n        case Box(String s) -> score(50);\n        case null -> score(0);\n    }\n} catch (CancellationException ce) {\n    ...\n} catch (ExecutionException ee) {\n    ...\n} catch (InterruptedException ie) {\n    ...\n}\n<\/code><\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-code\"><code><code>Future&lt;Box> f = ...;\n\ntry {\n    switch (f.get()) {\n        case Box(String s) when isGoodString(s) -> score(100);\n        case Box(String s) -> score(50);\n        case null -> score(0);\n    }\n} catch (CancellationException ce) {\n    ...\n} catch (ExecutionException ee) {\n    ...\n} catch (InterruptedException ie) {\n    ...\n}\n<\/code><\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Wprowadzenie nowego przypadku obs\u0142ugi wyj\u0105tk\u00f3w, zapisywanego jako <code>case throws<\/code>, pozwala na bezpo\u015brednie ich przechwytywanie wewn\u0105trz bloku <code>switch<\/code>, co eliminuje konieczno\u015b\u0107 stosowania zewn\u0119trznego try-catch:<\/p>\n","innerContent":["\n<p>Wprowadzenie nowego przypadku obs\u0142ugi wyj\u0105tk\u00f3w, zapisywanego jako <code>case throws<\/code>, pozwala na bezpo\u015brednie ich przechwytywanie wewn\u0105trz bloku <code>switch<\/code>, co eliminuje konieczno\u015b\u0107 stosowania zewn\u0119trznego try-catch:<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/code","attrs":[],"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-code\"><code>Future&lt;Box&gt; f = ...\nswitch (f.get()) {\n    case Box(String s) when isGoodString(s) -&gt; score(100);\n    case Box(String s)                      -&gt; score(50);\n    case null                               -&gt; score(0);\n    case throws CancellationException ce    -&gt; ...ce...\n    case throws ExecutionException ee       -&gt; ...ee...\n    case throws InterruptedException ie     -&gt; ...ie...\n}\n<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-code\"><code>Future&lt;Box&gt; f = ...\nswitch (f.get()) {\n    case Box(String s) when isGoodString(s) -&gt; score(100);\n    case Box(String s)                      -&gt; score(50);\n    case null                               -&gt; score(0);\n    case throws CancellationException ce    -&gt; ...ce...\n    case throws ExecutionException ee       -&gt; ...ee...\n    case throws InterruptedException ie     -&gt; ...ie...\n}\n<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Wprowadzenie <code>case throws<\/code> (i obs\u0142ugi nulli) pozwala na zastosowanie <code>switch<\/code> jako uniwersalnej maszyny obliczeniowej w kontekstach programowania opartego na wyra\u017ceniach, jak w strumieniach API. Na przyk\u0142ad:<\/p>\n","innerContent":["\n<p>Wprowadzenie <code>case throws<\/code> (i obs\u0142ugi nulli) pozwala na zastosowanie <code>switch<\/code> jako uniwersalnej maszyny obliczeniowej w kontekstach programowania opartego na wyra\u017ceniach, jak w strumieniach API. Na przyk\u0142ad:<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/code","attrs":[],"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-code\"><code>stream.map(Future&lt;Box&gt; f -&gt; switch (f.get()) {\n    case Box(String s) when isGoodString(s) -&gt; score(100);\n    case Box(String s) -&gt; score(50);\n    case null -&gt; score(0);\n    case throws Exception e -&gt; { log(e); return score(0); }\n}).reduce(0, Integer::sum);\n<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-code\"><code>stream.map(Future&lt;Box&gt; f -&gt; switch (f.get()) {\n    case Box(String s) when isGoodString(s) -&gt; score(100);\n    case Box(String s) -&gt; score(50);\n    case null -&gt; score(0);\n    case throws Exception e -&gt; { log(e); return score(0); }\n}).reduce(0, Integer::sum);\n<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Dzi\u0119ki temu podej\u015bciu <code>switch<\/code> mo\u017ce bezpo\u015brednio obs\u0142ugiwa\u0107 zar\u00f3wno warto\u015bci null, jak i r\u00f3\u017cne typy wyj\u0105tk\u00f3w bez dodatkowych klauzul <code>catch<\/code>.<\/p>\n","innerContent":["\n<p>Dzi\u0119ki temu podej\u015bciu <code>switch<\/code> mo\u017ce bezpo\u015brednio obs\u0142ugiwa\u0107 zar\u00f3wno warto\u015bci null, jak i r\u00f3\u017cne typy wyj\u0105tk\u00f3w bez dodatkowych klauzul <code>catch<\/code>.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>No dobra, ale co ma do tego Monada <code>Try<\/code>? Ot\u00f3\u017c na <a href=\"https:\/\/mail.openjdk.org\/pipermail\/amber-spec-experts\/2024-April\/004117.html\">li\u015bcie mailingowej JDK pojawi\u0142a si\u0119 dyskusja na temat dalszej ewolucji tego rozwi\u0105zania<\/a>. Tw\u00f3rcy Javy rozwa\u017cali bowiem wprowadzenie nowych konstrukcji takich jak chainowanie wyj\u0105tk\u00f3w i monady <code>Try<\/code>, jednak opinie na temat ich potrzeby s\u0105 mieszane. Obecnie w Javie stosuje si\u0119 tradycyjne bloki try-catch do zarz\u0105dzania wyj\u0105tkami, co jest proste, ale mo\u017ce by\u0107 uci\u0105\u017cliwe przy u\u017cyciu metod, kt\u00f3re zar\u00f3wno zwracaj\u0105 warto\u015bci, jak i wyrzucaj\u0105 wyj\u0105tki - jak ma to miejsce w opisywanych w tek\u015bcie przypadkach. Jako, \u017ce try catch nie jest wyra\u017ceniem (nie zwraca warto\u015bci) powoduje, \u017ce kod jest mniej komponowalny i bardziej podatny na b\u0142\u0119dy. Propozycja przekszta\u0142cenia try-catch w wyra\u017cenie okaza\u0142a si\u0119 zbyt ograniczona, poniewa\u017c wymaga\u0142a, aby bloki try i catch generowa\u0142y ten sam typ, co zbytnio ogranicza\u0142o mo\u017cliwo\u015bci obs\u0142ugi r\u00f3\u017cnych wynik\u00f3w wyj\u0105tk\u00f3w.<\/p>\n","innerContent":["\n<p>No dobra, ale co ma do tego Monada <code>Try<\/code>? Ot\u00f3\u017c na <a href=\"https:\/\/mail.openjdk.org\/pipermail\/amber-spec-experts\/2024-April\/004117.html\">li\u015bcie mailingowej JDK pojawi\u0142a si\u0119 dyskusja na temat dalszej ewolucji tego rozwi\u0105zania<\/a>. Tw\u00f3rcy Javy rozwa\u017cali bowiem wprowadzenie nowych konstrukcji takich jak chainowanie wyj\u0105tk\u00f3w i monady <code>Try<\/code>, jednak opinie na temat ich potrzeby s\u0105 mieszane. Obecnie w Javie stosuje si\u0119 tradycyjne bloki try-catch do zarz\u0105dzania wyj\u0105tkami, co jest proste, ale mo\u017ce by\u0107 uci\u0105\u017cliwe przy u\u017cyciu metod, kt\u00f3re zar\u00f3wno zwracaj\u0105 warto\u015bci, jak i wyrzucaj\u0105 wyj\u0105tki - jak ma to miejsce w opisywanych w tek\u015bcie przypadkach. Jako, \u017ce try catch nie jest wyra\u017ceniem (nie zwraca warto\u015bci) powoduje, \u017ce kod jest mniej komponowalny i bardziej podatny na b\u0142\u0119dy. Propozycja przekszta\u0142cenia try-catch w wyra\u017cenie okaza\u0142a si\u0119 zbyt ograniczona, poniewa\u017c wymaga\u0142a, aby bloki try i catch generowa\u0142y ten sam typ, co zbytnio ogranicza\u0142o mo\u017cliwo\u015bci obs\u0142ugi r\u00f3\u017cnych wynik\u00f3w wyj\u0105tk\u00f3w.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Z drugiej strony, integracja natywnej monady <code>Try<\/code> mog\u0142aby zaoferowa\u0107 bardziej uniwersalne rozwi\u0105zanie, osadzaj\u0105c wyj\u0105tki w konstrukcie funkcyjnym, kt\u00f3ry m\u00f3g\u0142by by\u0107 przetwarzany w innym miejscu. Pomys\u0142 ten pozwoli\u0142by na operacje takie jak kolejkowanie lub przekazywanie monady Try do przetwarzania w r\u00f3\u017cnych kontekstach, umo\u017cliwiaj\u0105c bardziej jednolite zarz\u0105dzanie wyj\u0105tkami. Jednak\u017ce, pomimo potencjalnych korzy\u015bci, to podej\u015bcie r\u00f3wnie\u017c zosta\u0142o odrzucone, sugeruj\u0105c, \u017ce cho\u0107 Java mog\u0142aby w\u0142\u0105czy\u0107 bardziej zaawansowane konstrukty (takie jak Monada Try z natywn\u0105 obs\u0142ug\u0105 w strukturach j\u0119zyka) czy rozbudowa\u0107 konstrukcje switch-case dla wyj\u0105tk\u00f3w, obecne preferencje sk\u0142aniaj\u0105 si\u0119 ku utrzymaniu lub nieznacznemu udoskonaleniu istniej\u0105cych struktur, zamiast gruntownej przebudowy. Dyskusja wskazuje bowiem na z\u0142o\u017cono\u015b\u0107 i potencjalne ograniczenia wprowadzenia nowych abstrakcji do j\u0119zyka, kt\u00f3re mog\u0142yby zar\u00f3wno poprawi\u0107 obs\u0142ug\u0119 b\u0142\u0119d\u00f3w, jak i jednocze\u015bnie wprowadzi\u0107 nowe wyzwania w zarz\u0105dzaniu wyj\u0105tkami.<\/p>\n","innerContent":["\n<p>Z drugiej strony, integracja natywnej monady <code>Try<\/code> mog\u0142aby zaoferowa\u0107 bardziej uniwersalne rozwi\u0105zanie, osadzaj\u0105c wyj\u0105tki w konstrukcie funkcyjnym, kt\u00f3ry m\u00f3g\u0142by by\u0107 przetwarzany w innym miejscu. Pomys\u0142 ten pozwoli\u0142by na operacje takie jak kolejkowanie lub przekazywanie monady Try do przetwarzania w r\u00f3\u017cnych kontekstach, umo\u017cliwiaj\u0105c bardziej jednolite zarz\u0105dzanie wyj\u0105tkami. Jednak\u017ce, pomimo potencjalnych korzy\u015bci, to podej\u015bcie r\u00f3wnie\u017c zosta\u0142o odrzucone, sugeruj\u0105c, \u017ce cho\u0107 Java mog\u0142aby w\u0142\u0105czy\u0107 bardziej zaawansowane konstrukty (takie jak Monada Try z natywn\u0105 obs\u0142ug\u0105 w strukturach j\u0119zyka) czy rozbudowa\u0107 konstrukcje switch-case dla wyj\u0105tk\u00f3w, obecne preferencje sk\u0142aniaj\u0105 si\u0119 ku utrzymaniu lub nieznacznemu udoskonaleniu istniej\u0105cych struktur, zamiast gruntownej przebudowy. Dyskusja wskazuje bowiem na z\u0142o\u017cono\u015b\u0107 i potencjalne ograniczenia wprowadzenia nowych abstrakcji do j\u0119zyka, kt\u00f3re mog\u0142yby zar\u00f3wno poprawi\u0107 obs\u0142ug\u0119 b\u0142\u0119d\u00f3w, jak i jednocze\u015bnie wprowadzi\u0107 nowe wyzwania w zarz\u0105dzaniu wyj\u0105tkami.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Wszystko jednak ma\u0142ymi kroczkami. Wida\u0107 jednak, \u017ce Pattern Matching pcha ewolucj\u0119 j\u0119zyka do przodu. Ca\u0142\u0105 sytuacje przywo\u0142uje dlatego, \u017ce po raz kolejny pokazuje, jak wa\u017cna jest ewolucja j\u0119zyka... i jak wa\u017cnym dla nas wszystkich jest to, \u017ce jest ona tak starannie przeprowadzana w jednak \"mainstreamowym\" j\u0119zyku jakim jest Java.<\/p>\n","innerContent":["\n<p>Wszystko jednak ma\u0142ymi kroczkami. Wida\u0107 jednak, \u017ce Pattern Matching pcha ewolucj\u0119 j\u0119zyka do przodu. Ca\u0142\u0105 sytuacje przywo\u0142uje dlatego, \u017ce po raz kolejny pokazuje, jak wa\u017cna jest ewolucja j\u0119zyka... i jak wa\u017cnym dla nas wszystkich jest to, \u017ce jest ona tak starannie przeprowadzana w jednak \"mainstreamowym\" j\u0119zyku jakim jest Java.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Mo\u017ce jednak kiedy\u015b Efekty? Loom pod spodem <a href=\"https:\/\/www.infoq.com\/presentations\/continuations-java\/\">wprowadzi\u0142 tak zwane \"delimited continuations\"<\/a> (mechanizm umo\u017cliwiaj\u0105cy kontrol\u0119 nad przep\u0142ywem wykonania programu poprzez zapisywanie, przechowywanie i p\u00f3\u017aniejsze przywracanie okre\u015blonych punkt\u00f3w w kodzie, co pozwala na bardziej elastyczn\u0105 manipulacj\u0119 stosami wywo\u0142a\u0144), a te w <a href=\"https:\/\/blog.poisson.chat\/posts\/2023-01-02-del-cont-examples.html\">Haskellu stanowi\u0105 w\u0142a\u015bnie krok po\u015bredni do wprowadzenia systemu effect\u00f3w<\/a>.<\/p>\n","innerContent":["\n<p>Mo\u017ce jednak kiedy\u015b Efekty? Loom pod spodem <a href=\"https:\/\/www.infoq.com\/presentations\/continuations-java\/\">wprowadzi\u0142 tak zwane \"delimited continuations\"<\/a> (mechanizm umo\u017cliwiaj\u0105cy kontrol\u0119 nad przep\u0142ywem wykonania programu poprzez zapisywanie, przechowywanie i p\u00f3\u017aniejsze przywracanie okre\u015blonych punkt\u00f3w w kodzie, co pozwala na bardziej elastyczn\u0105 manipulacj\u0119 stosami wywo\u0142a\u0144), a te w <a href=\"https:\/\/blog.poisson.chat\/posts\/2023-01-02-del-cont-examples.html\">Haskellu stanowi\u0105 w\u0142a\u015bnie krok po\u015bredni do wprowadzenia systemu effect\u00f3w<\/a>.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/image","attrs":{"id":18116,"sizeSlug":"full","linkDestination":"none","align":"center"},"innerBlocks":[],"innerHTML":"\n<figure class=\"wp-block-image aligncenter size-full\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-4.png\" alt=\"\" class=\"wp-image-18116\"\/><figcaption class=\"wp-element-caption\">Absolutnie nie sugeruje, \u017ceby z Javy zrobi\u0107 Haskella - ja nie z tych. Ale po prostu g\u0142owa mi zabrn\u0119\u0142a w takim dziwnym kierunku.<\/figcaption><\/figure>\n","innerContent":["\n<figure class=\"wp-block-image aligncenter size-full\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-4.png\" alt=\"\" class=\"wp-image-18116\"\/><figcaption class=\"wp-element-caption\">Absolutnie nie sugeruje, \u017ceby z Javy zrobi\u0107 Haskella - ja nie z tych. Ale po prostu g\u0142owa mi zabrn\u0119\u0142a w takim dziwnym kierunku.<\/figcaption><\/figure>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>A je\u015bli spodoba\u0142y Wam si\u0119 tego typu rozwa\u017cania nad r\u00f3\u017cnymi typami i strukturami, to par\u0119 dni temu (idealny timing) ukaza\u0142 si\u0119 artyku\u0142 zatytu\u0142owany <a href=\"https:\/\/ifesunmola.com\/sum-types-in-java\/\">Sum types in Java<\/a> od <a href=\"https:\/\/www.linkedin.com\/in\/ifesunmola\/\">Ife Sunmola<\/a> oferuje wprowadzenie do typ\u00f3w Sumy w Javie (czyli de facto Union types) wraz przyk\u0142adow\u0105 implementacj\u0119, analizuj\u0105c ich przydatno\u015b\u0107 w rozwi\u0105zywaniu typowych problem\u00f3w programistycznych, kt\u00f3re wymagaj\u0105 zarz\u0105dzania r\u00f3\u017cnymi, ale okre\u015blonymi typami. Ot, taka wisienka na torcie.<\/p>\n","innerContent":["\n<p>A je\u015bli spodoba\u0142y Wam si\u0119 tego typu rozwa\u017cania nad r\u00f3\u017cnymi typami i strukturami, to par\u0119 dni temu (idealny timing) ukaza\u0142 si\u0119 artyku\u0142 zatytu\u0142owany <a href=\"https:\/\/ifesunmola.com\/sum-types-in-java\/\">Sum types in Java<\/a> od <a href=\"https:\/\/www.linkedin.com\/in\/ifesunmola\/\">Ife Sunmola<\/a> oferuje wprowadzenie do typ\u00f3w Sumy w Javie (czyli de facto Union types) wraz przyk\u0142adow\u0105 implementacj\u0119, analizuj\u0105c ich przydatno\u015b\u0107 w rozwi\u0105zywaniu typowych problem\u00f3w programistycznych, kt\u00f3re wymagaj\u0105 zarz\u0105dzania r\u00f3\u017cnymi, ale okre\u015blonymi typami. Ot, taka wisienka na torcie.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Mia\u0142o by\u0107 kr\u00f3tko, wysz\u0142o d\u0142ugo - ale mam nadzieje, \u017ce si\u0119 podoba\u0142o.<\/p>\n","innerContent":["\n<p>Mia\u0142o by\u0107 kr\u00f3tko, wysz\u0142o d\u0142ugo - ale mam nadzieje, \u017ce si\u0119 podoba\u0142o.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/separator","attrs":[],"innerBlocks":[],"innerHTML":"\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","innerContent":["\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>PS1: Tak jak obieca\u0142em we wst\u0119pie, za tydzie\u0144 ju\u017c bardziej standardowa edycja. Ale dajcie te\u017c zna\u0107 czy Wam si\u0119 takie jednotematyczne podobaj\u0105, ja si\u0119 przy nich bardzo dobrze bawi\u0119.<\/p>\n","innerContent":["\n<p>PS1: Tak jak obieca\u0142em we wst\u0119pie, za tydzie\u0144 ju\u017c bardziej standardowa edycja. Ale dajcie te\u017c zna\u0107 czy Wam si\u0119 takie jednotematyczne podobaj\u0105, ja si\u0119 przy nich bardzo dobrze bawi\u0119.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>PS: Je\u015bli znacie Polski, zapraszam 9 Maja na konferencje <a href=\"http:\/\/javeloper.pl\">javeloper.pl<\/a>. O godzinie 16 opowiem bowiem podczas niej o GraalVM, a konkretnie Truffle i czym si\u0119 go je (pun intended).<\/p>\n","innerContent":["\n<p>PS: Je\u015bli znacie Polski, zapraszam 9 Maja na konferencje <a href=\"http:\/\/javeloper.pl\">javeloper.pl<\/a>. O godzinie 16 opowiem bowiem podczas niej o GraalVM, a konkretnie Truffle i czym si\u0119 go je (pun intended).<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/image","attrs":{"id":18111,"sizeSlug":"large","linkDestination":"none"},"innerBlocks":[],"innerHTML":"\n<figure class=\"wp-block-image size-large\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-3-1024x574.png\" alt=\"\" class=\"wp-image-18111\"\/><\/figure>\n","innerContent":["\n<figure class=\"wp-block-image size-large\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2024\/05\/image-3-1024x574.png\" alt=\"\" class=\"wp-image-18111\"\/><\/figure>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Jakby kto\u015b jeszcze nie by\u0142 przekonany - <a href=\"https:\/\/www.linkedin.com\/feed\/update\/urn:li:activity:7186730329020239872\/\">slajdy znajdziecie tutaj<\/a>.<\/p>\n","innerContent":["\n<p>Jakby kto\u015b jeszcze nie by\u0142 przekonany - <a href=\"https:\/\/www.linkedin.com\/feed\/update\/urn:li:activity:7186730329020239872\/\">slajdy znajdziecie tutaj<\/a>.<\/p>\n"]}],"_links":{"self":[{"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/posts\/18097","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/comments?post=18097"}],"version-history":[{"count":11,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/posts\/18097\/revisions"}],"predecessor-version":[{"id":18120,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/posts\/18097\/revisions\/18120"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/media\/18118"}],"wp:attachment":[{"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/media?parent=18097"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/categories?post=18097"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/tags?post=18097"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}