org-special-block-extras: a minimal working example

⭐ The code lives at github.com/alhassy/org-special-block-extras —star it, or discuss it there!
1. A tiny function
We sum the first
An integer 2i - 1, for some i ≥ 1n oddThe Common Lisp ‘loop’ macro.
Valid clauses include:
For clauses:
for VAR from/upfrom/downfrom EXPR1 to/upto/downto/above/below EXPR2
[by EXPR3]
for VAR = EXPR1 then EXPR2
for VAR in/on/in-ref LIST [by FUNC]
for VAR across/across-ref ARRAY
for VAR being:
the elements of/of-ref SEQUENCE [using (index VAR2)]
the symbols [of OBARRAY]
the hash-keys/hash-values of HASH-TABLE [using (hash-values/hash-keys V2)]
the key-codes/key-bindings/key-seqs of KEYMAP [using (key-bindings VAR2)]
the overlays/intervals [of BUFFER] [from POS1] [to POS2]
the frames/buffers
the windows [of FRAME]
Iteration clauses:
repeat INTEGER
while/until/always/never/thereis CONDITION
Accumulation clauses:
collect/append/nconc/concat/vconcat/count/sum/maximize/minimize FORM
[into VAR]
Miscellaneous clauses:
with VAR = INIT
if/when/unless COND CLAUSE [and CLAUSE]... else CLAUSE [and CLAUSE...]
named NAME
initially/finally [do] EXPRS...
do EXPRS...
[finally] return EXPR
For more details, see Info node ‘(cl)Loop Facility’.
(fn CLAUSE...); place the
cursor after the last parenthesis and press C-x C-eC-x C-e ∷ eval-last-sexp
Evaluate sexp before point; print value in the echo area.
Interactively, EVAL-LAST-SEXP-ARG-INTERNAL is the prefix argument.
With a non ‘-’ prefix argument, print output into current buffer.
This commands handles ‘defvar’, ‘defcustom’ and ‘defface’ the
same way that ‘eval-defun’ does. See the doc string of that
function for details.
Normally, this function truncates long output according to the
value of the variables ‘eval-expression-print-length’ and
‘eval-expression-print-level’. With a prefix argument of zero,
however, there is no such truncation.
Integer values are printed in several formats (decimal, octal,
and hexadecimal). When the prefix argument is -1 or the value
doesn’t exceed ‘eval-expression-print-maximum-character’, an
integer value is also printed as a character of that codepoint.
If ‘eval-expression-debug-on-error’ is non-nil, which is the default,
this command arranges for all errors to enter the debugger.
(fn EVAL-LAST-SEXP-ARG-INTERNAL)
to define it.
(defun sum-odds (n)
"Return 1 + 3 + ⋯ + (2n - 1)."
(cl-loop for i from 1 to n sum (- (* 2 i) 1)))
Peek: the first few values
(sum-odds 4) is the sum of the first 4 odd numbers. In order:
n |
1 | 2 | 3 | 4 |
(sum-odds n) |
1 | 4 | 9 | 16 |
These are squares! We prove it below.
2. How the loop accumulates
Each step adds the next odd number to the running sum:
3. Why squares?
The squares are no coincidence:
\begin{align*} & \sum_{i=1}^{n} (2i - 1) \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Split the sum} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & 2 · {\color{red}{\sum_{i=1}^{n} i}} - {\color{teal}{\sum_{i=1}^{n} 1}} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Gauss: ${\color{red}{\sum_{i=1}^{n} i}} = n(n+1)/2$; and $n$ ones sum to ${\color{teal}n}$} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & n(n + 1) - {\color{teal}n} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Distribute, then cancel} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & n^2 \tag{$\color{violet}{\text{Odd}}$} \label{Odd} \end{align*}
Hence, by \eqref{Odd}, (sum-odds n) is \(n^2\).
Life & Computing Science by Musa Al-hassy is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License