A while back I presented a one day SKILL++ seminar to a group of beginner and advanced SKILL programmers. One example I showed was Variations on how to sum a list of numbers. This is a good example because the problem itself is easy to understand, so the audience can concentrate on the solution techniques rather than on the problem itself. I want to show a few of these examples in this blog post (and a few upcoming posts) in hopes you may find some of the techniques useful.
Summing Straightforward One straightforward way to sum a given list of numbers is to use simple iteration and mimic a primitive microprocessor. That is, establish an accumulator initialized to zero, and continue to increment the accumulator by successive numbers from the list until the list is exhausted, and finally return the accumulated value.
(defun sumlist_1a (numbers)
(let ((sum 0))
(foreach number numbers
sum = sum + number)
sum))
I imagine the code in this function would look very similar in many different languages such as C or Java -- of course with syntax variations.
Summing with apply In SKILL++ (as well as in traditional SKILL) this is not a particularly efficient implementation because the SKILL virtual machine compiler, unlike a native compiler, is not able to make particularly good use of the processor registers. The way to force SKILL to use the processor registers is to organize your code, when possible, to call built-in compiled functions.
(defun sumlist_1b (numbers)
(apply plus numbers))
Remember -- to force this function to be defined as SKILL++ rather than traditional SKILL, you'll either need to load it from a file with a .ils extension, or you'll need two wrap the definition in (inScheme ...)
when you copy and paste it into the CIWindow.
A quick test with measureTime
shows that sumlist_1b
is roughly 10 times faster than sumlist_1a
on a 10,000 element list of numbers.
How does it work?
The plus
function returns the sum in its argument list. For example: (plus 1 2 3 4 5)
evaluates to 15
.
The apply
function, when called with two arguments, calls the function designated by its first argument. In particular apply
calls that function argument list given as its second argument. For example:
(apply plus '(1 2 3 4 5))
is a call to plus
with two arguments. The first argument plus
is the function which apply
should call. The second argument, '(1 2 3 4 5)
is the list of arguments to call plus
with. Thus this use of apply
is equivalent to the following. (plus 1 2 3 4 5)
Note that plus
is used without a leading quote because in SKILL++ all global functions are available in a SKILL++ global variable of the same name. The variable plus
evaluates to the plus function.
Since sumlist_1b
is so much faster (execution-wise) and simpler (line-of-code-wise), it is very tempting to use, but be careful! It suffers from some limitations that do not exist with sumlist_1a
. For example, sumlist_1b
cannot sum the elements of the nil
list. The sumlist_1a
, however, claims the sum of the list nil
is 0
, which indeed sounds like a reasonable answer. Furthermore, sumlist_1a
, claims that the sum of a singleton list such as (3.4)
is the first (and only) element of the list, which again seems like a reasonable result.
Apply in other languages
Actually the apply
function is not an invention of the SKILL (or SKILL++) language. It is in fact central to programming languages derived from lambda calculus. A quick search on Wikipedia finds an article explaining its use in several languages.
More to come
In the next posting, I'll show some ways to get the speed and conciseness of sumlist_1b
without the caveats.
See Also
http://en.wikipedia.org/wiki/Apply
Jim Newton