## A Scheme Idiom

### June 16, 2017

While I was reading some Scheme code recently, I discovered a delightful little Scheme idiom that could simplify some coding tasks. It looks like this:

```> (define (make-accum n)
(case-lambda
(() n)
((m) (set! n (+ n m)) n)))
> (define a (make-accum 20))
> a
#<procedure>
> (a)
20
> (a 10)
30
> (a)
30```

Variable a is a accumulator; `define` it to set its initial value, fetch its current value by calling it as a function, and increment it by calling it with a value. This works because function `make-accum` returns a function, defined by `case-lambda`, with a semantics that varies based on its arity: with no arguments, the function returns the value stored in the closure, and with a single argument, it increments the value stored in the closure and returns the new value. The actual value is stored inside the function closure so it is only available through the defined interface, making it “safer” in some sense. And the concept works for other data types than accumulators, as the solution page will show.

Your task is to describe a useful idiom in your favorite programming language. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

### 3 Responses to “A Scheme Idiom”

1. mcmillhj said

Perl has a cool idiom that was borrowed from LISP called the Schwartzian transform, named after Randal Schwartz, the first person to document its use in Perl. The basic idea is that you have a potentially expensive computation that you need to run on N elements and then you need to sort them. The Schwartzian Transform avoids recomputing the expensive computation for last passes of the sort.

This lets you do interesting things like:

1. Sort strings by their length

```#!perl

use strict;
use warnings;

use feature qw/say/;

my @strings = qw/
eren
mikasa
armin
levi
erwin
reiner
ymir
historia
bertholdt
pixis
/;

say join "\n",
map  { \$_->[0]             }
sort { \$a->[1] cmp \$b->[1] }
map  { [\$_, length(\$_)]    } @strings;

# eren
# levi
# ymir
# armin
# erwin
# pixis
# mikasa
# reiner
# historia
# bertholdt
```

2. Sort IPv4 addresses numerically

```#!/usr/bin/perl

use strict;
use warnings;

use feature qw/say/;

my @ips = qw/
213.61.108.26
235.94.112.131
162.219.166.100
26.190.195.43
96.113.27.227
96.112.27.227
96.112.29.227
96.112.29.255
164.124.74.26
58.5.201.175
228.131.119.187
191.226.212.172
65.70.48.227
35.214.73.61
149.14.104.245
/;

say join "\n",
map  { join '.', @\$_ }
sort { \$a->[0] <=> \$b->[0] || \$a->[1] <=> \$b->[1] || \$a->[2] <=> \$b->[2] || \$a->[3] <=> \$b->[3] }
map  { [split /\./]  } @ips;

# 26.190.195.43
# 35.214.73.61
# 58.5.201.175
# 65.70.48.227
# 96.112.27.227
# 96.112.29.227
# 96.112.29.255
# 96.113.27.227
# 149.14.104.245
# 162.219.166.100
# 164.124.74.26
# 191.226.212.172
# 213.61.108.26
# 228.131.119.187
# 235.94.112.131
```
2. @programmingpraxis: Is this a closure? Seems I’ve seen something similar before and it was termed a closure.

3. programmingpraxis said

@bookofstevegraham: Yes, this is a closure. The value of the variable n is enclosed within the function, and not available to the rest of the program except through the interface defined by the function.