aboutsummaryrefslogtreecommitdiff
path: root/_tils/2021-04-24-three-way-conditional-for-number-signs.md
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2021-06-07 22:11:40 -0300
committerEuAndreh <eu@euandre.org>2021-06-07 22:11:40 -0300
commitf285818db4b7a783120882340e193dcf572b383f (patch)
tree6f6c13e5cd56a9be280b067567ffffe9b1b67605 /_tils/2021-04-24-three-way-conditional-for-number-signs.md
parentTODOs.md: Add #task-6a3a99ec-dd86-b8b3-b1eb-f9b9a4298f3a (diff)
parentAdd article on Codd's paper (diff)
downloadeuandre.org-f285818db4b7a783120882340e193dcf572b383f.tar.gz
euandre.org-f285818db4b7a783120882340e193dcf572b383f.tar.xz
Merge remote-tracking branch 'refs/remotes/vps/main'
Diffstat (limited to '_tils/2021-04-24-three-way-conditional-for-number-signs.md')
-rw-r--r--_tils/2021-04-24-three-way-conditional-for-number-signs.md61
1 files changed, 61 insertions, 0 deletions
diff --git a/_tils/2021-04-24-three-way-conditional-for-number-signs.md b/_tils/2021-04-24-three-way-conditional-for-number-signs.md
new file mode 100644
index 0000000..ec62378
--- /dev/null
+++ b/_tils/2021-04-24-three-way-conditional-for-number-signs.md
@@ -0,0 +1,61 @@
+---
+
+title: Three-way conditional for number signs
+
+date: 2021-04-24 3
+
+layout: post
+
+lang: en
+
+ref: three-way-conditional-for-number-signs
+
+---
+
+A useful macro from Paul Graham's [On Lisp][on-lisp] book:
+
+```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 [Structure and Interpretation of Computer Programs][sicp], which I was reading recently:
+
+```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:
+
+```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.
+
+[on-lisp]: http://www.paulgraham.com/onlisptext.html
+[sicp]: https://mitpress.mit.edu/sites/default/files/sicp/index.html