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)
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?
plus function returns the sum in its argument list. For example:
(plus 1 2 3 4 5) evaluates to
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)
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.
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
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
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.