From a81c20dc76e5f10b20c7e1481c489d20f6e69985 Mon Sep 17 00:00:00 2001 From: Correl Roush Date: Wed, 3 Apr 2024 22:22:42 -0400 Subject: [PATCH] Merge notes on returns --- 20240401204408-returns.org | 47 ++++++++++++++++++++++++++++++++++-- 20240403221816-returns.org | 49 -------------------------------------- 2 files changed, 45 insertions(+), 51 deletions(-) delete mode 100644 20240403221816-returns.org diff --git a/20240401204408-returns.org b/20240401204408-returns.org index d3e23a1..fec634c 100644 --- a/20240401204408-returns.org +++ b/20240401204408-returns.org @@ -5,8 +5,51 @@ #+title: returns A library for [[id:cda9c620-fec5-4549-b979-22fc06819d77][Python]] providing implementations of various [[id:8ee5037f-0673-4968-9ec4-184bf31dd72d][Monads]]. -* Frustrations -Awaaiting =Future= and =FutureResult= returns =IO= and =IOResult= containers. +* Benefits +** Explicit errors +** Composition +*** Asynchronous composition +* Drawbacks +** Learning curve +** Formatting call chains in YAPF +Call chaining formats poorly in YAPF. Consider the following example which +performs the following steps: +1. Builds a request object +2. Wraps the request object in a Future +3. Binds the request to the HTTP send method +4. Binds the result to a response handler + +The code, formatted by YAPF, looks like this: + +#+begin_src python + return FutureResult.from_result( + self.build_request(request)).bind_async(safe_send).bind_result( + self.load_response) +#+end_src + +The same code, formatted instead by the Black formatter, looks like this: + +#+begin_src python + return ( + FutureResult.from_result(self.build_request(request)) + .bind_async(safe_send) + .bind_result(self.load_response) + ) +#+end_src + +A workaround is to use the =pointfree= module from =returns=, though this comes +with the additional overhead of understanding and using the point-free +functions. +#+begin_src python + return flow( + FutureResult.from_result(self.build_request(request)), + pointfree.bind_async(safe_send), + pointfree.bind_result(self.load_response), + ) +#+end_src + +** Opinionated Future IO +Awaiting =Future= and =FutureResult= returns =IO= and =IOResult= containers. While this makes some sense, it's frustrating that the =IO= wrapping isn't opt-in. While =Future= and =Result= offer the compositional benefits Monads offer to Python code, =IO= as a tool to indicate impure functions/values strikes diff --git a/20240403221816-returns.org b/20240403221816-returns.org deleted file mode 100644 index a30b68c..0000000 --- a/20240403221816-returns.org +++ /dev/null @@ -1,49 +0,0 @@ -:PROPERTIES: -:ID: 4276e1de-1ac5-4e4d-896c-1601e2e61a4e -:END: -#+title: Returns - -A library implementing various [[id:8ee5037f-0673-4968-9ec4-184bf31dd72d][Monads]] in [[id:cda9c620-fec5-4549-b979-22fc06819d77][Python]]. - -* Benefits -** Explicit errors -** Composition -*** Asynchronous composition -* Drawbacks -** Learning curve -** Formatting call chains in YAPF -Call chaining formats poorly in YAPF. Consider the following example which -performs the following steps: -1. Builds a request object -2. Wraps the request object in a Future -3. Binds the request to the HTTP send method -4. Binds the result to a response handler - -The code, formatted by YAPF, looks like this: - -#+begin_src python - return FutureResult.from_result( - self.build_request(request)).bind_async(safe_send).bind_result( - self.load_response) -#+end_src - -The same code, formatted instead by the Black formatter, looks like this: - -#+begin_src python - return ( - FutureResult.from_result(self.build_request(request)) - .bind_async(safe_send) - .bind_result(self.load_response) - ) -#+end_src - -A workaround is to use the =pointfree= module from =returns=, though this comes -with the additional overhead of understanding and using the point-free -functions. -#+begin_src python - return flow( - FutureResult.from_result(self.build_request(request)), - pointfree.bind_async(safe_send), - pointfree.bind_result(self.load_response), - ) -#+end_src