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.
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
2. Sort IPv4 addresses numerically
@programmingpraxis: Is this a closure? Seems I’ve seen something similar before and it was termed a closure.
@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.