~technomancy/fennel

Propagate error messages in -?> and -??> macros. v1 REJECTED

Phil Hagelberg: 1
 Propagate error messages in -?> and -??> macros.

 3 files changed, 11 insertions(+), 6 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~technomancy/fennel/patches/21426/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] Propagate error messages in -?> and -??> macros. Export this patch

This changes the nil-safe threading macros to be more useful in chains
involving functions which use the nil,msg pattern to indicate an
error. For instance, previously this would have only printed nil, but
now it prints nil along with the error message.
    (fn e [x]
      (values nil "oh no"))

    (fn f2 []
      (error "this never runs"))

    (print (-?> "/tmp/hi"
                (io.open :w)
                (: :write "whaaaat up")
                (e)
                (f2))) ;; -> nil	oh no

There is some risk that this will cause incompatibilities in cases
where code currently assumes that these macros will return only a
single value. However, I believe their increased utility for error
handling outweighs this downside.
---
 changelog.md          |  1 +
 reference.md          |  4 ++++
 src/fennel/macros.fnl | 12 ++++++------
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/changelog.md b/changelog.md
index 542491a..9ae7e26 100644
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,7 @@

## 0.9.0 / ???

* Return the second value when ending a `-?>` or `-?>>` chain early
* Support `&as` inside pattern matches
* Include stack trace for errors during macroexpansion
* The `sym` function in compile scope now takes a source table second argument
diff --git a/reference.md b/reference.md
index 4615634..b7c46fb 100644
--- a/reference.md
+++ b/reference.md
@@ -909,6 +909,10 @@ the checks in `-?>` and `-?>>` prevent the same from happening there
without performance overhead, so these pipelines are limited to a
single value.

However, when a chain ends early due to one step returning false or nil,
the entire form will return two values, since usually this means that
the second value is an error message.

> Note that these have nothing to do with "threads" used for
> concurrency; they are named after the thread which is used in
> sewing. This is similar to the way that `|>` works in OCaml and Elixir.
diff --git a/src/fennel/macros.fnl b/src/fennel/macros.fnl
index 76fc7ce..dcfd231 100644
--- a/src/fennel/macros.fnl
+++ b/src/fennel/macros.fnl
@@ -38,12 +38,12 @@ Same as -> except will short-circuit with nil when it encounters a nil value."
      (let [els [...]
            e (table.remove els 1)
            el (if (list? e) e (list e))
            tmp (gensym)]
            tmp (gensym) msg (gensym)]
        (table.insert el 2 tmp)
        `(let [,tmp ,val]
        `(let [(,tmp ,msg) ,val]
           (if ,tmp
               (-?> ,el ,(unpack els))
               ,tmp)))))
               (values ,tmp ,msg))))))

(fn -?>>* [val ...]
  "Nil-safe thread-last macro.
@@ -53,12 +53,12 @@ Same as ->> except will short-circuit with nil when it encounters a nil value."
      (let [els [...]
            e (table.remove els 1)
            el (if (list? e) e (list e))
            tmp (gensym)]
            tmp (gensym) msg (gensym)]
        (table.insert el tmp)
        `(let [,tmp ,val]
        `(let [(,tmp ,msg) ,val]
           (if ,tmp
               (-?>> ,el ,(unpack els))
               ,tmp)))))
               (values ,tmp ,msg))))))

(fn ?dot [tbl k ...]
  "Nil-safe table look up.
-- 
2.20.1
Phil Hagelberg <phil@hagelb.org> writes: