<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jacek Złydach</title>
    <description>The latest articles on DEV Community by Jacek Złydach (@temporal).</description>
    <link>https://dev.to/temporal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F123484%2F6ddcc2e3-239c-4975-82f3-10498a9a8846.png</url>
      <title>DEV Community: Jacek Złydach</title>
      <link>https://dev.to/temporal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/temporal"/>
    <language>en</language>
    <item>
      <title>Static local variables in Common Lisp</title>
      <dc:creator>Jacek Złydach</dc:creator>
      <pubDate>Fri, 10 Jan 2020 23:31:12 +0000</pubDate>
      <link>https://dev.to/temporal/static-local-variables-in-common-lisp-3dm6</link>
      <guid>https://dev.to/temporal/static-local-variables-in-common-lisp-3dm6</guid>
      <description>&lt;p&gt;Static local variables are variables with &lt;a href="https://en.wikipedia.org/wiki/Variable_(computer_science)#Scope_and_extent"&gt;local scope and indefinite extent&lt;/a&gt;.&lt;br&gt;
That means, they're accessible only within a specific block of instructions, as if they were regular local variables,&lt;br&gt;
but otherwise they behave like global variables - their memory is allocated just once, and they exist for as long as&lt;br&gt;
they're accessible by the program, retaining their value between subsequent executions of the code that created them.&lt;br&gt;
You may recognize this concept from C/C++:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int test_function() {
  static int counter = 0;
  return counter++;
}

//test:
test_function(); // -&amp;gt; 0
test_function(); // -&amp;gt; 1
test_function(); // -&amp;gt; 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Static local variables are rarely used, and are becoming increasingly absent in modern programming languages. And for good reasons.&lt;br&gt;
Such variables share the downsides of global variables - they introduce additional hidden state and make the code dangerous to use in&lt;br&gt;
multi-threaded programs. At the same time, they also create another downside: they're lexically scoped to the block of code they're declared in,&lt;br&gt;
meaning they're invisible to the outside world. While a global variable could be explicitly made a part of some module's interface,&lt;br&gt;
a static local variable can't be; it's invisible.&lt;/p&gt;

