From 61ffa8466bbfa4ca8b13b442a3bd63ef9504a6da Mon Sep 17 00:00:00 2001
From: EuAndreh <eu@euandre.org>
Date: Wed, 30 Apr 2025 06:23:27 -0300
Subject: src/content/en/: Unpluralize collection names

---
 src/content/en/til/2021/04/24/scm-nif.adoc | 61 ++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 src/content/en/til/2021/04/24/scm-nif.adoc

(limited to 'src/content/en/til/2021/04/24/scm-nif.adoc')

diff --git a/src/content/en/til/2021/04/24/scm-nif.adoc b/src/content/en/til/2021/04/24/scm-nif.adoc
new file mode 100644
index 0000000..2ea8a6f
--- /dev/null
+++ b/src/content/en/til/2021/04/24/scm-nif.adoc
@@ -0,0 +1,61 @@
+= Three-way conditional for number signs on Lisp
+:categories: lisp scheme common-lisp
+:sort: 2
+:updatedat: 2021-08-14
+
+:on-lisp: https://www.paulgraham.com/onlisptext.html
+:sicp: https://mitpress.mit.edu/sites/default/files/sicp/index.html
+
+A useful macro from Paul Graham's {on-lisp}[On Lisp] book:
+
+[source,lisp]
+----
+(defmacro nif (expr pos zero neg)
+  (let ((g (gensym)))
+    `(let ((,g ,expr))
+       (cond ((plusp ,g) ,pos)
+             ((zerop ,g) ,zero)
+             (t ,neg)))))
+----
+
+After I looked at this macro, I started seeing opportunities to using it in many
+places, and yet I didn't see anyone else using it.
+
+The latest example I can think of is section 1.3.3 of {sicp}[Structure and
+Interpretation of Computer Programs], which I was reading recently:
+
+[source,scheme]
+----
+(define (search f neg-point pos-point)
+  (let ((midpoint (average neg-point pos-point)))
+    (if (close-enough? neg-point post-point)
+        midpoint
+        (let ((test-value (f midpoint)))
+          (cond ((positive? test-value)
+                 (search f neg-point midpoint))
+                ((negative? test-value)
+                 (search f midpoint pos-point))
+                (else midpoint))))))
+----
+
+Not that the book should introduce such macro this early, but I couldn't avoid
+feeling bothered by not using the `nif` macro, which could even remove the need
+for the intermediate `test-value` variable:
+
+[source,scheme]
+----
+(define (search f neg-point pos-point)
+  (let ((midpoint (average neg-point pos-point)))
+    (if (close-enough? neg-point post-point)
+        midpoint
+        (nif (f midpoint)
+             (search f neg-point midpoint)
+             (midpoint)
+             (search f midpoint pos-point)))))
+----
+
+It also avoids `cond`'s extra clunky parentheses for grouping, which is
+unnecessary but built-in.
+
+As a macro, I personally feel it tilts the balance towards expressivenes despite
+its extra cognitive load toll.
-- 
cgit v1.2.3