&lt;p&gt;So why did I seek a way to implement them in Common Lisp? It turns out that despite their drawbacks, they're sometimes very useful.&lt;br&gt;
One of such cases is when you want to minimize the number of memory allocations your code does, without impacting its readability.&lt;br&gt;
This is important for writing high-performance software, like video games (and this is where I encountered my own need for these variables).&lt;br&gt;
Static local variables allow a block of code to preallocate its temporary buffers once, avoiding the penalty of repeated reallocation.&lt;br&gt;
Consider:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defun process-data ()
  (some-level
   (of-processing
    ;;  ...

    (static-let ((query-results (make-array 40000 :element-type 'double-float :fill-pointer 0)))
      (run-a-query "[... some query data ...]" :into query-results)
      (process-results query-results))

    ;; more code
    )))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;STATIC-LET&lt;/code&gt; in the code above allocates a &lt;code&gt;QUERY-RESULTS&lt;/code&gt; buffer when the function &lt;code&gt;PROCESS-DATA&lt;/code&gt; is first executed; subsequent calls to &lt;code&gt;PROCESS-DATA&lt;/code&gt;&lt;br&gt;
will not allocate this memory again, making the code effectively non-consing (i.e. not allocating memory).&lt;/p&gt;

&lt;p&gt;Why do it this way, instead of using a global variable (or perhaps a class-scoped slot when writing a method)? Because it keeps the declaration&lt;br&gt;
and initialization close to the code that's using it. The variable is still lexically scoped - code outside of &lt;code&gt;STATIC-LET&lt;/code&gt; can't get to it,&lt;br&gt;
which partially mitigates the issue of hidden state (in fact, when not used in multi-threaded context, this code would still technically&lt;br&gt;
count as functional programming).&lt;/p&gt;

&lt;p&gt;What about the magic &lt;code&gt;40000&lt;/code&gt;? Is it wise to allocate buffers of predetermined size? The answer is, in performance-critical code, absolutely.&lt;br&gt;
Memory is always finite and most software cannot recover when it runs out. Making buffer size explicit is actually the safer choice,&lt;br&gt;
because it forces you to write your code so that it either stays in fixed bounds or gracefully handles memory outage, giving you predictable&lt;br&gt;
memory usage patterns.&lt;/p&gt;

&lt;p&gt;After this lengthy introduction, let's look at how you can make static local variables in Common Lisp.&lt;/p&gt;

&lt;h1&gt;
  
  
  The implementation
&lt;/h1&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defmacro static-let (vars &amp;amp;body body)
  "Like `LET', but makes `VARS' static (in C language sense).

A static variable is like a global lexical variable, but accessible only within the scope
of the `BODY' form, and it retains value between executions of the `BODY' form. Initial
value of each binding is evaluated only once, the first time `BODY' is executed.

The macro supports optional type declarations; instead of usual binding form
`(VAR-NAME INITALIZER)', use `(VAR-NAME TYPE INITALIZER)' to get automatic type declarations.

Be careful with this macro, as it creates a new set of static variables each time it's expanded.
This macro is not thread safe. Also, avoid recursive execution of `BODY'.
If a static variable is initialized or set to `NIL', it will be reinitialized the next time
`BODY' is executed."
  (loop
     for entry in vars
     for name = (if (consp entry) (car entry) entry)
     for type = (when (and (consp entry)
                           (caddr entry))
                  (cadr entry))
     for initform = (when (consp entry)
                      (or (caddr entry)
                          (cadr entry)))
     for sym = (gensym (string name))
     collect `(,sym (load-time-value (list nil))) into letforms
     if type
     collect `(type ,type ,name) into declforms
     collect `(unless (car ,sym) (setf (car ,sym) ,initform)) into initforms
     collect `(,name (car ,sym)) into macroletforms
     finally
       (return
         `(let ,letforms
            ,@initforms
            (symbol-macrolet ,macroletforms
              ,@(if declforms
                    `((declare ,@declforms)))
              ,@body)))))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It's a relatively simple macro, though it may take a bit to parse. Like a proper &lt;code&gt;LET&lt;/code&gt;-style macro, it supports defining multiple&lt;br&gt;
lexical variables in one block and initialize them with values. As a bonus, the variable form may also look like &lt;code&gt;(NAME TYPE INITIAL-VALUE)&lt;/code&gt;,&lt;br&gt;
which allows me to provide type declarations for the variables in the same place (I tend to like my Lisp thoroughly typed).&lt;/p&gt;

&lt;p&gt;Here's an example macroexpansion:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(macroexpand-1 '(static-let ((test-array (make-array 40000 :element-type 'double-float)))
                 (setf (aref test-array 0) 42)))

;;; =&amp;gt;

(LET ((#:TEST-ARRAY730 (LOAD-TIME-VALUE (LIST NIL))))
  (UNLESS (CAR #:TEST-ARRAY730)
    (SETF (CAR #:TEST-ARRAY730)
            (MAKE-ARRAY 40000 :ELEMENT-TYPE 'DOUBLE-FLOAT)))
  (SYMBOL-MACROLET ((TEST-ARRAY (CAR #:TEST-ARRAY730)))
    (SETF (AREF TEST-ARRAY 0) 42)))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The magic which allows to create a static variable is contained in the &lt;code&gt;LOAD-TIME-VALUE&lt;/code&gt; form. Quoting the HyperSpec,&lt;br&gt;
"load-time-value provides a mechanism for delaying evaluation of form until the expression is in the run-time environment; (…)&lt;br&gt;
with the &lt;em&gt;result of this evaluation then being treated as a literal object&lt;/em&gt; at run time" (emphasis mine, see &lt;a href="http://clhs.lisp.se/Body/s_ld_tim.htm"&gt;full documentation&lt;/a&gt; for context).&lt;/p&gt;

&lt;p&gt;Key words here are "literal object". Literal objects are usually ones you type directly in the source code, like a &lt;code&gt;"string literal"&lt;/code&gt;, or&lt;br&gt;
&lt;code&gt;'(a quoted form)&lt;/code&gt;. The details of handling such objects are &lt;a href="http://clhs.lisp.se/Body/03_bd.htm"&gt;a bit complicated&lt;/a&gt;, but for this purpose, it's sufficient&lt;br&gt;
to say that at some point before the code is executed, literal objects are instantiated, and from that point on, any place in the source code that refers to&lt;br&gt;
such a literal now refers to the particular instance of it. So, from the point of view of the Lisp runtime, before the above macroexpansion is executed,&lt;br&gt;
&lt;code&gt;(LOAD-TIME-VALUE (LIST NIL)&lt;/code&gt; has already been replaced by a reference to a particular empty cons cell. This cons cell is our static local variable.&lt;/p&gt;

&lt;p&gt;The rest of the macroexpansion executes normally. There's a test that guards the code setting the &lt;code&gt;CAR&lt;/code&gt; of the cons cell to the result of initialization form for our static&lt;br&gt;
variable, which ensures that the initialization happens the first time control flows through this block of code. Then, there's a &lt;code&gt;SYMBOL-MACROLET&lt;/code&gt; that ensures our&lt;br&gt;
variable is accessible for both reading and writing under the name given to it in &lt;code&gt;STATIC-LET&lt;/code&gt; form (this is the standard Common Lisp idiom for when you want to&lt;br&gt;
make a bit of code present itself as if it was just a variable).&lt;/p&gt;

&lt;p&gt;Why the empty cons cell, you may ask? Why not put the initialization form into the &lt;code&gt;LOAD-TIME-VALUE&lt;/code&gt; directly? The reason is, the evaluation of that form happens&lt;br&gt;
well before runtime, so if you compile the file (with a &lt;code&gt;COMPILE-FILE&lt;/code&gt; call), the actual result of the initialization form may end up encoded in the compiled file.&lt;br&gt;
In our example above, that would be 320KB worth of floats, and in practice this may easily run into hundreds of megabytes of data that will end up&lt;br&gt;
stored in the compiled file (or dumped Lisp image). So instead, &lt;code&gt;STATIC-LET&lt;/code&gt; only allocates an empty cons cell, a minimal literal object that can&lt;br&gt;
store a reference to the data initialize at runtime.&lt;/p&gt;

&lt;p&gt;(When delivering executables, one must remember to never call the functions using &lt;code&gt;STATIC-LET&lt;/code&gt; before dumping the Lisp image; otherwise, the initialized data&lt;br&gt;
will end up being stored in the image file in full form. Also note that this implementation has one caveat: if, at any point, the variable is set to &lt;code&gt;NIL&lt;/code&gt;,&lt;br&gt;
it will be reinitialized the next time control goes through &lt;code&gt;STATIC-LET&lt;/code&gt;. This behavior deviates from what C/C++ does, and it could be corrected with little extra&lt;br&gt;
work, but I deemed it not worth it.)&lt;/p&gt;

&lt;p&gt;Let's verify &lt;code&gt;STATIC-LET&lt;/code&gt; works as described:&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defun test-static-let ()&lt;br&gt;
  (format t "~&amp;amp;Executing test.")&lt;br&gt;
  (static-let ((test-counter (progn (format t "~&amp;amp;Allocating counter.")&lt;br&gt;
                                    0))&lt;br&gt;
               (test-array (progn (format t "~&amp;amp;Allocating array.")&lt;br&gt;
                                  (make-array 40000 :element-type 'double-float))))&lt;br&gt;
    (incf test-counter)&lt;br&gt;
    (incf (aref test-array 0))&lt;br&gt;
    (format t "~&amp;amp;Counter: ~A, array's first element: ~A" test-counter (aref test-array 0)))&lt;br&gt;
  (format t "~&amp;amp;Test done."))

&lt;p&gt;(loop&lt;br&gt;
   repeat 3&lt;br&gt;
   do&lt;br&gt;
     (test-static-let))&lt;/p&gt;

&lt;p&gt;Executing test.&lt;br&gt;
Allocating counter.&lt;br&gt;
Allocating array.&lt;br&gt;
Counter: 1, array's first element: 1.0d0&lt;br&gt;
Test done.&lt;br&gt;
Executing test.&lt;br&gt;
Counter: 2, array's first element: 2.0d0&lt;br&gt;
Test done.&lt;br&gt;
Executing test.&lt;br&gt;
Counter: 3, array's first element: 3.0d0&lt;br&gt;
Test done.&lt;br&gt;
&lt;/p&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Alternative approaches&lt;br&gt;
&lt;/h1&gt;

&lt;p&gt;Hanging the static variable off a cons cell allocated by &lt;code&gt;LOAD-TIME-VALUE&lt;/code&gt; is what I found to be the best way to implement it, but it's not the only way.&lt;br&gt;
Alternative approaches include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  redefining the entire function using static variables as closure, with static variables being regular lexical variables over which that function closes;&lt;/li&gt;
&lt;li&gt;  keeping a global hash table for "static" variables, and using unique symbols (generated by &lt;code&gt;GENSYM&lt;/code&gt;) as keys;&lt;/li&gt;
&lt;li&gt;  creating each such variable as &lt;code&gt;DEFVAR&lt;/code&gt;, with an unique name generated by &lt;code&gt;GENSYM&lt;/code&gt; (an approach taken by &lt;a href="https://github.com/y2q-actionman/with-c-syntax"&gt;with-c-syntax&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;  attaching the variable into the property list of a symbol generated by &lt;code&gt;GENSYM&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these approaches have certain drawbacks. The closure approach requires change to the very function definition (a macro can't just hoist&lt;br&gt;
the code it generates into the surrounding context). Global hash table, magic defvars and property lists all are technically accessible&lt;br&gt;
from the outside, and come with small performance penalties. Overall, despite the caveat with &lt;code&gt;NIL&lt;/code&gt; values (which is entirely due to my&lt;br&gt;
&lt;del&gt;laziness&lt;/del&gt; &lt;span class="underline"&gt;thoughtful engineering decision&lt;/span&gt;), I prefer the &lt;code&gt;LOAD-TIME-VALUE&lt;/code&gt; approach.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>performance</category>
      <category>commonlisp</category>
      <category>lisp</category>
    </item>
    <item>
      <title>Algebraic Effects - You Can Touch This!</title>
      <dc:creator>Jacek Złydach</dc:creator>
      <pubDate>Wed, 24 Jul 2019 12:20:00 +0000</pubDate>
      <link>https://dev.to/temporal/algebraic-effects-you-can-touch-this-1nb7</link>
      <guid>https://dev.to/temporal/algebraic-effects-you-can-touch-this-1nb7</guid>
      <description>&lt;p&gt;An &lt;a href="https://overreacted.io/algebraic-effects-for-the-rest-of-us/"&gt;article by Dan Abramov&lt;/a&gt; (of &lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt; fame) has been &lt;a href="https://news.ycombinator.com/item?id=20496043"&gt;making rounds today&lt;/a&gt; on the Internet. It introduces readers to a body of theoretical work called "algebraic effects", providing an overview and a set of examples of how these ideas could be implemented in hypothetical extension to JavaScript.&lt;/p&gt;

&lt;p&gt;What jumped at me in this article were two things. First, that the article claims this field of work is still theoretical, "only supported by a few languages that were created specifically to explore that idea" and definitely not production-ready. Second, that I've seen code like the article's examples before - in fact, I write similar code frequently, both in professional and hobby settings. The presented examples are a JavaScript pseudocode version of the &lt;strong&gt;Common Lisp's conditions and restarts system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To be completely honest: I'm not familiar with the body of work under the name of "algebraic effects", though I've learned it has a larger scope than what's described here and in the original article (see remarks at the end of this post). However, Dan's article describes a subset that's in actual, practical use, so this is what this article focuses on.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conditions and Restarts
&lt;/h1&gt;

&lt;p&gt;Conditions and restarts are kind of like try/throw exception handling you know from more mainstream languages, except much more powerful. It's not meant for just handling errors, but any kind of flow, in which some communication up and down the call stack must occur.&lt;/p&gt;

&lt;p&gt;To quote from an &lt;a href="http://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html"&gt;excellent introduction in &lt;em&gt;Practical Common Lisp&lt;/em&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The condition system is more flexible than exception systems because instead of providing a two-part division between the code that signals an error and the code that handles it, the condition system splits the responsibilities into three parts--&lt;em&gt;signaling&lt;/em&gt; a condition, &lt;em&gt;handling&lt;/em&gt; it, and &lt;em&gt;restarting&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;(…) you could use the condition system to allow a low-level function to detect a problem while parsing a log file and signal an error, to allow mid-level code to provide several possible ways of recovering from such an error, and to allow code at the highest level of the application to define a policy for choosing which recovery strategy to use.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I won't try to summarize PCL here, but I want to introduce some vocabulary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;condition&lt;/strong&gt; - is an object that represents some "situation" - i.e. something of note that's happened, but not necessarily an error&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;signal&lt;/strong&gt; - quoting &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm"&gt;from CLHS&lt;/a&gt;, "v. to announce, using a standard protocol, that a particular situation, represented by a &lt;em&gt;condition&lt;/em&gt;, has been detected"&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;handler&lt;/strong&gt; - a function that receives a &lt;em&gt;condition&lt;/em&gt;, and can somehow handle it (e.g. by invoking a &lt;em&gt;restart&lt;/em&gt;), or decline and just pass the &lt;em&gt;condition&lt;/em&gt; on&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;restart&lt;/strong&gt; - &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_rst.htm#restart"&gt;quoting again&lt;/a&gt;, "represents a function that can be called to perform some form of recovery action"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Outside of Lisp, conditions are usually known as exception objects, signaling is done by &lt;code&gt;throw&lt;/code&gt;, and restarts and handlers are bundled together as &lt;code&gt;catch&lt;/code&gt; &amp;amp; &lt;code&gt;finally&lt;/code&gt; blocks.&lt;/p&gt;

&lt;p&gt;For more details, head on to the PCL chapter I linked above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error handling example
&lt;/h2&gt;

&lt;p&gt;I'm not going to repeat the original article here; it's really worth a read anyway. What I'll do instead is show you how the example from would be done in Common Lisp, where it's not pseudocode but a real, fully supported, ANSI-standardized feature.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;;;; Bookkeeping, to make the example compile and run.
(define-condition ask-for-name () ()
  (:documentation "A mock condition that means a name needs to be provided."))

(defun name (user)
  "Reader for name of `USER'."
  (car user))

(defun friend-names (user)
  "Reader for a list of names of friends of `USER'."
  (cdr user))

(defun (setf friend-names) (new-value user)
  "Setter for `FRIEND-NAMES'."
  (setf (cdr user) new-value))

;;; A helper macro wrapping an idiom allowing to do a test and request a new value if test fails.
(defmacro ensure (test place condition)
  "If the `TEST' fails, signal a `CONDITION', with a restart `USE-VALUE' ready for a new value."
  `(restart-case
       (unless ,test
         (signal ,condition))
     (use-value (new-value)
       (setf ,place new-value))))

;;; Implementation of the first example from the original article
(defun get-name (user)
  (let ((name (name user)))
    (ensure (not (null name)) ;Just NAME would suffice, but spelling it out for clarity.
      name
      'ask-for-name)
    name))

(defun make-friends (user-1 user-2)
  (push (get-name user-2) (friend-names user-1))
  (push (get-name user-1) (friend-names user-2)))

(let ((ricky (cons nil nil))
      (bubbles (cons "Bubbles" nil)))
  (handler-bind ((ask-for-name (lambda (c) (use-value "Ricky" c))))
    (make-friends ricky bubbles)
    ;; Let's return the two objects for the sake of REPL output.
    (list ricky bubbles)))

    ;;; REPL output:
    ((NIL "Bubbles") ("Bubbles" "Ricky"))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The part:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;perform&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ask name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;is implemented by the &lt;code&gt;ensure&lt;/code&gt; form, which performs the test and ensures a restart named &lt;code&gt;use-value&lt;/code&gt; is in place to externally set the value of a passed place (e.g. variable). This small utility essentially works as a simplified Common Lisp's &lt;code&gt;assert&lt;/code&gt; macro, except the latter forces you to specify the new value(s) interactively (in fact, you could rewrite this code to work with Lisp's interactive debugger by changing &lt;code&gt;ensure&lt;/code&gt; to &lt;code&gt;assert&lt;/code&gt;, and &lt;code&gt;(use-value "Ricky" c)&lt;/code&gt; to &lt;code&gt;(continue c)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;handle (effect) { ... }&lt;/code&gt; part is entirely handled by &lt;code&gt;handler-bind&lt;/code&gt; Common Lisp &lt;a href="http://clhs.lisp.se/Body/m_handle.htm"&gt;form&lt;/a&gt; - its job is to bind functions to handle particular signals coming from the code it encloses. You can see it matches &lt;code&gt;ask-for-name&lt;/code&gt; condition we've defined earlier, and to handle it, it calls &lt;code&gt;use-value&lt;/code&gt;. &lt;code&gt;use-value&lt;/code&gt; is a Common Lisp built-in for invoking a restart named &lt;code&gt;use-value&lt;/code&gt; (it's not an uncommon thing to do), but if such a built-in wasn't provided, you'd rewrite the handler-bind as follows:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(handler-bind ((ask-for-name (lambda (c)
                               (let ((restart (find-restart 'use-value c)))
                                 (when restart
                                   (invoke-restart restart "Ricky"))))))
  (make-friends ricky bubbles)
  ;; Let's return the two objects for the sake of REPL output.
  (list ricky bubbles))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That is, you can find and invoke programmatically any restart that was installed when the condition was signaled. Common Lisp just provides a shorthand, functional interface to common restarts &lt;code&gt;abort&lt;/code&gt;, &lt;code&gt;continue&lt;/code&gt;, &lt;code&gt;muffle-warning&lt;/code&gt;, &lt;code&gt;store-value&lt;/code&gt;, and &lt;code&gt;use-value&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond errors
&lt;/h2&gt;

&lt;p&gt;As said before, conditions/restarts system can be used for more than just an error handling. The second example from the article demonstrates something that's essentially dynamic binding for function names, which can be done in Common Lisp in a different way (and arguably should), albeit with some work. Clojure - another Lisp - provides a nice built-in tool for that: &lt;a href="https://clojuredocs.org/clojure.core/with-redefs-fn"&gt;with-redefs-fn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So instead, let me describe an &lt;a href="https://news.ycombinator.com/item?id=20513136"&gt;example I initially posted on HN&lt;/a&gt;, of how you can use conditions and restarts to implement progress reporting and aborting of a long-running calculation, possibly in interactive / GUI context.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(define-condition progress ()
  ((amount :initarg :amount
           :reader amount
           :documentation "How done is the operation, [0..1]."))
  (:documentation "A condition signaled by long operations that report progress."))

(defun process-partial-data (data)
  (declare (ignore data))
  ;; Some data processing here.
  )

(defun process-data (data)
  (restart-case
      ;; Main flow
      (loop
         ;; Report that we've started
         initially
           (signal 'progress :amount 0)

         ;; Perform the data processing
         with total = (length data)
         for datum in data
         for i below total
         do
           (process-partial-data datum)
           (signal 'progress :amount (/ i total))

         ;; Report that we're done
         finally
           (signal 'progress :amount 1)
           (return :done))
    ;; Restart flow
    (abort-work ()
      (format *trace-output* "Aborting work!")
      :failed)))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The "business meat" of our function is the loop form. You'll notice it reports its progress by signaling a &lt;code&gt;progress&lt;/code&gt; condition which, without installed handlers, is essentially a no-op (unlike throwing an exception). The "meat" is wrapped in &lt;code&gt;restart-case&lt;/code&gt; form, in order to provide an alternative flow called &lt;code&gt;abort-work&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's look at some REPL session logs (&lt;code&gt;-&amp;gt;&lt;/code&gt; denotes returned result, to differentiate it from printed output). First, regular use:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CL-USER&amp;gt; (process-data '(1 2 3 4 5 6))
-&amp;gt; :DONE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let's simulate a GUI progress bar, by actually listening to the &lt;code&gt;progress&lt;/code&gt; condition:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CL-USER&amp;gt; (handler-bind ((progress (lambda (p) (format *trace-output* "~&amp;amp;Progress: ~F~%" (amount p)))))
           (process-data '(1 2 3 4 5 6)))

Progress: 0.0
Progress: 0.0
Progress: 0.16666667
Progress: 0.33333334
Progress: 0.5
Progress: 0.6666667
Progress: 0.8333333
Progress: 1.0
-&amp;gt; :DONE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let's simulate user pressing a "Cancel" button by assuming that it was clicked around the 50% progress mark. We can do that through invoking the &lt;code&gt;abort-work&lt;/code&gt; restart programmatically:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CL-USER&amp;gt; (handler-bind ((progress (lambda (p) (format *trace-output* "~&amp;amp;Progress: ~F~%" (amount p))
                                                (when (&amp;gt;= (amount p) 0.5)
                                                  (invoke-restart 'abort-work)))))
             (process-data '(1 2 3 4 5 6)))
Progress: 0.0
Progress: 0.0
Progress: 0.16666667
Progress: 0.33333334
Progress: 0.5
Aborting work!
-&amp;gt; :FAILED
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As &lt;a href="https://news.ycombinator.com/item?id=20515543"&gt;pointed out&lt;/a&gt; under my original example, in real use you'd want to hide this mechanism under a macro. It's fairy easy to write one, for instance:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defmacro dolist-with-progress-noted ((datum data return) (&amp;amp;key on-abort) &amp;amp;body body)
  (alexandria:once-only (data)
    (alexandria:with-gensyms (total i)
      `(restart-case
           (loop
              initially
                (signal 'progress :amount 0)

              with ,total = (length ,data)
              for ,datum in ,data
              for ,i below ,total
              do
                ,@body
                (signal 'progress :amount (/ ,i ,total))

              finally
                (signal 'progress :amount 1)
                (return ,return))
         (abort-work ()
           ,on-abort)))))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now the following code expands to the original example above:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defun process-data (data)
  (dolist-with-progress-noted (datum data :done)
      (:on-abort (progn (format *trace-output* "Aborting work!") :failed))
    (process-partial-data datum)))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Parting thoughts
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://news.ycombinator.com/item?id=20513370"&gt;On HN thread it's been pointed out&lt;/a&gt; that algebraic effects as a concept is larger than what Common Lisp can support. So it might be; I don't know much about the scope of the theoretical work there. The missing ingredient is implied to be "continuations", which are not supported in Common Lisp. However, &lt;a href="https://en.wikipedia.org/wiki/Scheme_(programming_language)"&gt;Scheme&lt;/a&gt; family of Lisps &lt;strong&gt;has&lt;/strong&gt; continuations. And apparently &lt;a href="https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Error-System.html#Error-System"&gt;conditions&lt;/a&gt;. In the highest of Lisp traditions, they should be able to incorporate whatever other clever ideas come out of algebraic effects work.&lt;/p&gt;

&lt;p&gt;So, it turns out, you absolutely &lt;em&gt;can&lt;/em&gt; touch this, and could for the past 30+ years (&lt;a href="https://news.ycombinator.com/item?id=20514404"&gt;or more&lt;/a&gt;), in a production-ready environment. I'm happy to see the JavaScript community rediscovering forgotten techniques of the programming art, but before people jump to writing their own DSLs for the JS transpilers, I implore you - please at least take a look at how it has all been done successfully in practical languages, and heed the lessons their communities learned.&lt;/p&gt;

&lt;p&gt;(Originally published on &lt;a href="http://jacek.zlydach.pl/blog/2019-07-24-algebraic-effects-you-can-touch-this.html"&gt;my blog&lt;/a&gt;. Who do I ask to get dev.to to enable syntax highlighting for Common Lisp code?)&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>commonlisp</category>
      <category>lisp</category>
    </item>
  </channel>
</rss>
