<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Jim Newton Blog</title><link>http://www.cadence.com/Community/search/SearchResults.aspx?&amp;u=196313&amp;un=Team%20SKILL&amp;Scope=Blogs</link><description>Search results by user ID 196313</description><dc:language>en-US</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/cadence/community/blogs/196313" /><feedburner:info uri="cadence/community/blogs/196313" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>SKILL for the Skilled: Many Ways to Sum a List (Part 8): Closures -- Functions with State</title><link>http://feedproxy.google.com/~r/cadence/community/blogs/196313/~3/2hG8j-eptE0/skill-for-the-skilled-many-ways-to-sum-a-list-part-8.aspx</link><pubDate>Tue, 23 Apr 2013 13:21:00 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:1321806</guid><dc:creator>Team SKILL</dc:creator><description>&lt;p&gt;In the &lt;a href="http://www.cadence.com/Community/search/SearchResults.aspx?u=196313&amp;amp;o=DateDescending"&gt;past several postings&lt;/a&gt; to this blog, we&amp;#39;ve looked at various ways to sum a given list of numbers. In this posting&amp;nbsp;I&amp;#39;ll present yet another way to do this. This&amp;nbsp;time the technique will be markedly different than the previous ways, and will take advantage of a powerful feature of SKILL++, namely lexical closures. These closures will be used to implement data encapsulation, and we&amp;#39;ll also use lexical closures to capture computation state and continue the computation later. &lt;/p&gt;&lt;h4&gt;Put the CIWindow into SKILL++ mode&lt;/h4&gt;Before proceeding, we need to change the listening mode of the CIWindow. We would like the CIWindow to interpret&amp;nbsp;input expressions as SKILL++ rather than traditional SKILL. &lt;p&gt;Normally, when you type SKILL expressions into the CIWindow&amp;nbsp;that defines functions or defines variables, the semantics of your code is taken as traditional SKILL. If, however, you would like to have SKILL++ (Scheme) semantics, you can put the CIWindow into &lt;b&gt;SKILL++ Mode&lt;/b&gt; by calling the function &lt;code&gt;(toplevel &amp;#39;ils)&lt;/code&gt;. This function does not return immediately, but rather puts the CIWindow into a different listening mode until you call the function &lt;code&gt;resume&lt;/code&gt;, causing the &lt;code&gt;(toplevel &amp;#39;ils)&lt;/code&gt; to return. &lt;/p&gt;&lt;p&gt;You can find out which &lt;i&gt;listening mode&lt;/i&gt; the CIWindow is in either by looking at the indicate in the button left-hand corner of the CIW. If in SKILL listening mode &lt;b&gt;&amp;gt;&lt;/b&gt; will be inconspicuously displayed. The &lt;b&gt;&amp;gt;&lt;/b&gt; is a little difficult to notice because it is so inconspicuous. &lt;/p&gt;&lt;img src="http://www.cadence.com/Community/CSSharedFiles/blogs/cic/team%20skill/skillprompt.png" alt="FILE UNREADABLE" /&gt;&lt;p&gt;However, if in SKILL++ listening mode &lt;b&gt;ILS-&amp;gt;&lt;/b&gt; will be displayed.&lt;/p&gt;&lt;img src="http://www.cadence.com/Community/CSSharedFiles/blogs/cic/team%20skill/schemeprompt.png" alt="FILE UNREADABLE" /&gt;&lt;p&gt;You may also determine the listening mode by calling the function &lt;code&gt;theEnvironment&lt;/code&gt; which will return either &lt;code&gt;nil&lt;/code&gt; if in SKILL mode, or non-nil, if in SKILL++ mode. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;(theEnvironment)
&lt;i&gt;  ==&amp;gt; nil&lt;/i&gt;
(toplevel &amp;#39;ils)
(theEnvironment)
&lt;i&gt;  ==&amp;gt; envobj@0x18fa2020&lt;/i&gt;
(resume)
&lt;i&gt;  ==&amp;gt; nil&lt;/i&gt;
(theEnvironment)
&lt;i&gt;  ==&amp;gt; nil&lt;/i&gt;
&lt;/pre&gt;&lt;h4&gt;Defining an adder&lt;/h4&gt;With the CIWindow in SKILL++ mode we can proceed to define a SKILL++ function. &lt;pre&gt;(unless (theEnvironment)
   (toplevel &amp;#39;ils))

(defun make_adder_8a ()   ; 1.1
  (let ((sum 0))          ; 1.2
    (lambda (n)           ; 1.3
      sum = sum + n)))    ; 1.4
&lt;/pre&gt;&lt;p&gt;This definition of &lt;code&gt;make_adder_8a&lt;/code&gt; is a 4 line function, yet does a lot in its 4 lines. It is a higher-order function, as seen in &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2011/01/04/skill-for-the-skilled-what-is-skill.aspx"&gt;SKILL for the Skilled: What is SKILL++?&lt;/a&gt; it is a function which returns another function. It is a function which creates and returns a special kind of function called a lexical closure. In particular the &lt;code&gt;lambda&lt;/code&gt; on line 1.3 creates a unary function which when called will evaluate the expression on line 1.4. However, the expression on line 1.4, references a variable, &lt;code&gt;sum&lt;/code&gt; defined on line 1.2 and which is &lt;i&gt;external&lt;/i&gt; to the &lt;code&gt;lambda&lt;/code&gt;. In this case &lt;code&gt;sum&lt;/code&gt; is called a &lt;i&gt;free variable&lt;/i&gt;. &lt;/p&gt;&lt;p&gt;The important feature of SKILL++ which makes this magic work is that when &lt;code&gt;make_adder_8a&lt;/code&gt; gets called, the &lt;code&gt;let&lt;/code&gt; on line 1.2 creates a new &lt;i&gt;binding&lt;/i&gt; for the variable named &lt;code&gt;sum&lt;/code&gt;. A binding is a newly allocated memory location which is associated with a named variable. The initial value stored in this memory location is &lt;code&gt;0&lt;/code&gt; as indicated on line 1.2. SKILL++ then proceeds to line 1.3 where it creates an anonymous function, attaching it to this binding. The two occurrences of the name, &lt;code&gt;sum&lt;/code&gt;, on line 1.4 (within this anonymous function) are compiled as references to the binding. &lt;/p&gt;&lt;p&gt;The &lt;code&gt;make_adder_8a&lt;/code&gt; function returns the anonymous function object created on line 1.3, without evaluating the code on line 1.4. Critically this function object maintains a link to the &lt;code&gt;sum&lt;/code&gt; binding. Thereafter when the anonymous is called, the expression on line 1.4 is evaluated and its value returned. In evaluating this expression, the value of &lt;code&gt;sum&lt;/code&gt; (in this allocated binding) is referenced and updated by the expression &lt;code&gt;sum = sum + n&lt;/code&gt;, &lt;code&gt;n&lt;/code&gt; being the value passed to the anonymous function when it is called. &lt;/p&gt;&lt;h4&gt;Testing make_adder_8a&lt;/h4&gt;Let&amp;#39;s experiment with &lt;code&gt;make_adder_8a&lt;/code&gt;. Keep in mind that &lt;code&gt;make_adder_8a&lt;/code&gt; does not actually add anything, rather it creates a function which is capabile of adding. &lt;pre&gt;A = (make_adder_8a)       ; 2.1
&lt;i&gt;  ==&amp;gt; funobj:A&lt;/i&gt;
(A 1)                     ; 2.2
&lt;i&gt;  ==&amp;gt; 1&lt;/i&gt;
(A 2)                     ; 2.3
&lt;i&gt;  ==&amp;gt; 3&lt;/i&gt;
(A 3)                     ; 2.4
&lt;i&gt;  ==&amp;gt; 6&lt;/i&gt;
(A 4)                     ; 2.5
&lt;i&gt;  ==&amp;gt; 10&lt;/i&gt;
(A 5)                     ; 2.6
&lt;i&gt;  ==&amp;gt; 15&lt;/i&gt;
&lt;/pre&gt;&lt;h4&gt;Arduous line-by-line explanation&lt;/h4&gt;On line 2.1, &lt;code&gt;make_adder_8a&lt;/code&gt; is called, and as described above a SKILL++ anonymous function object (a closure) is created and returned. This closure is stored in the global variable &lt;code&gt;A&lt;/code&gt;. &lt;p&gt;The CIWindow prints this value as funobj:A. As mentioned before the initial value of &lt;code&gt;sum&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;. Note that &lt;code&gt;sum&lt;/code&gt; is not a global variable. Rather it is a variable which is visible only to the code on lines 1.3 and 1.4. Furthermore, notice that we have no immediate access to the variable &lt;code&gt;sum&lt;/code&gt;. We cannot query the value of &lt;code&gt;code&lt;/code&gt; and we cannot modify its value, except by calling the function we have just stored in the global variable &lt;code&gt;A&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;When line 2.2, &lt;code&gt;(A 1)&lt;/code&gt; is evaluated, the expression on line 1.4 is evaluated: &lt;code&gt;sum = sum + n&lt;/code&gt; with &lt;code&gt;n=1&lt;/code&gt;; &lt;code&gt;sum&lt;/code&gt; is updated from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt;, and &lt;code&gt;1&lt;/code&gt; is returned and printed into the CIWindow. &lt;/p&gt;&lt;p&gt;When line 2.3, &lt;code&gt;(A 2)&lt;/code&gt; is evaluated, again the expression on line 1.4 is evaluated: &lt;code&gt;sum = sum + n&lt;/code&gt; with &lt;code&gt;n=2&lt;/code&gt;. This time, &lt;code&gt;sum&lt;/code&gt; is updated from &lt;code&gt;1&lt;/code&gt; to &lt;code&gt;3&lt;/code&gt; and &lt;code&gt;3&lt;/code&gt; is returned. &lt;/p&gt;&lt;p&gt;When lines 2.4, 2.5, and 2.6 are evaluated, &lt;code&gt;sum = sum + n&lt;/code&gt; is evaluated three times with &lt;code&gt;n=3&lt;/code&gt;, &lt;code&gt;n=4&lt;/code&gt;, and &lt;code&gt;n=5&lt;/code&gt; respectively; thus &lt;code&gt;sum&lt;/code&gt; is updated to &lt;code&gt;6&lt;/code&gt;, &lt;code&gt;10&lt;/code&gt;, and finally to &lt;code&gt;15&lt;/code&gt;. &lt;/p&gt;&lt;h4&gt;Summing a list with an adder&lt;/h4&gt;You can use an adder as created by &lt;code&gt;make_adder_8a&lt;/code&gt; to add the elements of a list incrementally. &lt;pre&gt;A = (make_adder_8a)          ; 3.1
&lt;i&gt;  ==&amp;gt; funobj:A&lt;/i&gt;
(mapcar A &amp;#39;(1 2 3 4 5))      ; 3.2
&lt;i&gt;  ==&amp;gt; (1 3 6 10 15)&lt;/i&gt;
&lt;/pre&gt;This call to &lt;code&gt;mapcar&lt;/code&gt; iterates across the given list &lt;code&gt;(1 2 3 4 5)&lt;/code&gt; and calls the function &lt;code&gt;A&lt;/code&gt; on each iteration, each time with the successive element of the list. Since each call to &lt;code&gt;A&lt;/code&gt; returns the current value of the partial sum, &lt;code&gt;mapcar&lt;/code&gt; returns not he final sum, but rather the list of partial sums computed at each step of the iteration. &lt;h4&gt;&amp;nbsp;&amp;nbsp;&lt;/h4&gt;&lt;h4&gt;Multiple SKILL++ adders in parallel&lt;/h4&gt;You can create several adders which work independent of each other. In the following example, we create two &lt;i&gt;adders&lt;/i&gt;, &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;. Each one internally maintains its own partial sum of the arguments given to successive calls. &lt;pre&gt;B1 = (make_adder_8a)       ; 4.1
&lt;i&gt;  ==&amp;gt; funobj:B1&lt;/i&gt;
B2 = (make_adder_8a)       ; 4.2
&lt;i&gt;  ==&amp;gt; funobj:B2&lt;/i&gt;
B3 = (make_adder_8a)       ; 4.3
&lt;i&gt;  ==&amp;gt; funobj:B3&lt;/i&gt;
(B1 1)                     ; 4.4
&lt;i&gt;  ==&amp;gt; 1&lt;/i&gt;
(B2 10)                    ; 4.5
&lt;i&gt;  ==&amp;gt; 10&lt;/i&gt;
(B3 100)                   ; 4.6
&lt;i&gt;  ==&amp;gt; 100&lt;/i&gt;
(B1 2)                     ; 4.7
&lt;i&gt;  ==&amp;gt; 3&lt;/i&gt;
(B2 20)                    ; 4.8
&lt;i&gt;  ==&amp;gt; 30&lt;/i&gt;
(B3 200)                   ; 4.9
&lt;i&gt;  ==&amp;gt; 300&lt;/i&gt;
(B1 3)                     ; 4.10
&lt;i&gt;  ==&amp;gt; 6&lt;/i&gt;
(B2 3)                     ; 4.11
&lt;i&gt;  ==&amp;gt; 60&lt;/i&gt;
(B3 30)                    ; 4.12
&lt;i&gt;  ==&amp;gt; 600&lt;/i&gt;
&lt;/pre&gt;&lt;p&gt;This works because each call to &lt;code&gt;make_adder_8a&lt;/code&gt; on lines 4.1, 4.2, and 4.3, each allocate a new closure (three in all), assign each of them respectively turn to the global variables &lt;code&gt;B1&lt;/code&gt;, &lt;code&gt;B2&lt;/code&gt;, and&lt;code&gt;B3&lt;/code&gt;. Each of these three function has its own independent binding of &lt;code&gt;sum&lt;/code&gt;, each of which is initialized to &lt;code&gt;code&lt;/code&gt;. When lines 4.4, 4.7, and 4.10 are evaluated, the &lt;code&gt;sum&lt;/code&gt; binding of &lt;code&gt;B1&lt;/code&gt; is updated, but the &lt;code&gt;sum&lt;/code&gt; bindings of &lt;code&gt;B2&lt;/code&gt; and &lt;code&gt;B3&lt;/code&gt; are not effected. Similarly when 4.5, 4.8, and 4.11 are evaluated, the &lt;code&gt;sum&lt;/code&gt; binding of &lt;code&gt;B2&lt;/code&gt; is effected. And similarly for lines 4.6, 4.9, and 4.12. &lt;/p&gt;&lt;h4&gt;Using flet as an alternative to lambda&lt;/h4&gt;If you find the use of &lt;code&gt;(lambda ...)&lt;/code&gt; to be confusing in the definition of &lt;code&gt;make_adder_8a&lt;/code&gt;, you can, as an alternative, define the same functionality using &lt;code&gt;flet&lt;/code&gt;. &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;(defun make_adder_8b ()       ; 5.1
  (let ((sum 0))              ; 5.2
    (flet ((add (n)           ; 4.3
             sum = sum + n))  ; 5.4
      add)))                  ; 5.5
&lt;/pre&gt;&lt;p&gt;This implementation of &lt;code&gt;make_adder_8b&lt;/code&gt; uses &lt;code&gt;flet&lt;/code&gt; to define a local function named &lt;code&gt;add&lt;/code&gt;. The normal pattern of using &lt;code&gt;flet&lt;/code&gt; which you&amp;#39;ve seen in previous posts of &lt;i&gt;SKILL for the Skilled&lt;/i&gt; such as &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2011/01/25/skill-for-the-skilled-continued-introduction-to-skill.aspx"&gt;Continued Introduction to SKILL++&lt;/a&gt;, is to define a local function and call it. The pattern used by &lt;code&gt;make_adder_8b&lt;/code&gt; is to define a local function and return it, allowing the function which called &lt;code&gt;make_adder_8b&lt;/code&gt; to call it, or likewise return it to its caller. &lt;/p&gt;&lt;h4&gt;Data Encapsulation and Object Orientation&lt;/h4&gt;Some programming languages present the ability to encapsulate data as part of the object model. In these languages &lt;i&gt;private&lt;/i&gt; variables are member variables within classes, and methods in/on those classes awkwardly manipulate and access these private variables. &lt;p&gt;This unholy marriage of private data to object model is limiting in practice because it is not only object oriented programs which need to hide data. In fact, a program written in any style may need to take advantage of encapsulate. In SKILL++ (and other dialects of Scheme), data encapsulation is independent from the object system, as it should be. &lt;/p&gt;&lt;p&gt;In SKILL++ the &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;lambda&lt;/code&gt; primitives behave differently than in traditional SKILL. They behave in a way which allows a function to create lexical closures. These lexical closures are then able to manipulate the state of &lt;i&gt;private&lt;/i&gt; variables which they encapsulate. &lt;/p&gt;&lt;h4&gt;Summary&lt;/h4&gt;In this article, we looked at how to use lexical closures which maintain their internal state to implement counters. We looked very lightly and abstractly into how this is implemented within the SKILL++. And we traced step by step though a couple of examples of how this works in practice. &lt;p&gt;In this way SKILL++ provides data encapsulation completely independent from the object system. While SKILL++ does indeed have an extensive, full-featured, and powerful object system, in SKILL++ you are not forced to write a program in an object oriented way just to encapsulate/hide data. Encapsulation is a feature of SKILL++ which is available to you whether you are using OO, imperative, declarative, functional, or any other style you choose. &lt;/p&gt;&lt;h4&gt;More to come&lt;/h4&gt;In the next post we&amp;#39;ll look more at the differences you&amp;#39;ll see when defining these types of functions in SKILL++ vs in SKILL. &lt;h4&gt;See Also&lt;/h4&gt;&lt;p&gt;&lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2011/01/04/skill-for-the-skilled-what-is-skill.aspx"&gt;SKILL for the Skilled: What is SKILL++?&lt;/a&gt; &lt;br /&gt;as &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2011/01/25/skill-for-the-skilled-continued-introduction-to-skill.aspx"&gt;Continued Introduction to SKILL++&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Jim Newton&lt;/p&gt;</description><feedburner:origLink>http://www.cadence.com/Community/blogs/cic/archive/2013/04/23/skill-for-the-skilled-many-ways-to-sum-a-list-part-8.aspx</feedburner:origLink></item><item><title>SKILL for the Skilled: Many Ways to Sum a List (Part 7)</title><link>http://feedproxy.google.com/~r/cadence/community/blogs/196313/~3/PyORbrxAIzE/skill-for-the-skilled-many-ways-to-sum-a-list-part-7.aspx</link><pubDate>Mon, 25 Mar 2013 13:05:00 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:1321615</guid><dc:creator>Team SKILL</dc:creator><description>&lt;p&gt;In this episode of &lt;i&gt;SKILL for the Skilled&lt;/i&gt; I&amp;#39;ll introduce a feature of the &lt;code&gt;let&lt;/code&gt; primitive&amp;nbsp;that Scheme programmers will find familiar, but other readers may have never seen before. The feature is called &lt;i&gt;named let&lt;/i&gt;, and I&amp;#39;ll show you how to use it to sum&amp;nbsp;the numbers in a given list.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Named LET&lt;/b&gt;&lt;/p&gt;There is a feature of &lt;code&gt;let&lt;/code&gt; available in SKILL++ which is not available in traditional SKILL, called &lt;i&gt;named let&lt;/i&gt;. Here is an example of how it can be used to sum a given list of numbers. &lt;pre&gt;(defun sumlist_7a (numbers)
  (let REPEAT
    ((sum_so_far 0)
     (rest       numbers))
    (if rest
        (REPEAT (plus sum_so_far (car rest))
                (cdr rest))
        sum_so_far)))
&lt;/pre&gt;In this example, the &lt;i&gt;named let&lt;/i&gt; defines a local function named, &lt;code&gt;REPEAT&lt;/code&gt; and calls it once with the two arguments, &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;numbers&lt;/code&gt;. Of course, &lt;code&gt;REPEAT&lt;/code&gt; is by no means a reserved word; you can name the local function any valid variable name. Within the body of the &lt;i&gt;named let&lt;/i&gt; you may call the local function with two arguments. You may recursively call the function zero, one, or more times as your algorithm requires. &lt;p&gt;&lt;b&gt;Testing the function&lt;/b&gt;&lt;/p&gt;If we enable tracing of &lt;code&gt;sumlist_7a&lt;/code&gt; and &lt;code&gt;REPEAT&lt;/code&gt;, we can see what happens when calling &lt;code&gt;sumlist_7a&lt;/code&gt;. We can see that the local function, &lt;code&gt;REPEAT&lt;/code&gt; is called recursively several times, and that the implementation does in fact return the correct sum of the given list of numbers. &lt;pre&gt;(trace sumlist_7a)
(trace REPEAT)
(sumlist_7a &amp;#39;(1 2 3 4 5))
|sumlist_7a((1 2 3 4 5))
||(REPEAT 0 (1 2 3 4 5))
|||(REPEAT 1 (2 3 4 5))
||||(REPEAT 3 (3 4 5))
|||||(REPEAT 6 (4 5))
||||||(REPEAT 10 (5))
|||||||(REPEAT 15 nil)
|||||||REPEAT --&amp;gt; 15
||||||REPEAT --&amp;gt; 15
|||||REPEAT --&amp;gt; 15
||||REPEAT --&amp;gt; 15
|||REPEAT --&amp;gt; 15
||REPEAT --&amp;gt; 15
|sumlist_7a --&amp;gt; 15
15
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Equivalent to labels&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The &lt;i&gt;named let&lt;/i&gt; is more or less equivalent to a declaration and call of a local function as if by using &lt;code&gt;labels&lt;/code&gt;. If you recall, this is exactly what was shown in &lt;code&gt;sumlist_3b&lt;/code&gt; in &lt;i&gt;SKILL for the Skilled: Many Ways to Sum a List (Part 3)&lt;/i&gt;. &lt;/p&gt;&lt;p&gt;(defun sumlist_3b (numbers)&lt;br /&gt;&amp;nbsp; (labels ((sum (sum_so_far rest)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (if rest&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (sum (plus (car rest) sum_so_far)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (cdr rest))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum_so_far)))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (sum 0 numbers)))&lt;/p&gt;&lt;p&gt;If you trace &lt;code&gt;sumlist_3b&lt;/code&gt; and &lt;code&gt;sum&lt;/code&gt; you&amp;#39;ll see that it executes pretty much the same thing as &lt;code&gt;sumlist_7a&lt;/code&gt;. &lt;/p&gt;&lt;pre&gt;(trace sumlist_3b)
(trace sum)
(sumlist_3b &amp;#39;(1 2 3 4 5))
|sumlist_3b((1 2 3 4 5))
||(sum 0 (1 2 3 4 5))
|||(sum 1 (2 3 4 5))
||||(sum 3 (3 4 5))
|||||(sum 6 (4 5))
||||||(sum 10 (5))
|||||||(sum 15 nil)
|||||||sum --&amp;gt; 15
||||||sum --&amp;gt; 15
|||||sum --&amp;gt; 15
||||sum --&amp;gt; 15
|||sum --&amp;gt; 15
||sum --&amp;gt; 15
|sumlist_3b --&amp;gt; 15
15
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Illusion of jumping to the top&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The illusion (or abstraction) presented by the &lt;i&gt;named let&lt;/i&gt; is that of being able to &lt;i&gt;jump&lt;/i&gt; back to the top of the &lt;code&gt;let&lt;/code&gt; form, and evaluate it again with different initialization values. &lt;/p&gt;&lt;p&gt;Consider this simple &lt;code&gt;let&lt;/code&gt; example. &lt;/p&gt;&lt;pre&gt;(let loop
   ((a 10)
    (b 0))
 (println (list a b))
 (when (plusp a)
   (loop (sub1 a) 
         (add1 b))))
&lt;/pre&gt;Which prints the following output. &lt;pre&gt;(10 0)
(9 1)
(8 2)
(7 3)
(6 4)
(5 5)
(4 6)
(3 7)
(2 8)
(1 9)
(0 10)
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Doesn&amp;#39;t work in traditional SKILL&lt;/b&gt;&lt;/p&gt;&lt;p&gt;If you try to evaluate a named let in traditional SKILL (e.g., with a .il file extension), you&amp;#39;ll get an error something like the following, which basically means that SKILL let expects a list as its first operand and you have given the symbol &lt;code&gt;loop&lt;/code&gt; instead. &lt;/p&gt;&lt;pre&gt;*Error* let: local bindings must be a proper list - loop&lt;/pre&gt;&lt;p&gt;&lt;b&gt;let is syntactic sugar for lambda&lt;/b&gt;&lt;/p&gt;&lt;p&gt;In SKILL++ the normal &lt;i&gt;let&lt;/i&gt; has the same semantics as calling an unnamed function with particular parameter values. For example: &lt;/p&gt;&lt;pre&gt;(let ((a X)
      (b Y)
      (c Z))
  (expr1 a b)
  (expr2 b c))
&lt;/pre&gt;Is semantically the same as the following arguably less readable expression. The expression uses &lt;i&gt;funcall&lt;/i&gt; to call a nameless function, defined by the &lt;code&gt;(lambda (a b c) ...)&lt;/code&gt;; in particular to call it with the three values &lt;code&gt;X&lt;/code&gt;, &lt;code&gt;Y&lt;/code&gt;, and &lt;code&gt;Z&lt;/code&gt;. In fact the two code snippets are simply syntactical transforms of each other. &lt;pre&gt;(funcall (lambda (a b c)
           (expr1 a b)
           (expr2 b c))
         X
         Y
         Z)
&lt;/pre&gt;When you look at the equivalent &lt;code&gt;lambda&lt;/code&gt; form of &lt;code&gt;let&lt;/code&gt; it is immediately clear that the expressions within the lambda are not able to make recursive calls to this unnamed function. This limitation is solved by the &lt;i&gt;named let&lt;/i&gt;. &lt;p&gt;&lt;b&gt;Named let and tail-call optimization&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The illusion of &lt;i&gt;jumping&lt;/i&gt; back to the top in sort of a &lt;code&gt;goto&lt;/code&gt; fashion is indeed what happens if tail-call-elimination is enabled via the &lt;i&gt;optimizeTailCall&lt;/i&gt; status flag explained in &lt;i&gt;SKILL for the Skilled: Many Ways to Sum a List (Part 4)&lt;/i&gt;. &lt;/p&gt;&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;/p&gt;&lt;p&gt;In this post I&amp;#39;ve shown some examples of how to used the &lt;i&gt;named let&lt;/i&gt; construct of SKILL++. This construct converts the conventional &lt;code&gt;let&lt;/code&gt; into a loop --- a loop which can be repeated by &lt;i&gt;calling&lt;/i&gt; the label as a function, providing the next iteration&amp;#39;s variable values. &lt;/p&gt;&lt;p&gt;&lt;b&gt;More to come&lt;/b&gt;&lt;/p&gt;&lt;p&gt;In upcoming posts we&amp;#39;ll continue to survey the SKILL++ language using the example of summing a list. &lt;/p&gt;&lt;p&gt;&lt;b&gt;See Also&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/18/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-3.aspx?postID=1314708"&gt;SKILL for the Skilled: Many Ways to Sum a List (Part 3)&lt;/a&gt; &lt;br /&gt;&lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/10/15/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-4.aspx?postID=1314709"&gt;SKILL for the Skilled: Many Ways to Sum a List (Part 4)&lt;/a&gt; &lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Scheme_%28programming_language%29"&gt;Scheme&lt;/a&gt; In particular see the discussion of &lt;a href="http://en.wikipedia.org/wiki/Scheme_%28programming_language%29#Block_structure"&gt;named let&lt;/a&gt; &lt;/p&gt;</description><feedburner:origLink>http://www.cadence.com/Community/blogs/cic/archive/2013/03/25/skill-for-the-skilled-many-ways-to-sum-a-list-part-7.aspx</feedburner:origLink></item><item><title>SKILL for the Skilled: Many Ways to Sum a List (Part 6)</title><link>http://feedproxy.google.com/~r/cadence/community/blogs/196313/~3/p5dXSJSH2uY/6-skill-for-the-skilled-many-ways-to-sum-a-list-part-6.aspx</link><pubDate>Thu, 10 Jan 2013 17:04:00 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:1316750</guid><dc:creator>Team SKILL</dc:creator><description>In a &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/10/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-2.aspx?postID=1314605"&gt;previous post&lt;/a&gt; I presented &lt;code&gt;sumlist_2b&lt;/code&gt; as a function&amp;nbsp;that would sum lists of length 0, 1, or more. &lt;pre&gt;(defun sumlist_2b (numbers)
  (apply plus 0 0 numbers))
&lt;/pre&gt;&lt;p&gt;Unfortunately &lt;code&gt;sumlist_2b&lt;/code&gt; cannot handle extremely long lists. In this posting, I will introduce &lt;code&gt;sumlist_6&lt;/code&gt; which does not suffer from this limitation. &lt;/p&gt;&lt;p&gt;This posting will not introduce any new SKILL++ primitives. Instead, it will use several primitives which have been introduced in the previous several postings to implement an algorithm which you may not have seen before. If any of these are unknown or mysterious to you, please consult previous postings of &lt;i&gt;SKILL for the Skilled&lt;/i&gt; or the Virtuoso on-line documentation. &lt;/p&gt;&lt;code&gt;apply&lt;/code&gt; used to call a function indirectly given the function object and a list of arguments. &lt;code&gt;sstatus&lt;/code&gt; modify a status variable of the SKILL virtual machine. &lt;code&gt;optimizeTailCall&lt;/code&gt; makes function calls in tail position be stack-space neutral. &lt;code&gt;labels&lt;/code&gt; defines local function functions which may be mutually recursive &lt;code&gt;unwindProtect&lt;/code&gt;defines a clean-up procedure which is executed even if an error is triggered. &lt;h4&gt;Very long lists&lt;/h4&gt;&lt;p&gt;If you attempt to use &lt;code&gt;sumlist_2b&lt;/code&gt; on extremely long lists it will fail. You can generate a very long list as follows: &lt;/p&gt;&lt;pre&gt;data = (list 1.1 -2.1 2.3 -.04)
(for i 1 15
  data = (append data data))
&lt;/pre&gt;&lt;p&gt;This produces a list of length 131072. If you attempt to sum this list with &lt;code&gt;sumlist_2b&lt;/code&gt; you get the following error. &lt;/p&gt;&lt;pre&gt;*Error* plus: too many arguments (at most 65535 expected, 131074 given) - (0 0 1.1 -2.1 2.3 ... )
&amp;lt;&amp;lt;&amp;lt; Stack Trace &amp;gt;&amp;gt;&amp;gt;
apply(plus 0 0 numbers)
sumlist_2b(data)
&lt;/pre&gt;&lt;p&gt;The error message complains about a list of length &lt;code&gt;131074&lt;/code&gt;. This is because &lt;code&gt;data&lt;/code&gt; has length &lt;code&gt;131072&lt;/code&gt;, but &lt;code&gt;sumlist_2b&lt;/code&gt; prepends two additional &lt;code&gt;0&lt;/code&gt;&amp;#39;s to the argument list. &lt;code&gt;131072 + 2 = 131074&lt;/code&gt;. &lt;/p&gt;&lt;h4&gt;An esoteric issue?&lt;/h4&gt;&lt;p&gt;You may very well consider this an esoteric issue. And you would be right. If you are in charge of generating the data, and you know the number of elements in your list is less than &lt;code&gt;16K&lt;/code&gt;, then there is no need to worry about this corner case. I suspect very few of the readers of this blog have ever, or will ever encounter such a situation. Even with that being the case, I discuss this here in the hopes that some of the techniques may prove useful, even if the exact problem never occurs. &lt;/p&gt;&lt;p&gt;Another reason to present a solution to this particular problem is that in so doing we can combine several other concepts which have been discussed in the previous &lt;i&gt;SKILL for the Skilled&lt;/i&gt; blog postings. &lt;/p&gt;&lt;h4&gt;The applyReduce function&lt;/h4&gt;&lt;p&gt;The following implementation of &lt;code&gt;applyReduce&lt;/code&gt; takes advantage of &lt;code&gt;(sstatus optimizeTailCall t)&lt;/code&gt; and &lt;code&gt;unwindProtect&lt;/code&gt; as seen in a previous post of &lt;i&gt;SKILL for the Skilled&lt;/i&gt;. &lt;/p&gt;&lt;pre&gt;(defun applyReduce (fun args @key (maxArgs 8192) identity)
  (labels ((apply_head (fun args tail)
             (let ((save (cdr tail)))
               (setcdr tail nil)
               (unwindProtect
                (apply fun args)
                (setcdr tail save))))
           (apply_reduce (args)
             (let ((tail (nthcdr (sub1 maxArgs) args)))
               (if (cdr tail)
                   (apply_reduce (cons (apply_head fun args tail)
                                       (cdr tail)))
                   (apply fun args)))))
    (cond
      ((cdr args) 
       &lt;i&gt;;; if args has more the two elements&lt;/i&gt;
       (let ((save_optimizeTailCall (status optimizeTailCall)))
         (sstatus optimizeTailCall t)
         (unwindProtect
           (apply_reduce args)
           (sstatus optimizeTailCall save_optimizeTailCall))))
      (args
       &lt;i&gt;;; if args has exactly one element&lt;/i&gt;
       (car args))
      (t
       &lt;i&gt;;; if args is nil&lt;/i&gt;
       identity))))
&lt;/pre&gt;&lt;h4&gt;How does it work?&lt;/h4&gt;&lt;p&gt;The &lt;code&gt;applyReduce&lt;/code&gt; function above calls the given function multiple times, but each time with a maximum of &lt;code&gt;maxArgs&lt;/code&gt; number of arguments. The &lt;code&gt;maxArgs&lt;/code&gt; parameter defaults to &lt;code&gt;8192&lt;/code&gt; but you may override it to something smaller, especially to understand better how the function works. &lt;/p&gt;&lt;pre&gt;(trace plus)
(applyReduce plus &amp;#39;(.1 .2 .3 .4 .5 .6 .7 .8 .9
                    .11 .12 .13 .14 .15 .16 .17 .18 .19) ?maxArgs 5)
(untrace plus)
&lt;/pre&gt;&lt;p&gt;In the trace output you can see that the &lt;code&gt;plus&lt;/code&gt; function is called several times, but never with more than 5 arguments. After the initial call, the first argument to &lt;code&gt;plus&lt;/code&gt; is the return value of the previous call. &lt;/p&gt;&lt;pre&gt;||||||||||||||(0.1 + 0.2 + 0.3 + 0.4 + 0.5)
||||||||||||||plus --&amp;gt; 1.5
||||||||||||||||(1.5 + 0.6 + 0.7 + 0.8 + 0.9)
||||||||||||||||plus --&amp;gt; 4.5
||||||||||||||||||(4.5 + 0.11 + 0.12 + 0.13 + 0.14)
||||||||||||||||||plus --&amp;gt; 5.0
||||||||||||||||||||(5.0 + 0.15 + 0.16 + 0.17 + 0.18)
||||||||||||||||||||plus --&amp;gt; 5.66
||||||||||||||||||(5.66 + 0.19)
||||||||||||||||||plus --&amp;gt; 5.85
&lt;/pre&gt;&lt;p&gt;Now we can use &lt;code&gt;applyReduce&lt;/code&gt; to create an efficient &lt;code&gt;sumlist_6&lt;/code&gt; function which is able to add up the elements of an arbitrarily long list. We can use &lt;code&gt;sumlist_6&lt;/code&gt; to add up the 131072 elements of the list &lt;code&gt;data&lt;/code&gt; created above. &lt;/p&gt;&lt;pre&gt;(defun sumlist_6 (numbers)
  (applyReduce plus numbers ?identity 0))
&lt;/pre&gt;&lt;p&gt;Testing it, we can see that it works and returns the correct result. We need to test &lt;code&gt;sumlist_6&lt;/code&gt; for a very long list, as well as for the nil list and a singleton list. &lt;/p&gt;&lt;pre&gt;(sumlist_6 data)
--&amp;gt; 41287.68

(sumlist_6 nil)
--&amp;gt; 0

(sumlist_6 &amp;#39;(42))
--&amp;gt; 42
&lt;/pre&gt;&lt;h4&gt;What about the performance?&lt;/h4&gt;&lt;p&gt;Recall the algorithm implemented as &lt;code&gt;sumlist_1a&lt;/code&gt;. &lt;/p&gt;&lt;pre&gt;(defun sumlist_1a (numbers)
  (let ((sum 0))
    (foreach number numbers
      sum = sum + number)
    sum))
&lt;/pre&gt;&lt;p&gt;On the Linux machine which I normally use, evaluating &lt;code&gt;(sumlist_1a data)&lt;/code&gt; takes approximately &lt;code&gt;0.02&lt;/code&gt; seconds, while evaluating &lt;code&gt;(sumlist_6 data)&lt;/code&gt; takes about &lt;code&gt;0.003&lt;/code&gt;. I.e., &lt;code&gt;sumlist_6&lt;/code&gt; is about 6 times faster for large lists. &lt;/p&gt;&lt;h4&gt;Summary&lt;/h4&gt;&lt;p&gt;The technique shown in &lt;code&gt;sumlist_2b&lt;/code&gt; is very simple, and requires very little code. Nevertheless, it has the caveat that it will fail for arbitrarily long lists. This usually does not matter, and because this corner case is relatively unlikely to occur, the technique is tempting to use, and in fact is a good solution if the data is under your control and you know the length of the list in question is not extremely large. &lt;/p&gt;&lt;p&gt;The technique shown in &lt;code&gt;sumlist_6&lt;/code&gt; is more correct, at the sacrifice of being more complicated code. That being said, because the complication of &lt;code&gt;sumlist_6&lt;/code&gt; is factored into the implementation of the function &lt;code&gt;applyReduce&lt;/code&gt;, the actual implementation of &lt;code&gt;sumlist_6&lt;/code&gt; is as simple as &lt;code&gt;sumlist_2b&lt;/code&gt;. I would suggest putting a copy of &lt;code&gt;applyReduce&lt;/code&gt; in your personal SKILL function library, with the appropriate customer prefix of course. &lt;/p&gt;&lt;h4&gt;More to come&lt;/h4&gt;&lt;p&gt;In upcoming posts we&amp;#39;ll continue to survey the SKILL++ language using the example of summing a list. &lt;/p&gt;&lt;p&gt;Jim Newton&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Previous blog posts in this series&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/11/26/5-skill-for-the-skilled-many-ways-to-sum-a-list-part-5.aspx?postID=1316749"&gt;SKILL for the Skilled: Many Ways to Sum a List (Part 5)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/10/15/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-4.aspx?postID=1314709"&gt;SKILL for the Skilled: Many Ways to Sum a List (Part 4)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/18/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-3.aspx?postID=1314708"&gt;SKILL for the Skilled: Many Ways to Sum a List (Part 3)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/10/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-2.aspx?postID=1314605"&gt;SKILL for the Skilled: Many Ways to Sum a List (Part 2)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/05/skill-for-the-skilled-many-ways-to-sum-a-list-part-1.aspx?postID=1314591"&gt;SKILL for the Skilled: Many Ways to Sum a List (Part 1)&lt;/a&gt;&lt;/p&gt;</description><feedburner:origLink>http://www.cadence.com/Community/blogs/cic/archive/2013/01/10/6-skill-for-the-skilled-many-ways-to-sum-a-list-part-6.aspx</feedburner:origLink></item><item><title>SKILL for the Skilled: Many Ways to Sum a List (Part 5)</title><link>http://feedproxy.google.com/~r/cadence/community/blogs/196313/~3/dUNsgHggfYs/5-skill-for-the-skilled-many-ways-to-sum-a-list-part-5.aspx</link><pubDate>Mon, 26 Nov 2012 17:00:00 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:1316749</guid><dc:creator>Team SKILL</dc:creator><description>In the most recent&amp;nbsp;posts of &lt;i&gt;SKILL for the Skilled&lt;/i&gt; (see previous post &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/10/15/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-4.aspx?postID=1314709"&gt;here&lt;/a&gt;) we looked at different ways to sum a given list of numbers. The goal of these articles is not really to help you sum lists better, but rather to use a simple problem to demonstrate and compare features of the SKILL++ language. &lt;p&gt;In this posting of we show yet another implementation of &lt;code&gt;sumlist&lt;/code&gt; using an operator which will be new to many readers. While the &lt;code&gt;do&lt;/code&gt; construct is common to many lisp dialects, particularly Scheme implementations, it is somewhat controversial as some people love it, and some people hate it. Some people find it elegant and expressive, and other find it terse and awkward. I&amp;#39;ll present it here and let you decide for yourself. &lt;/p&gt;&lt;b&gt;Summing a list with the &lt;code&gt;(do ...)&lt;/code&gt; loop&lt;/b&gt; &lt;p&gt;Recall the implementation of &lt;code&gt;sumlist_1a&lt;/code&gt; which accepts a list of numbers as its argument and returns the arithmetic of these numbers. &lt;/p&gt;&lt;pre&gt;(defun sumlist_1a (numbers)&lt;br /&gt;  (let ((sum 0))&lt;br /&gt;    (foreach number numbers&lt;br /&gt;      sum = sum + number)&lt;br /&gt;    sum))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Here is yet another implementation of the &lt;code&gt;sumlist&lt;/code&gt; function which we&amp;#39;ve seen in the past several postings. This version of the function uses the &lt;code&gt;(do ...)&lt;/code&gt; construct. &lt;/p&gt;&lt;pre&gt;(defun sumlist_5a (numbers)&lt;br /&gt;  (do ((remaining  numbers (cdr remaining))&lt;br /&gt;       (sum_so_far 0       (plus sum_so_far (car remaining))))&lt;br /&gt;      ((null remaining)&lt;br /&gt;       sum_so_far)))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Evolution of Lisp&lt;/b&gt;&lt;/p&gt;There is an interesting paper which is easy to find on the Internet named &lt;a href="http://www.cs.umbc.edu/331/resources/papers/Evolution-of-Lisp.pdf%3Ci"&gt;Evolution of Lisp&lt;/a&gt; by Guy Steele and Richard Gabriel. This paper chronicles many of the features of modern Lisp languages. In the paper you can see the origins of many of the features of SKILL, including the rather obscure one we are going to look at today. Although this construct was first introduced into &lt;a href="http://en.wikipedia.org/wiki/Maclisp"&gt;Maclisp&lt;/a&gt; in 1972, &lt;i&gt;Evolution of Lisp&lt;/i&gt; refers to it as the &lt;i&gt;new-style do&lt;/i&gt;. &lt;p&gt;An excerpt from &lt;i&gt;Evolution of Lisp&lt;/i&gt;: &lt;font size="-1"&gt;&lt;/font&gt;&lt;/p&gt;&lt;font size="-1"&gt;The awful part [&lt;i&gt;of do&lt;/i&gt;] is that it uses multiple levels of parentheses as delimiters and you have to get them right or endure strange behavior; only a diehard Lisper could love such a syntax. Arguments over syntax aside, there is something to be said for recognizing that a loop that steps only one variable is pretty useless, in any programming language. It is almost always the case that one variable is used to generate successive values while another is used to accumulate a result. If the loop syntax steps only the generating variable, then the accumulating variable must be stepped &amp;quot;manually&amp;quot; by using assignment statements [...] or some other side effect. The multiple-variable do loop reflects an essential symmetry between generation and accumulation, allowing iteration to be expressed without explicit side effects: &lt;/font&gt;&lt;p&gt;&lt;font size="-1"&gt;&lt;/font&gt;&lt;b&gt;Examining the example&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;sumlist_5a&lt;/code&gt; uses &lt;code&gt;do&lt;/code&gt; to iterate two variables &lt;code&gt;remaining&lt;/code&gt; and &lt;code&gt;sum_so_far&lt;/code&gt; from their respective initial values to their final values, using respective formulas to update the variables to their &lt;i&gt;next&lt;/i&gt; values.&lt;/p&gt;&lt;strong&gt;Breaking it down: Step by Step &lt;/strong&gt;&lt;p&gt;As was mentioned above, the syntax of &lt;code&gt;do&lt;/code&gt; is somewhat off-putting. There are lots of parentheses, and several interdependent components which you have to get right. The following is an itemization of the various parts of the &lt;code&gt;(do ...)&lt;/code&gt; loop. &lt;/p&gt;&lt;ol&gt;&lt;li&gt;You normally need to declare 0 or more variables: &lt;code&gt;remaining&lt;/code&gt; and &lt;code&gt;sum_so_far&lt;/code&gt; in this case. Two variables are specified in this case, but you may use as many as you like. &lt;pre&gt;(do ((&lt;b&gt;remaining&lt;/b&gt;  &lt;i&gt;numbers&lt;/i&gt; &lt;i&gt;(cdr remaining)&lt;/i&gt;)&lt;br /&gt;     (&lt;b&gt;sum_so_far&lt;/b&gt; &lt;i&gt;0&lt;/i&gt;       &lt;i&gt;(plus sum_so_far (car remaining))&lt;/i&gt;))&lt;br /&gt;    (&lt;i&gt;(null remaining)&lt;/i&gt;&lt;br /&gt;     &lt;i&gt;sum_so_far&lt;/i&gt;))&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Specify an initial value of each variable: &lt;ul&gt;&lt;li&gt;&lt;code&gt;remaining = numbers&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;sum_so_far = 0&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;(do ((&lt;i&gt;remaining&lt;/i&gt;  &lt;b&gt;numbers&lt;/b&gt; &lt;i&gt;(cdr remaining)&lt;/i&gt;)&lt;br /&gt;     (&lt;i&gt;sum_so_far&lt;/i&gt; &lt;b&gt;0&lt;/b&gt;       &lt;i&gt;(plus sum_so_far (car remaining))&lt;/i&gt;))&lt;br /&gt;    (&lt;i&gt;(null remaining)&lt;/i&gt;&lt;br /&gt;     &lt;i&gt;sum_so_far&lt;/i&gt;))&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Specify a termination condition. The loop continues until this expression becomes TRUE. In this case: &lt;ul&gt;&lt;li&gt;&lt;code&gt;(null remaining)&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;specifying to continue until the list &lt;code&gt;remaining&lt;/code&gt; is empty. &lt;pre&gt;(do ((&lt;i&gt;remaining&lt;/i&gt;  &lt;i&gt;numbers&lt;/i&gt; &lt;i&gt;(cdr remaining)&lt;/i&gt;)&lt;br /&gt;     (&lt;i&gt;sum_so_far&lt;/i&gt; &lt;i&gt;0&lt;/i&gt;       &lt;i&gt;(plus sum_so_far (car remaining))&lt;/i&gt;))&lt;br /&gt;    (&lt;b&gt;(null remaining)&lt;/b&gt;&lt;br /&gt;     &lt;i&gt;sum_so_far&lt;/i&gt;))&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;If the condition is not yet TRUE, then each variable is updated as per the corresponding formula. In this case: &lt;ul&gt;&lt;li&gt;&lt;code&gt;remaining = (cdr remaining)&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;sum_so_far = (plus sum_so_far (car remaining))&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;(do ((&lt;i&gt;remaining&lt;/i&gt;  &lt;i&gt;numbers&lt;/i&gt; &lt;b&gt;(cdr remaining)&lt;/b&gt;)&lt;br /&gt;     (&lt;i&gt;sum_so_far&lt;/i&gt; &lt;i&gt;0&lt;/i&gt;       &lt;b&gt;(plus sum_so_far (car remaining))&lt;/b&gt;))&lt;br /&gt;    (&lt;i&gt;(null remaining)&lt;/i&gt;&lt;br /&gt;     &lt;i&gt;sum_so_far&lt;/i&gt;))&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;When the condition is TRUE, the loop terminates and the specified value is returned. This value is usually depends on some of the iteration variables. In this case: &lt;ul&gt;&lt;li&gt;&lt;code&gt;sum_so_far&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;(do ((&lt;i&gt;remaining&lt;/i&gt;  &lt;i&gt;numbers&lt;/i&gt; &lt;i&gt;(cdr remaining)&lt;/i&gt;)&lt;br /&gt;     (&lt;i&gt;sum_so_far&lt;/i&gt; &lt;i&gt;0&lt;/i&gt;       &lt;i&gt;(plus sum_so_far (car remaining))&lt;/i&gt;))&lt;br /&gt;    (&lt;i&gt;(null remaining)&lt;/i&gt;&lt;br /&gt;     &lt;i&gt;sum_so_far&lt;/i&gt;))&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;It is not shown above, but you may optionally include 1 or more expressions in the body of the &lt;code&gt;(do ...)&lt;/code&gt;. &lt;pre&gt;(do ((&lt;i&gt;remaining&lt;/i&gt;  &lt;i&gt;numbers&lt;/i&gt; &lt;i&gt;(cdr remaining)&lt;/i&gt;)&lt;br /&gt;     (&lt;i&gt;sum_so_far&lt;/i&gt; &lt;i&gt;0&lt;/i&gt;       &lt;i&gt;(plus sum_so_far (car remaining))&lt;/i&gt;))&lt;br /&gt;    (&lt;i&gt;(null remaining)&lt;/i&gt;&lt;br /&gt;     &lt;i&gt;sum_so_far&lt;/i&gt;)&lt;br /&gt;  &lt;b&gt;(println remaining)&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;(printf &amp;quot;partial sum = %L\n&amp;quot; sum_so_far)&lt;/b&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Variations &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;One way to think of the SKILL &lt;code&gt;do&lt;/code&gt; is as a mixture or generalization of several iteration constructs. &lt;/p&gt;&lt;p&gt;&lt;b&gt;Do as for&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The following is like a &lt;code&gt;(for ...)&lt;/code&gt; loop. &lt;/p&gt;&lt;pre&gt;(do ((i 0 i+1))&lt;br /&gt;    (i==100 &lt;br /&gt;     t) &lt;i&gt;; return t because for always returns t&lt;/i&gt;&lt;br /&gt;  (println i))&lt;br /&gt;&lt;/pre&gt;... is equivalent to ... &lt;pre&gt;(for i 0 100&lt;br /&gt;  (println i))&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;&lt;p&gt;Do as foreach&lt;/p&gt;&lt;/b&gt;&lt;p&gt;The following is like a &lt;code&gt;(foreach ...)&lt;/code&gt; loop. &lt;/p&gt;&lt;pre&gt;(let ((some_list &amp;#39;(a b c d)))&lt;br /&gt;  (do ((sub  some_list        (cdr sub))&lt;br /&gt;       (item (car some_list)  (cadr sub)))&lt;br /&gt;      ((null sub) &lt;br /&gt;       some_list) &lt;i&gt;; return some_list because foreach returns the list it iterated over&lt;/i&gt;&lt;br /&gt;    (println item)))&lt;br /&gt;&lt;/pre&gt;... is equivalent to ... &lt;pre&gt;(let ((some_list &amp;#39;(a b c d)))&lt;br /&gt;  (foreach i some_list&lt;br /&gt;    (println i)))&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;&lt;p&gt;Do as a mixture of for and foreach&lt;/p&gt;&lt;/b&gt;&lt;p&gt;The &lt;code&gt;(foreach ...)&lt;/code&gt; iterates successively through a given list of items. The &lt;code&gt;(for ...)&lt;/code&gt; loop iterates successively through a range of integers, given the lower and upper bounds of the range. If you want to iterate one variable through a given list while simultaneously iterating another variable through a range of integers, you can use the &lt;code&gt;(do ...)&lt;/code&gt; loop. &lt;/p&gt;&lt;pre&gt;(let ((some_list &amp;#39;(a b c d ...)))&lt;br /&gt;  (do ((index 0               (add1 index))&lt;br /&gt;       (sub   some_list       (cdr sub))&lt;br /&gt;       (item  (car some_list) (cadr sub)))&lt;br /&gt;      ((null sub) &lt;br /&gt;       t)&lt;br /&gt;    (printf &amp;quot;The %d&amp;#39;th of the list is %L\n&amp;quot; index item)))&lt;br /&gt;&lt;/pre&gt;Which produces the following output. &lt;pre&gt;The 0&amp;#39;th of the list is a&lt;br /&gt;The 1&amp;#39;th of the list is b&lt;br /&gt;The 2&amp;#39;th of the list is c&lt;br /&gt;The 3&amp;#39;th of the list is d&lt;br /&gt;The 4&amp;#39;th of the list is e&lt;br /&gt;The 5&amp;#39;th of the list is f&lt;br /&gt;The 6&amp;#39;th of the list is g&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;&lt;p&gt;Summary&lt;/p&gt;&lt;/b&gt;&lt;p&gt;The SKILL &lt;code&gt;do&lt;/code&gt; can be tricky to use. It allows the programmer control of several parallel iteration variables, all of which are potentially &lt;i&gt;incremented&lt;/i&gt; according to different rules. You may also explicitly determine the return value, which is fixed and useless for other iteration constructs such as &lt;code&gt;(for ...)&lt;/code&gt;. You may also specify a series of expressions to evaluate when the iteration finishes while the iteration variables are still in scope holding their &lt;i&gt;final&lt;/i&gt; values. &lt;/p&gt;&lt;p&gt;Hopefully you can use the steps above as sort of a cookbook. &lt;/p&gt;&lt;b&gt;&lt;p&gt;More to come &lt;/p&gt;&lt;/b&gt;In upcoming posts we&amp;#39;ll continue to survey the SKILL++ language using the example of summing a list. &lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;p&gt;See Also&lt;/p&gt;&lt;/b&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.cs.umbc.edu/331/resources/papers/Evolution-of-Lisp.pdf"&gt;Evolution of Lisp&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Maclisp"&gt;Maclisp&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Jim Newton&lt;/p&gt;&lt;h4&gt;&lt;/h4&gt;</description><feedburner:origLink>http://www.cadence.com/Community/blogs/cic/archive/2012/11/26/5-skill-for-the-skilled-many-ways-to-sum-a-list-part-5.aspx</feedburner:origLink></item><item><title>SKILL for the Skilled: Many Ways to Sum a List (Part 4)</title><link>http://feedproxy.google.com/~r/cadence/community/blogs/196313/~3/78XklT0Dxjg/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-4.aspx</link><pubDate>Mon, 15 Oct 2012 15:27:00 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:1314709</guid><dc:creator>Team SKILL</dc:creator><description>In the previous posts &lt;i&gt;SKILL for the Skilled: Many Ways to Sum a List (Parts &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/05/skill-for-the-skilled-many-ways-to-sum-a-list-part-1.aspx?postID=1314591"&gt;1,&lt;/a&gt; &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/10/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-2.aspx?postID=1314605"&gt;2,&lt;/a&gt; and &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/18/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-3.aspx?postID=1314708"&gt;3&lt;/a&gt;)&lt;/i&gt; we looked at several ways to sum a given list of numbers. We ignored the cases of the given list being very long. In this post, we will examine a way to sum the elements of arbitrarily long lists using recursive functions. &lt;p&gt;The approach shown in this post (part 4) will only work in Virtuoso IC 6.1; it depends on features which are not available in IC 5.1.41 and earlier. In particular we&amp;#39;ll look at the &lt;code&gt;optimizeTailCall&lt;/code&gt; status flag and at &lt;code&gt;unwindProtect&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;You may read this post in either of two ways. If you would like a way to make arbitrarily deep recursion work in SKILL++, you can look at the usage of the &lt;code&gt;callWithOptimizeTailCall&lt;/code&gt; function in &lt;code&gt;sumlist_4a&lt;/code&gt;. If you&amp;#39;d like to know how it works, look at the section Some Trickery. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;What about large lists?&lt;/strong&gt;&lt;/p&gt;One disadvantage of the type of recursive function shown in &lt;code&gt;sumlist_3a&lt;/code&gt; (seen earlier) is that every pending call to a function in SKILL++ requires stack space, and stack space is limited. &lt;p&gt;The two functions &lt;code&gt;sumlist_1a&lt;/code&gt; and &lt;code&gt;sumlist_3a&lt;/code&gt; differ in their ability to handle long lists. To demonstrate this limitation it helps to programmatically generate a very long list. The following expressions will generate a list of length 16,384. &lt;/p&gt;&lt;pre&gt;data = (list 1.1 -2.1 2.3 -.04)
(for i 1 12
  data = (append data data))
&lt;/pre&gt;&lt;p&gt;Now what happens if we try to add up 16,384 numbers? &lt;/p&gt;&lt;pre&gt;(sumlist_1a data)
=&amp;gt; 5160.96

(sumlist_3a data)
&lt;i&gt;
*Error* sumlist_3a: Runtime Stack Overflow!!!
&amp;lt;&amp;lt;&amp;lt; Stack Trace &amp;gt;&amp;gt;&amp;gt;
sumlist_3a(cdr(numbers))
(car(numbers) + sumlist_3a(cdr(numbers)))
if(numbers (car(numbers) + sumlist_3a(cdr(numbers))) 0)
sumlist_3a(cdr(numbers))
(car(numbers) + sumlist_3a(cdr(numbers)))
if(numbers (car(numbers) + sumlist_3a(cdr(numbers))) 0)
sumlist_3a(cdr(numbers))
(car(numbers) + sumlist_3a(cdr(numbers)))
if(numbers (car(numbers) + sumlist_3a(cdr(numbers))) 0)
sumlist_3a(cdr(numbers))
...
&lt;/i&gt;
&lt;/pre&gt;&lt;pre&gt;(sumlist_3b data)
&lt;i&gt;*Error* unknown: Runtime Stack Overflow!!!
&amp;lt;&amp;lt;&amp;lt; Stack Trace &amp;gt;&amp;gt;&amp;gt;
sum((sum_so_far + car(rest)) cdr(rest))
if(rest (sum (sum_so_far + car(rest)) cdr(rest)) sum_so_far)
sum((sum_so_far + car(rest)) cdr(rest))
if(rest (sum (sum_so_far + car(rest)) cdr(rest)) sum_so_far)
sum((sum_so_far + car(rest)) cdr(rest))
if(rest (sum (sum_so_far + car(rest)) cdr(rest)) sum_so_far)
sum((sum_so_far + car(rest)) cdr(rest))
if(rest (sum (sum_so_far + car(rest)) cdr(rest)) sum_so_far)
sum((sum_so_far + car(rest)) cdr(rest))
if(rest (sum (sum_so_far + car(rest)) cdr(rest)) sum_so_far)
...&lt;/i&gt;
&lt;/pre&gt;&lt;p&gt;It seems there is not enough stack space to add these numbers using the types of recursive functions we have seen up until now. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tail call optimization&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The subtle difference between &lt;code&gt;sumlist_3a&lt;/code&gt; and &lt;code&gt;sumlist_3b&lt;/code&gt; is not very important in the simple case, but allows for a very special optimization called &lt;i&gt;tail call optimization&lt;/i&gt;. The maximum length of the list you may pass to function &lt;code&gt;sumlist_3a&lt;/code&gt; is limited by the stack-space. As seen in the stack-trace above, if the list is too long, we get the error &lt;code&gt;Runtime Stack Overflow!!!&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;When tail call optimization is enabled, a function call in tail position does not consume additional stack space, thus allowing such a function call (even a recursive function call) to work like a &lt;code&gt;GOTO&lt;/code&gt;. &lt;/p&gt;&lt;pre&gt;(defun callWithOptimizeTailCall (thunk)
  (let ((save (status optimizeTailCall)))
    (sstatus optimizeTailCall t)
    (unwindProtect
      (thunk)
      (sstatus optimizeTailCall save))))
&lt;/pre&gt;&lt;p&gt;In SKILL++, tail call optimization is a run-time switch. This means you need not do anything special when loading your code, but you have to enable the optimization at run-time. The function &lt;code&gt;callWithOptimizeTailCall&lt;/code&gt;, defined above, is written to allow the caller to specify which bit of code needs the optimization. It can be used as shown in &lt;code&gt;sumlist_4a&lt;/code&gt; defined here. &lt;/p&gt;&lt;pre&gt;(defun sumlist_4a (numbers)
  (labels ((sum (sum_so_far rest)
             (if rest
                 (sum (plus sum_so_far (car rest))
                      (cdr rest))
                 sum_so_far)))
    (callWithOptimizeTailCall
       (lambda ()
         (sum 0 numbers)))))
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/pre&gt;&lt;strong&gt;OK, Let&amp;#39;s Test It&lt;/strong&gt; &lt;p&gt;So does it work? &lt;/p&gt;&lt;pre&gt;(sumlist_4a data)
&lt;i&gt;==&amp;gt; 5160.96&lt;/i&gt;
&lt;/pre&gt;&lt;p&gt;Yippie! no stack trace. SKILL++ was able to make the recursive call 16,384 times with no problem. &lt;/p&gt;&lt;p&gt;Okay, let&amp;#39;s stress test it. &lt;/p&gt;&lt;pre&gt;(progn data = (append data data)
       data = (append data data)
       data = (append data data)
       (length data))
&lt;i&gt;==&amp;gt;131072 &lt;/i&gt;
&lt;/pre&gt;&lt;p&gt;Now let&amp;#39;s see if SKILL++ can add up a list of 131,072 numbers by a recursive function:&lt;/p&gt;&lt;pre&gt;(sumlist_4a data)
&lt;i&gt;==&amp;gt;41287.68 &lt;/i&gt;
&lt;/pre&gt;&lt;p&gt;Yes. No problem. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Manipulating optimizeTailCall&lt;/strong&gt;&lt;/p&gt;You don&amp;#39;t really need to understand how &lt;code&gt;callWithOptimizeTailCall&lt;/code&gt; works in order to use it. To use it, the one or more expressions you&amp;#39;d like to evaluate with the optimization enabled must be wrapped in &lt;code&gt;(lambda () ...)&lt;/code&gt; and that function of no arguments should be passed to the &lt;code&gt;callWithOptimizeTailCall&lt;/code&gt;. &lt;pre&gt;(callWithOptimizeTailCall
  (lambda ()&lt;i&gt;
     ... some code ...
     ... maybe some more code ...&lt;/i&gt;
  ))
&lt;/pre&gt;&lt;p&gt;The promise of &lt;code&gt;callWithOptimizeTailCall&lt;/code&gt; is that it will call the given function with tail call optimization enabled, but have no lasting effect on the global &lt;code&gt;optimizeTailCall&lt;/code&gt; setting. I.e., if &lt;code&gt;optimizeTailCall&lt;/code&gt; was enabled, it will remain enabled; and if it was disabled, it will remain disabled. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Some Trickery&lt;/strong&gt;&lt;/p&gt;The implementation of &lt;code&gt;callWithOptimizeTailCall&lt;/code&gt; uses some pretty low level trickery which some of the readers might find interesting. &lt;code&gt;status&lt;/code&gt; E.g., &lt;code&gt;(status debugMode)&lt;/code&gt; &lt;br /&gt;returns either &lt;code&gt;t&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt; depending on the value of the named (unquoted) status flag. There are several other documented status flags in SKILL. Perhaps the most commonly used ones are &lt;code&gt;debugMode&lt;/code&gt; and &lt;code&gt;printinfix&lt;/code&gt;. See the Cadence on-line documentation for explanation of others. &lt;code&gt;debugMode&lt;/code&gt; Instructs the SKILL VM compiler to include additional debug information into the compiled instructions. &lt;code&gt;printinfix&lt;/code&gt; Instructs the SKILL pretty-printer whether to use infix operators (such as &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;||&lt;/code&gt;, &lt;code&gt;&amp;#39;&lt;/code&gt;, and &lt;code&gt;-&amp;gt;&lt;/code&gt;) and C-style function call syntax such as &lt;code&gt;(1+2+3)&lt;/code&gt;, or whether to use function names (such as &lt;code&gt;plus&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt;, &lt;code&gt;quote&lt;/code&gt;, and &lt;code&gt;getq&lt;/code&gt;), and use lisp-style function call syntax such as &lt;code&gt;(plus 1 2 3)&lt;/code&gt;. &lt;code&gt;sstatus&lt;/code&gt; E.g., &lt;code&gt;(sstatus debugMode t)&lt;/code&gt; &lt;br /&gt;Sets the value of the named global status flag. All the flags which are available to &lt;code&gt;status&lt;/code&gt; are available for &lt;code&gt;sstatus&lt;/code&gt;. &lt;code&gt;unwindProtect&lt;/code&gt; E.g., &lt;code&gt;(unwindProtect (unsafe_function) (deleteFile fileName))&lt;/code&gt;. &lt;br /&gt;This is used when calling a function or evaluating an expression which might trigger an error. &lt;code&gt;unwindProtect&lt;/code&gt; takes two operands: an expression to evaluate, and a clean-up expression. The clean-up expression will get evaluated regardless of whether the first expression triggered an error or not. However, unlike &lt;code&gt;errset&lt;/code&gt; it does not suppress the error. In the example in &lt;code&gt;callWithOptimizeTailCall&lt;/code&gt;, the use of &lt;code&gt;unwindProtect&lt;/code&gt; assures that &lt;code&gt;(sstatus optimizeTailCall save)&lt;/code&gt;, i.e., the call to restore the &lt;code&gt;optimizeTailCall&lt;/code&gt; status occurs, even if the given function, &lt;code&gt;thunk&lt;/code&gt; triggered an error. &lt;code&gt;optimizeTailCall&lt;/code&gt; E.g., &lt;code&gt;(sstatus optimizeTailCall t)&lt;/code&gt; &lt;br /&gt;Controls whether tail-call optimization is enabled. Remember to always restore &lt;code&gt;optimizeTailCall&lt;/code&gt; to its previous value so as never to globally effect this flag. &lt;p&gt;&lt;strong&gt;Quick Review&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;In this post you saw a cookbook way of modifying a particular type of recursive function so that it does not need significant stack space at run-time. The main trick is to write the recursion using tail-call style, and use the function &lt;code&gt;callWithOptimizeTailCall&lt;/code&gt; to let SKILL++ do the work for you. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;More to come&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;In the upcoming postings we&amp;#39;ll look at even more variations of list summing. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;See Also&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Tail_call"&gt;Tail Call&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Jim Newton&lt;/p&gt;</description><feedburner:origLink>http://www.cadence.com/Community/blogs/cic/archive/2012/10/15/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-4.aspx</feedburner:origLink></item><item><title>SKILL for the Skilled: Many Ways to Sum a List (Part 3)</title><link>http://feedproxy.google.com/~r/cadence/community/blogs/196313/~3/Ylr4q5V8xmQ/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-3.aspx</link><pubDate>Tue, 18 Sep 2012 21:00:00 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:1314708</guid><dc:creator>Team SKILL</dc:creator><description>In &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/05/skill-for-the-skilled-many-ways-to-sum-a-list-part-1.aspx?postID=1314591"&gt;Part 1&lt;/a&gt; and &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/10/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-2.aspx?postID=1314605"&gt;Part 2&lt;/a&gt; of this series&amp;nbsp;of posts, I showed a couple of ways to sum up a given list of numbers. In this post, I want to show a couple of ways to use recursive functions to do this. &lt;p&gt;&lt;b&gt;Recall the sumlist_1a function&lt;/b&gt;&lt;/p&gt;&lt;p&gt;In a previous posting the function &lt;code&gt;sumlist_1a&lt;/code&gt; was defined. &lt;/p&gt;&lt;pre&gt;(defun sumlist_1a (numbers)
  (let ((sum 0))
    (foreach number numbers
      sum = sum + number)
    sum))
&lt;/pre&gt;&lt;p&gt;Describing this algorithm in words, we see that it does not express the mathematical relationship very well,&amp;nbsp;but it does describe how a Von Neumann machine would perform the calculation. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Initialize an accumulator to 0 &lt;/li&gt;&lt;li&gt;Keep incrementing the accumulator by the successive element of the list &lt;/li&gt;&lt;li&gt;When the list is exhausted, return the accumulator &lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Implementation with simple recursion&lt;/b&gt; &lt;p&gt;The following implementation of &lt;code&gt;sumlist_3a&lt;/code&gt; is an example of simple recursion. &lt;/p&gt;&lt;pre&gt;(defun sumlist_3a (numbers)
  (if numbers
      (plus (car numbers)
            (sumlist_3a (cdr numbers)))
      0))
&lt;/pre&gt;&lt;p&gt;Expressing this algorithm in words, you can see that it is more elegant than &lt;code&gt;sumlist_1a&lt;/code&gt; as the code actually expresses a mathematical relationship. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;The sum of the empty list is &lt;code&gt;0&lt;/code&gt;&lt;/li&gt;&lt;li&gt;The sum of a N element list is the first element plus the sum of the remaining elements&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;An advantage of recursive functions such as &lt;code&gt;sumlist_3a&lt;/code&gt; is that they are elegant. They often require less code because there is no need to maintain state; e.g., there is no accumulator variable, and no variables are modified during the evaluation of the function. &lt;/p&gt;&lt;b&gt;Implementation with tail recursion&lt;/b&gt; &lt;p&gt;The &lt;code&gt;sumlist_3b&lt;/code&gt; function is a tail recursive version of &lt;code&gt;sumlist_3a&lt;/code&gt;. &lt;/p&gt;&lt;pre&gt;(defun sumlist_3b (numbers)
  (labels ((sum (sum_so_far rest)
             (if rest
                 (sum (plus (car rest) sum_so_far)
                      (cdr rest))
                 sum_so_far)))
    (sum 0 numbers)))
&lt;/pre&gt;&lt;p&gt;An obvious drawback of this type of recursive function is that it is more difficult for the human to read than simple recursion. &lt;/p&gt;&lt;p&gt;Tail recursion is a technique which can be used to enable recursive function to require no more stack space than iterative functions. There is a pretty clear explanation on &lt;a href="http://en.wikipedia.org/wiki/Tail_call"&gt;Wikipedia&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;The main difference, computation-wise, between &lt;code&gt;sumlist_3a&lt;/code&gt; and &lt;code&gt;sumlist_3b&lt;/code&gt; is the following. In &lt;code&gt;sumlist_3a&lt;/code&gt; the final computation the function does is to call the &lt;code&gt;plus&lt;/code&gt; function. For example the top level call to sumlist_3a with &lt;code&gt;(1 2 3 4 5 6 7)&lt;/code&gt; must completely finish processing &lt;code&gt;(2 3 4 5 6 7)&lt;/code&gt; before it can add the &lt;code&gt;1&lt;/code&gt;--the call to &lt;code&gt;(plus 1 ...)&lt;/code&gt; cannot occur before the recursive call to &lt;code&gt;sumlist_3a&lt;/code&gt; returns. &lt;/p&gt;&lt;p&gt;In &lt;code&gt;sumlist_3b&lt;/code&gt;, on the other hand, the computation order is reversed. In the local function, &lt;code&gt;sum&lt;/code&gt;, the &lt;code&gt;(plus 1 ...)&lt;/code&gt; happens first. That partial sum is passed as the &lt;code&gt;sum_so_far&lt;/code&gt; parameter. The final thing the local function does is call itself recursively. There is no pending operating waiting for the recursive call to return. &lt;/p&gt;&lt;p&gt;We&amp;#39;ll talk more about why this is important in an upcoming posting of &lt;i&gt;SKILL for the Skilled -- Many Ways to Sum a List&lt;/i&gt;. &lt;/p&gt;&lt;b&gt;Testing the functions&lt;/b&gt; &lt;p&gt;If we call &lt;code&gt;sumlist_1a&lt;/code&gt;, &lt;code&gt;sumlist_3a&lt;/code&gt;, and &lt;code&gt;sumlist_3b&lt;/code&gt; on some examples we see that they return the same thing. &lt;/p&gt;&lt;pre&gt;(sumlist_1a nil)
=&amp;gt; 0

(sumlist_3a nil)
=&amp;gt; 0

(sumlist_3b nil)
=&amp;gt; 0

(sumlist_1a &amp;#39;(3.4))
=&amp;gt; 3.4

(sumlist_3a &amp;#39;(3.4))
=&amp;gt; 3.4

(sumlist_3b &amp;#39;(3.4))
=&amp;gt; 3.4

(sumlist_1a &amp;#39;(1 2 3 4 5 6 7))
=&amp;gt; 28

(sumlist_3a &amp;#39;(1 2 3 4 5 6 7))
=&amp;gt; 28

(sumlist_3b &amp;#39;(1 2 3 4 5 6 7))
=&amp;gt; 28
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Computation order&lt;/b&gt;&lt;/p&gt;&lt;p&gt;That the computation order of &lt;code&gt;sumlist_3a&lt;/code&gt; and &lt;code&gt;sumlist_3b&lt;/code&gt; are opposite can be seen by tracing the &lt;code&gt;plus&lt;/code&gt; function. &amp;nbsp;&lt;/p&gt;&lt;pre&gt;(trace plus)
&lt;i&gt;==&amp;gt;(plus)&lt;/i&gt;
(sumlist_3a &amp;#39;(1 2 3 4 5))
||||||(5 + 0)
||||||plus --&amp;gt; 5
|||||(4 + 5)
|||||plus --&amp;gt; 9
||||(3 + 9)
||||plus --&amp;gt; 12
|||(2 + 12)
|||plus --&amp;gt; 14
||(1 + 14)
||plus --&amp;gt; 15
&lt;i&gt;==&amp;gt;15&lt;/i&gt;
(sumlist_3b &amp;#39;(1 2 3 4 5))
||||(1 + 0)
||||plus --&amp;gt; 1
|||||(2 + 1)
|||||plus --&amp;gt; 3
||||||(3 + 3)
||||||plus --&amp;gt; 6
|||||||(4 + 6)
|||||||plus --&amp;gt; 10
||||||||(5 + 10)
||||||||plus --&amp;gt; 15
&lt;i&gt;==&amp;gt;15&lt;/i&gt;
&lt;/pre&gt;&lt;p&gt;Looking at the trace output, we see that &lt;code&gt;sumlist_3a&lt;/code&gt; calls plus with first argument being first 5, then 4, 3, 2, and finally&amp;nbsp;1. However, &lt;code&gt;sumlist_3b&lt;/code&gt;, &lt;code&gt;plus&lt;/code&gt; is called first with first argument being 1, then with 2, 3, 4, and finally with 5. Since integer addition is commutative, associative, and side effect free, both algorithms give the same result. &lt;/p&gt;&lt;p&gt;This difference in the two computation models might be important in some situations if some function other than &lt;code&gt;plus&lt;/code&gt; is used. For example, if a function with side effects is used, you might find that the side-effects happen in a different order. &lt;/p&gt;&lt;p&gt;For example, replacing the &lt;code&gt;0&lt;/code&gt; with &lt;code&gt;nil&lt;/code&gt;, replacing the &lt;code&gt;plus&lt;/code&gt; function with &lt;code&gt;cons&lt;/code&gt;, and renaming the local function from &lt;code&gt;sum&lt;/code&gt; to &lt;code&gt;rev&lt;/code&gt; we have two different and useful functions: a list-copy function and a list-reverse function. &lt;/p&gt;&lt;pre&gt;(defun copy_3e (numbers)
  (if numbers
      (cons (car numbers)
            (copy_3e (cdr numbers)))
      nil))

(defun reverse_3f (numbers)
  (labels ((rev (list_so_far rest)
             (if rest
                 (rev (cons (car rest) list_so_far)
                      (cdr rest))
                 list_so_far)))
    (rev nil numbers)))
&lt;/pre&gt;&lt;p&gt;Testing these functions we see the following results: &lt;/p&gt;&lt;pre&gt;(copy_3e &amp;#39;(1 2 3 4 5))
&lt;i&gt;==&amp;gt;(1 2 3 4 5)&lt;/i&gt;
(reverse_3f &amp;#39;(1 2 3 4 5))
&lt;i&gt;==&amp;gt;(5 4 3 2 1)&lt;/i&gt;
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Review&lt;/b&gt; &lt;/p&gt;&lt;p&gt;In the paragraphs above we looked at two different types of recursive functions. The two techniques usually give compatible results. However, depending on the application one technique may be preferable because of computation order or order of side effects. &lt;/p&gt;&lt;b&gt;More to come&lt;/b&gt; &lt;p&gt;I&amp;#39;ve alluded several times to the issue that these recursive functions fail for very long lists. In the next post we&amp;#39;ll look at some ways of dealing with this issue. &lt;/p&gt;&lt;p&gt;&lt;b&gt;See Also&lt;/b&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Tail_call"&gt;Tail Recursion&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Jim Newton&lt;/p&gt;</description><feedburner:origLink>http://www.cadence.com/Community/blogs/cic/archive/2012/09/18/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-3.aspx</feedburner:origLink></item><item><title>SKILL for the Skilled: Many Ways to Sum a List (Part 2)</title><link>http://feedproxy.google.com/~r/cadence/community/blogs/196313/~3/oMQ-68bwMR4/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-2.aspx</link><pubDate>Mon, 10 Sep 2012 15:53:00 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:1314605</guid><dc:creator>Team SKILL</dc:creator><description>In the previous posting, &lt;i&gt;&lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2012/09/05/skill-for-the-skilled-many-ways-to-sum-a-list-part-1.aspx?postID=1314591"&gt;SKILL for the Skilled: Many Ways to Sum a List (Part 1&lt;/a&gt;)&lt;/i&gt;, I showed a couple of ways to arithmetically sum up a given list of numbers. In particular, I presenting the following function definition. &lt;pre&gt;(defun sumlist_1b (numbers)
  (apply plus numbers))
&lt;/pre&gt;&lt;p&gt;In this posting, (Part 2), we&amp;#39;ll look at improving this implementation by using the &lt;code&gt;apply&lt;/code&gt; function with more than two arguments to enable handling of short lists. &lt;/p&gt;&lt;b&gt;Limitations of the sublist_1b&lt;/b&gt; &lt;p&gt;This function, &lt;code&gt;sumlist_1b&lt;/code&gt;, is &lt;i&gt;usually&lt;/i&gt; able to add up the numbers in a given list. It is the fastest way I know of from SKILL++ to sum a list, and because of that it is tempting to ignore several cases where it fails. &lt;/p&gt;&lt;ol&gt;&lt;li&gt;the &lt;code&gt;nil&lt;/code&gt; list &lt;/li&gt;&lt;li&gt;a singleton list &lt;/li&gt;&lt;li&gt;a list whose length is longer than 65535 in length. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;An attempt to sum the elements of the empty list results in the following: &lt;/p&gt;&lt;pre&gt;(sumlist_1b nil)
*Error* plus: too few arguments (at least 2 expected, 0 given) - nil
&amp;lt;&amp;lt;&amp;lt; Stack Trace &amp;gt;&amp;gt;&amp;gt;
apply(plus numbers)
sumlist_1b(nil)
&lt;/pre&gt;&lt;p&gt;An attempt to sum the elements of a singleton list results in the following: &lt;/p&gt;&lt;pre&gt;(sumlist_1b &amp;#39;(3.4))
*Error* plus: too few arguments (at least 2 expected, 1 given) - (3.4)
&amp;lt;&amp;lt;&amp;lt; Stack Trace &amp;gt;&amp;gt;&amp;gt;
apply(plus numbers)
sumlist_1b(&amp;#39;(3.4))
&lt;/pre&gt;&lt;p&gt;It is somewhat curious but notable that the SKILL &lt;code&gt;plus&lt;/code&gt; function is unable to be called with zero or a single argument. &lt;/p&gt;&lt;b&gt;Sometimes you may be able to ignore this limitation&lt;/b&gt; &lt;p&gt;If you are in charge of the data, for example if your program is generating the lists of numbers which you&amp;#39;d like to sum up, you may already know that that in your application &lt;code&gt;sumlist_1b&lt;/code&gt; will never be called with nil, singleton lists, or extremely long lists. If that is the case there is no need to worry; &lt;code&gt;sumlist_1b&lt;/code&gt; works just fine despite its limitation. However, you need a more robust version of this function, read on. &lt;/p&gt;&lt;p&gt;&lt;b&gt;Try #1 to fix sumlist_1b&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The first two of the above limitations can be solved in a straightforward way as special cases in the function implementation. &lt;/p&gt;&lt;pre&gt;(defun sumlist_2a (numbers)
  (cond
    ((cdr numbers)          ; if there is more than one element
     (apply plus numbers))
    ((null numbers)         ; if zero elements
     0)
    (t                      ; a singleton list
     (car numbers))))
&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;sumlist_2a&lt;/code&gt; function contains special cases for the &lt;code&gt;nil&lt;/code&gt; list and for a singleton list. The tests in the &lt;code&gt;(cond ...)&lt;/code&gt; are ordered such that the most common case comes first: &lt;code&gt;(cdr numbers)&lt;/code&gt;. If the given list has more than one element, then the &lt;code&gt;cdr&lt;/code&gt; function will return non-nil. I am assuming that this is the most common situation. &lt;/p&gt;&lt;b&gt;Using apply with 3 or more arguments&lt;/b&gt; &lt;p&gt;Rather than adding additional complexity as in &lt;code&gt;sumlist_2a&lt;/code&gt;, there is a simpler way to extend &lt;code&gt;sumlist_1b&lt;/code&gt; to work on nil and singleton lists. &lt;/p&gt;&lt;p&gt;With two arguments, the &lt;code&gt;apply&lt;/code&gt; function, calls the designated function with the given argument list. A standard (and handy) feature of &lt;code&gt;apply&lt;/code&gt; is that if it is given more than two arguments, the second to penultimate ones have the special meaning that they are implicitly prepended to the final one. For example: &lt;/p&gt;&lt;pre&gt;(apply plus 1 2 3 &amp;#39;(4 5 6 7 8))
&lt;/pre&gt;&lt;p&gt;is equivalent to &lt;/p&gt;&lt;pre&gt;(apply plus &amp;#39;(1 2 3 4 5 6 7 8))
&lt;/pre&gt;&lt;p&gt;This feature of &lt;code&gt;apply&lt;/code&gt; is pretty common for Lisp dialects such as Common Lisp, elisp (emacs lisp), and MIT/GNU Scheme. One would naturally expect the &lt;code&gt;apply&lt;/code&gt; function in SKILL to work the same way, and fortunately it does. &lt;/p&gt;&lt;p&gt;This feature of &lt;code&gt;apply&lt;/code&gt; is of course not very interesting for lists whose contents are explicitly given, because if you can type &lt;code&gt;(apply plus 1 2 3 &amp;#39;(4 5 6 7 8))&lt;/code&gt; you can as easily type &lt;code&gt;(apply plus &amp;#39;(1 2 3 4 5 6 7 8))&lt;/code&gt;. But it does allow us to rewrite the &lt;code&gt;sumlist_1b&lt;/code&gt; function as follows. &lt;/p&gt;&lt;pre&gt;(defun sumlist_2b (numbers)
  (apply plus 0 0 numbers))
&lt;/pre&gt;&lt;b&gt;Why does this work?&lt;/b&gt; &lt;p&gt;This works because prepending &lt;code&gt;0&lt;/code&gt; twice to the argument list of &lt;code&gt;plus&lt;/code&gt; assures that &lt;code&gt;plus&lt;/code&gt; has at least two arguments. Also, &lt;code&gt;zero&lt;/code&gt; is the arithmetic identity for addition. Arithmetically adding two zeros does not effect the sum -- neither in value nor in type.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Similar problems&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Is there a way to construct a function such as &lt;code&gt;sumlist_1b&lt;/code&gt;, &lt;code&gt;sumlist_2a&lt;/code&gt;, or &lt;code&gt;sumlist_2b&lt;/code&gt; which will work for other types of operations like maximization and minimization? &lt;/p&gt;&lt;p&gt;Using the model shown in &lt;code&gt;sumlist_1b&lt;/code&gt;, we can implement a function that will return the maximum element of a given list, provided the list has more than one element. &lt;/p&gt;&lt;pre&gt;(defun maxlist_2c (numbers)
  (apply max numbers))
&lt;/pre&gt;&lt;p&gt;However, &lt;code&gt;maxlist_2c&lt;/code&gt; fails if the list has one or zero elements. If you want to be able to maximize a list even it it is &lt;code&gt;nil&lt;/code&gt; or a singleton list, you can do something similar to &lt;code&gt;sumlist_2a&lt;/code&gt;. The maximum element of a singleton list is the first (only) element. However, you&amp;#39;d have to define what you mean by the maximum element of an empty list. It does not really make sense in general because the &lt;i&gt;max&lt;/i&gt; operation does not have an identity element. While &lt;code&gt;x+0=0+x=x&lt;/code&gt;, there is no number, I, such that &lt;code&gt;max{x,I}=max{I,x}=x&lt;/code&gt;. For this reason the function &lt;code&gt;maxlist_2d&lt;/code&gt; triggers an error for the empty list. &lt;/p&gt;&lt;p&gt;Even though it does not make sense in general, for your particular application it very well might have a meaning; so you can change the call to error by some other code as you like. &lt;/p&gt;&lt;pre&gt;(defun maxlist_2d (numbers)
  (cond
    ((cdr numbers)
     (apply max numbers))
    ((null numbers)
     (error &amp;quot;cannot find maximum of the empty list&amp;quot;))
    (t
     (car numbers))))
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;More to come&lt;/b&gt;&lt;/p&gt;&lt;p&gt;See Also &lt;/p&gt;&lt;h4&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://groups.csail.mit.edu/mac/projects/scheme/"&gt;MIT/GNU Scheme&lt;/a&gt; -- &lt;a href="http://people.csail.mit.edu/jaffer/r5rs_8.html#IDX411"&gt;apply&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.lispworks.com/documentation/HyperSpec/Front/"&gt;Common Lisp&lt;/a&gt; -- &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_apply.htm#apply"&gt;APPLY&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gnu.org/software/emacs/manual/elisp.html"&gt;Emacs Lisp&lt;/a&gt; -- &lt;a href="http://www.gnu.org/software/emacs/manual/html_node/elisp/Calling-Functions.html#index-apply-724"&gt;apply&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Jim Newton&lt;/p&gt;</description><feedburner:origLink>http://www.cadence.com/Community/blogs/cic/archive/2012/09/10/unfinished-skill-for-the-skilled-many-ways-to-sum-a-list-part-2.aspx</feedburner:origLink></item><item><title>SKILL for the Skilled: Many Ways to Sum a List (Part 1)</title><link>http://feedproxy.google.com/~r/cadence/community/blogs/196313/~3/1urXkut_Zvs/skill-for-the-skilled-many-ways-to-sum-a-list-part-1.aspx</link><pubDate>Wed, 05 Sep 2012 15:38:00 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:1314591</guid><dc:creator>Team SKILL</dc:creator><description>A while back I presented a one day SKILL++ seminar to a group of beginner and advanced SKILL programmers. One example I showed was &lt;i&gt;Variations on how to sum a list of numbers&lt;/i&gt;. This is a good example because the problem itself is easy to understand,&amp;nbsp;so the audience can concentrate on the solution techniques rather than on the problem itself. &lt;p&gt;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. &lt;/p&gt;&lt;b&gt;Summing Straightforward &lt;/b&gt;&lt;p&gt;One straightforward way to sum a given list of numbers is to use simple iteration and mimic a primitive microprocessor.&amp;nbsp;That is,&amp;nbsp;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. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;(defun sumlist_1a (numbers)
  (let ((sum 0))
    (foreach number numbers
      sum = sum + number)
    sum))
&lt;/pre&gt;&lt;p&gt;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. &lt;/p&gt;&lt;b&gt;Summing with apply&lt;/b&gt; &lt;p&gt;In SKILL++ (as well as in&amp;nbsp;traditional SKILL) this is not a particularly efficient implementation because the SKILL virtual machine compiler, unlike a native compiler,&amp;nbsp;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. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;(defun sumlist_1b (numbers)
  (apply plus numbers))
&lt;/pre&gt;&lt;p&gt;Remember -- to force this function to be defined as SKILL++ rather than traditional SKILL, you&amp;#39;ll either need to load it from a file with a .ils extension, or you&amp;#39;ll need two wrap the definition in &lt;code&gt;(inScheme ...)&lt;/code&gt; when you copy and paste it into the CIWindow. &lt;/p&gt;&lt;p&gt;A quick test with &lt;code&gt;measureTime&lt;/code&gt; shows that &lt;code&gt;sumlist_1b&lt;/code&gt; is roughly 10 times faster than &lt;code&gt;sumlist_1a&lt;/code&gt; on a 10,000 element list of numbers. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;How does it work?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;plus&lt;/code&gt; function returns the sum in its argument list. For example: &lt;code&gt;(plus 1 2 3 4 5)&lt;/code&gt; evaluates to &lt;code&gt;15&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;The &lt;code&gt;apply&lt;/code&gt; function, when called with two arguments, calls the function designated by its first argument. In particular &lt;code&gt;apply&lt;/code&gt; calls that function argument list given as its second argument. For example: &lt;/p&gt;&lt;pre&gt;(apply plus &amp;#39;(1 2 3 4 5))&lt;/pre&gt;is a call to &lt;code&gt;plus&lt;/code&gt; with two arguments. The first argument &lt;code&gt;plus&lt;/code&gt; is the function which &lt;code&gt;apply&lt;/code&gt; should call. The second argument, &lt;code&gt;&amp;#39;(1 2 3 4 5)&lt;/code&gt; is the list of arguments to call &lt;code&gt;plus&lt;/code&gt; with. Thus this use of &lt;code&gt;apply&lt;/code&gt; is equivalent to the following. &lt;pre&gt;(plus 1 2 3 4 5)&lt;/pre&gt;&lt;p&gt;Note that &lt;code&gt;plus&lt;/code&gt; 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 &lt;code&gt;plus&lt;/code&gt; evaluates to the plus function. &lt;/p&gt;&lt;p&gt;Since &lt;code&gt;sumlist_1b&lt;/code&gt; 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&amp;nbsp;that do not exist with&amp;nbsp;&lt;code&gt;sumlist_1a&lt;/code&gt;. For example, &lt;code&gt;sumlist_1b&lt;/code&gt; cannot sum the elements of the &lt;code&gt;nil&lt;/code&gt; list. The &lt;code&gt;sumlist_1a&lt;/code&gt;, however, claims the sum of the list &lt;code&gt;nil&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;, which indeed sounds like a reasonable answer. Furthermore, &lt;code&gt;sumlist_1a&lt;/code&gt;, claims that the sum of a singleton list such as &lt;code&gt;(3.4)&lt;/code&gt; is the first (and only) element of the list, which again seems like a reasonable result. &lt;/p&gt;&lt;p&gt;&lt;b&gt;Apply in other languages&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Actually the &lt;code&gt;apply&lt;/code&gt; 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 &lt;a href="http://en.wikipedia.org/wiki/Apply"&gt;Wikipedia&lt;/a&gt; finds an article explaining its use in several languages. &lt;/p&gt;&lt;p&gt;&lt;b&gt;More to come&lt;/b&gt;&lt;/p&gt;&lt;p&gt;In the next posting, I&amp;#39;ll show some ways to get the speed and conciseness of &lt;code&gt;sumlist_1b&lt;/code&gt; without the caveats. &lt;/p&gt;&lt;h4&gt;See Also&lt;/h4&gt;&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Apply"&gt;http://en.wikipedia.org/wiki/Apply&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Jim Newton&lt;/p&gt;</description><feedburner:origLink>http://www.cadence.com/Community/blogs/cic/archive/2012/09/05/skill-for-the-skilled-many-ways-to-sum-a-list-part-1.aspx</feedburner:origLink></item><item><title>SKILL for the Skilled: Introduction to Classes -- Part 5</title><link>http://feedproxy.google.com/~r/cadence/community/blogs/196313/~3/AN6P3R8AVNw/u-nder-construction-skill-for-the-skilled-introduction-to-classes-part-5.aspx</link><pubDate>Fri, 10 Feb 2012 14:00:00 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:1305299</guid><dc:creator>Team SKILL</dc:creator><description>&lt;p&gt;In the previous &lt;i&gt;SKILL for the Skilled&lt;/i&gt; postings, we looked at a pretty good algorithm for solving the Sudoku puzzle. This algorithm is able to find at least one solution of the puzzle if one exists, and is able to detect that no solution exists if that is in fact the case. In this article we look at a particularly difficult case which the algorithm we have chosen performs poorly. &lt;/p&gt;&lt;p&gt;&lt;b&gt;What about a difficult puzzle?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;In his article &lt;a href="http://norvig.com/sudoku.html"&gt;Solving Every Sudoku Puzzle&lt;/a&gt;, Peter Norvig suggests a puzzle which is pretty difficult. In fact it is the worse case for the algorithm he proposes in the article. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;Sudoku puzzle 5-1 &lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;(SkuSolve &amp;#39;((? ? ?  ? ? 6  ? ? ?)&lt;br /&gt;            (? 5 9  ? ? ?  ? ? 8)&lt;br /&gt;            (2 ? ?  ? ? 8  ? ? ?)&lt;br /&gt;&lt;br /&gt;            (? 4 5  ? ? ?  ? ? ?)&lt;br /&gt;            (? ? 3  ? ? ?  ? ? ?)&lt;br /&gt;            (? ? 6  ? ? 3  ? 5 4)&lt;br /&gt;&lt;br /&gt;            (? ? ?  3 2 5  ? ? 6)&lt;br /&gt;            (? ? ?  ? ? ?  ? ? ?)&lt;br /&gt;            (? ? ?  ? ? ?  ? ? ?)))&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;The algorithm implemented in &lt;code&gt;SkuFindSolution&lt;/code&gt; does in fact solve this puzzle but considerably slower than the other examples shown above. On the particular machine I&amp;#39;m using, all the puzzles described in the previous posting are solved in less than 1/10 of a second. This problematic puzzle takes more than 25 seconds to solve. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;starting with: &lt;br /&gt;+-----+-----+-----+&lt;br /&gt;| | | | | |6| | | |&lt;br /&gt;| |5|9| | | | | |8|&lt;br /&gt;|2| | | | |8| | | |&lt;br /&gt;| |4|5| | | | | | |&lt;br /&gt;| | |3| | | | | | |&lt;br /&gt;| | |6| | |3| |5|4|&lt;br /&gt;| | | |3|2|5| | |6|&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;+-----+-----+-----+&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;found solution:&lt;br /&gt;+-----+-----+-----+&lt;br /&gt;|8|3|4|9|7|6|5|1|2|&lt;br /&gt;|6|5|9|2|3|1|7|4|8|&lt;br /&gt;|2|7|1|4|5|8|6|9|3|&lt;br /&gt;|1|4|5|8|6|2|3|7|9|&lt;br /&gt;|7|2|3|5|4|9|8|6|1|&lt;br /&gt;|9|8|6|7|1|3|2|5|4|&lt;br /&gt;|4|1|7|3|2|5|9|8|6|&lt;br /&gt;|5|9|2|6|8|4|1|3|7|&lt;br /&gt;|3|6|8|1|9|7|4|2|5|&lt;br /&gt;+-----+-----+-----+&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;A different algorithm&lt;/b&gt; &lt;/p&gt;&lt;p&gt;The version of &lt;code&gt;SkuFindSolution&lt;/code&gt; shown in &lt;i&gt;&lt;a href="https://www.cadence.com:443/Community/blogs/cic/archive/2011/11/14/under-construction-skill-for-the-skilled-introduction-to-classes-part-4.aspx"&gt;SKILL for the Skilled: Part 4&lt;/a&gt;&lt;/i&gt; iterates over the cells in the board simply in the order they appear in the list. The following improved version of &lt;code&gt;SkuFindSolution&lt;/code&gt; first sorts the cells into order of increasing possibility. Cells which have few possibilities are moved to the beginning of the list, and cells with more possibilities are moved to the end of the list. &lt;/p&gt;&lt;p&gt;The changes in the function are to introduce the local function &lt;code&gt;count_possibilities&lt;/code&gt; into the &lt;code&gt;(labels ...)&lt;/code&gt;, &lt;/p&gt;&lt;pre&gt;(count_possibilities (cell)&lt;br /&gt;  (let ((c 0))&lt;br /&gt;    (for i 1 9&lt;br /&gt;      (unless (conflict? i cell)&lt;br /&gt;        c++))&lt;br /&gt;     c))&lt;br /&gt;&lt;/pre&gt;and to insert a call to &lt;code&gt;(sort ... (genCmpFunction...))&lt;/code&gt; &lt;pre&gt;sudoku-&amp;gt;cells = (sort sudoku-&amp;gt;cells&lt;br /&gt;                      (genCmpFunction ?key count_possibilities))&lt;br /&gt;&lt;/pre&gt;before calling &lt;code&gt;solve_cell&lt;/code&gt;. &lt;p&gt;Recall the functions &lt;code&gt;genCmpFunction&lt;/code&gt; and &lt;code&gt;identity&lt;/code&gt; from a previous blog posting. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;(defun genCmpFunction (@key (test lessp)&lt;br /&gt;                            (key  identity))&lt;br /&gt;  (lambda (A B)&lt;br /&gt;    (test (key A)&lt;br /&gt;          (key B))))&lt;br /&gt;&lt;br /&gt;(defun identity (x)&lt;br /&gt;  x)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;genCmpFunction&lt;/code&gt; generates a function which can be used as the second argument of &lt;code&gt;sort&lt;/code&gt;. In this case &lt;code&gt;genCmpFunction&lt;/code&gt; returns a function which will cause &lt;code&gt;sort&lt;/code&gt; to order the cells in increasing order according to the return value of &lt;code&gt;count_possibilities&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;The local function &lt;code&gt;count_possibilities&lt;/code&gt; returns the integer corresponding to how many of the number in the set &lt;code&gt;{1 2 3 4 5 6 7 8 9}&lt;/code&gt; are conflict-free when placed in the given cell. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;New version of SkuFindSolution&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;(defun SkuFindSolution (sudoku)&lt;br /&gt;  (prog ()       &lt;br /&gt;    (labels (&lt;b&gt;(count_possibilities (cell)&lt;br /&gt;               (let ((c 0))&lt;br /&gt;                 (for i 1 9&lt;br /&gt;                   (unless (conflict? i cell)&lt;br /&gt;                     c++))&lt;br /&gt;                 c))&lt;/b&gt;&lt;br /&gt;             (conflict? (solution cell)&lt;br /&gt;               (exists group &amp;#39;(column row b3x3)&lt;br /&gt;                 (exists c (slotValue cell group)-&amp;gt;cells&lt;br /&gt;                   (and (neq c cell)&lt;br /&gt;                        (eqv solution c-&amp;gt;value)))))&lt;br /&gt;             (solve_cells (cells)&lt;br /&gt;               (cond&lt;br /&gt;                 ((null cells)&lt;br /&gt;                  (return sudoku))&lt;br /&gt;                 (((car cells)-&amp;gt;value)&lt;br /&gt;                  (and (not (conflict? (car cells)-&amp;gt;value&lt;br /&gt;                                       (car cells)))&lt;br /&gt;                       (solve_cells (cdr cells))))&lt;br /&gt;                 (t&lt;br /&gt;                  (let ((cell (car cells)))&lt;br /&gt;                    (for solution 1 9&lt;br /&gt;                      (unless (conflict? solution cell)&lt;br /&gt;                        cell-&amp;gt;value = solution&lt;br /&gt;                        (solve_cells (cdr cells))))&lt;br /&gt;                    cell-&amp;gt;value = nil)))))&lt;br /&gt;      &lt;b&gt;&lt;br /&gt;      sudoku-&amp;gt;cells = (sort sudoku-&amp;gt;cells&lt;br /&gt;                            (genCmpFunction ?key count_possibilities))&lt;br /&gt;      &lt;/b&gt;&lt;br /&gt;      (solve_cells sudoku-&amp;gt;cells))))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;What about the performance?&lt;/b&gt;&lt;/p&gt;&lt;p&gt;I ran the new algorithm and the old algorithm on four examples, three from the previous posting 4-1, 4-2, and 4-3, and also on 5-1 above. It turns out that the old algorithm performs 2x to 8x faster than the new for the cases it handles well. In particular, for cases for which the old algorithm solves the puzzle in less than 1/10 of a second, the new algorithm works slower but still solves in less than 1/10 of a second. On the other hand, on the extreme case where old algorithm handles poorly, where the old algorithm requires half a minute to solve the puzzle, the new algorithm is 12x faster. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;Performance Measurements &lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Puzzle&lt;/th&gt;&lt;th&gt;Algorithm 1&lt;br /&gt;(seconds)&lt;/th&gt;&lt;th&gt;Algorithm 2&lt;br /&gt;(seconds)&lt;/th&gt;&lt;th&gt;Comparison&lt;br /&gt;&amp;lt; 1.0 is bad &lt;br /&gt;(&lt;i&gt;More is Better&lt;/i&gt;) &lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4-1&lt;/td&gt;&lt;td&gt;0.0420&lt;/td&gt;&lt;td&gt;0.0669&lt;/td&gt;&lt;td&gt;1 / 1.59 &lt;i&gt;degradation&lt;/i&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4-2&lt;/td&gt;&lt;td&gt;0.0230&lt;/td&gt;&lt;td&gt;0.0830&lt;/td&gt;&lt;td&gt;1 / 3.61 &lt;i&gt;degradation&lt;/i&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4-3&lt;/td&gt;&lt;td&gt;0.0030&lt;/td&gt;&lt;td&gt;0.0220&lt;/td&gt;&lt;td&gt;1 / 7.35 &lt;i&gt;degradation&lt;/i&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5-1&lt;/td&gt;&lt;td&gt;25.22&lt;/td&gt;&lt;td&gt;2.075&lt;/td&gt;&lt;td&gt;12.154 &lt;i&gt;improvement&lt;/i&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;b&gt;Summary&lt;/b&gt; &lt;p&gt;In this series of 5 postings (first&amp;nbsp;four listed below)&amp;nbsp;we&amp;#39;ve used the SKILL++ Object System to implement a sudoku puzzle solver. &lt;/p&gt;&lt;p&gt;I hope you will find the examples in these posting useful. &lt;/p&gt;&lt;p&gt;Jim Newton&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.cadence.com:443/Community/blogs/cic/archive/2011/08/15/skill-for-the-skilled-introduction-to-classes-part-1.aspx"&gt;SKILL for the Skilled: Introduction to Classes - Part 1&lt;/a&gt;&lt;br /&gt;&lt;a href="https://www.cadence.com:443/Community/blogs/cic/archive/2011/09/05/under-construction-skill-for-the-skilled-introduction-to-classes-part-2.aspx"&gt;SKILL for the Skilled: Introduction to Classes - Part 2&lt;/a&gt;&lt;br /&gt;&lt;a href="https://www.cadence.com:443/Community/blogs/cic/archive/2011/10/17/under-construction-skill-for-the-skilled-introduction-to-classes-part-3.aspx"&gt;SKILL for the Skilled: Introduction to Classes - Part 3&lt;/a&gt;&lt;br /&gt;&lt;a href="https://www.cadence.com:443/Community/blogs/cic/archive/2011/11/14/under-construction-skill-for-the-skilled-introduction-to-classes-part-4.aspx"&gt;SKILL for the Skilled: Introduction to Classes - Part 4&lt;/a&gt;&lt;/p&gt;</description><feedburner:origLink>http://www.cadence.com/Community/blogs/cic/archive/2012/02/10/u-nder-construction-skill-for-the-skilled-introduction-to-classes-part-5.aspx</feedburner:origLink></item><item><title>SKILL for the Skilled: Introduction to Classes -- Part 4</title><link>http://feedproxy.google.com/~r/cadence/community/blogs/196313/~3/ObMddrGCl6o/under-construction-skill-for-the-skilled-introduction-to-classes-part-4.aspx</link><pubDate>Mon, 14 Nov 2011 15:00:00 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:1292969</guid><dc:creator>Team SKILL</dc:creator><description> 

In several previous postings we introduced the problem of solving the
sudoku puzzle. 
&lt;ul&gt;&lt;li&gt; In &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2011/08/15/skill-for-the-skilled-introduction-to-classes-part-1.aspx?postID=1292966"&gt;Part 1&lt;/a&gt;, we saw the rules of sudoku and a brief
introduction to the SKILL++ Object System.  

&lt;/li&gt;&lt;li&gt; In &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2011/09/05/under-construction-skill-for-the-skilled-introduction-to-classes-part-2.aspx?postID=1292967"&gt;Part 2&lt;/a&gt;, we started solving the problem top-down by
implementing the top level function &lt;code&gt;SkuSolve&lt;/code&gt; and
agreeing to fill in all the missing pieces incrementally until the
program was complete.  We also saw how to use hierarchical class
definitions to represent the components representing rows, columns and
3x3 blocks.

&lt;/li&gt;&lt;li&gt; In &lt;a href="http://www.cadence.com/Community/blogs/cic/archive/2011/10/17/under-construction-skill-for-the-skilled-introduction-to-classes-part-3.aspx?postID=1292968"&gt;Part 3&lt;/a&gt;, we saw how to create and initialize non-trivial
instances of SKILL++ classes, and used these techniques to initialize
the sudoku board with a given partial solution, ready for solving.

&lt;/li&gt;&lt;li&gt; In this posting, Part 4, we&amp;#39;ll finally show one possible
definition of function &lt;code&gt;SkuFindSolution&lt;/code&gt;.
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;
Just for a reminder, here is the definition of the top level
function, &lt;code&gt;SkuSolve&lt;/code&gt;.
&lt;/p&gt;&lt;pre&gt;(defun SkuSolve (partial_solution)&lt;br /&gt;  (let ((sudoku (SkuInitialize (SkuNew) partial_solution)))&lt;br /&gt;    (printf &amp;quot;starting with: \n%s\n&amp;quot;&lt;br /&gt;            (SkuPrint sudoku))&lt;br /&gt;    (printf &amp;quot;\nfound solution:\n%s\n&amp;quot;&lt;br /&gt;            (SkuPrint (SkuFindSolution sudoku)))))&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;
We have already seen the definitions
of &lt;code&gt;SkuNew&lt;/code&gt;, &lt;code&gt;SkuInitialize&lt;/code&gt;,
and &lt;code&gt;SkuPrint&lt;/code&gt;.  Now we can take a look at the
implementation of
&lt;code&gt;SkuFindSolution&lt;/code&gt;, the function which actually searches for
the sudoku solution.

&lt;/p&gt;&lt;b&gt;Solving the sudoku puzzle&lt;/b&gt;&lt;p&gt;

The function &lt;code&gt;SkuFindSolution&lt;/code&gt; takes an instance of
class &lt;code&gt;SkuSudoku&lt;/code&gt; (created by &lt;code&gt;SkuNew&lt;/code&gt;, and
populated by &lt;code&gt;SkuInitialize&lt;/code&gt;) and modifies it to find a
solution of the sudoku puzzle, &lt;i&gt;assuming one exists&lt;/i&gt;.
&lt;/p&gt;&lt;p&gt;
How does it work? 
&lt;/p&gt;&lt;p&gt;
It basically brute forces its way through the cells in the board,
trying every possibility for each cell, from 1 to 9, which does not
present an immediate &lt;i&gt;conflict&lt;/i&gt;. If no solution exists for a
particular cell (i.e., if each choice from 1 to 9 inflicts a
conflict), the algorithm backtracks and tries a different guess, until
it guesses correctly.
&lt;/p&gt;&lt;p&gt;
The local function &lt;code&gt;conflict?&lt;/code&gt; asks &amp;quot;Does the given digit
already exist in the row, column, or 3x3 block which contains the
cell?&amp;quot;  If not, it is a potentially valid guess.  The local
function &lt;code&gt;solve_cells&lt;/code&gt; takes a list of all the remaining
cells which have not yet been visited.  Each digit that does not create a conflict is tried.  There are three cases in the &lt;code&gt;(cond
...)&lt;/code&gt;:
&lt;/p&gt;&lt;ol&gt;&lt;li&gt; If there are no more cells to consider, then we&amp;#39;re done; we&amp;#39;ve
found a solution!  In this case we don&amp;#39;t return
from &lt;code&gt;solve_cells&lt;/code&gt;, but rather return
from &lt;code&gt;(SkuFindSolution ...)&lt;/code&gt; thanks
to &lt;code&gt;prog/return&lt;/code&gt;.

&lt;/li&gt;&lt;li&gt; If the cell already has a value in it, skip it because it
was &lt;i&gt;given&lt;/i&gt; in the puzzle partial solution.  Note that this
second case refuses to recure if a conflict is found.  This means the
puzzle has no solution, and recursion terminates,
causing &lt;code&gt;SkuFindSolution&lt;/code&gt; to return &lt;code&gt;nil&lt;/code&gt;.

&lt;/li&gt;&lt;li&gt; Otherwise, try all possibilities 1 through 9, skipping conflicts.
If the &lt;code&gt;(for ...)&lt;/code&gt; loop completes, that means we didn&amp;#39;t
find a solution for this cell. This happens if we&amp;#39;ve made an invalid
guess in a previous iteration.  So we set the cell back to the
unsolved state (&lt;code&gt;nil&lt;/code&gt;), and backtrack.
&lt;/li&gt;&lt;/ol&gt;

&lt;pre&gt;(defun SkuFindSolution (partial)&lt;br /&gt;  (prog ()&lt;br /&gt;    (labels ((conflict? (digit cell)&lt;br /&gt;               (exists group &amp;#39;(column row b3x3)&lt;br /&gt;                 (exists c (slotValue cell group)-&amp;gt;cells&lt;br /&gt;                   (and (neq c cell)&lt;br /&gt;                        (eqv digit c-&amp;gt;value)))))&lt;br /&gt;             (solve_cells (cells)&lt;br /&gt;               (cond&lt;br /&gt;                 ((null cells)&lt;br /&gt;                  (return sudoku))&lt;br /&gt;                 (((car cells)-&amp;gt;value)&lt;br /&gt;                   (and (not (conflict? (car cells)-&amp;gt;value&lt;br /&gt;                                        (car cells)))&lt;br /&gt;                        (solve_cells (cdr cells))))&lt;br /&gt;                 (t&lt;br /&gt;                  (let ((cell (car cells)))&lt;br /&gt;                    (for solution 1 9&lt;br /&gt;                      (unless (conflict? solution cell)&lt;br /&gt;                        cell-&amp;gt;value = solution&lt;br /&gt;                        (solve_cells (cdr cells))))&lt;br /&gt;                    cell-&amp;gt;value = nil)))))&lt;br /&gt;      (solve_cells sudoku-&amp;gt;cells))))&lt;br /&gt;&lt;/pre&gt;

&lt;b&gt;Testing the program&lt;/b&gt;
&lt;p&gt;
Now you can test the program by copying the following into the CIWindow which
comes from the &lt;a href="http://en.wikipedia.org/wiki/Sudoku"&gt;Sudoku
Wikipedia entry&lt;/a&gt;.

&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table&gt;
&lt;tr&gt;&lt;th&gt; Sudoku puzzle 4-1
&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;pre&gt;(SkuSolve &amp;#39;((5 3 ?  ? 7 ?  ? ? ?)&lt;br /&gt;            (6 ? ?  1 9 5  ? ? ?)&lt;br /&gt;            (? 9 8  ? ? ?  ? 6 ?)&lt;br /&gt;&lt;br /&gt;            (8 ? ?  ? 6 ?  ? ? 3)&lt;br /&gt;            (4 ? ?  8 ? 3  ? ? 1)&lt;br /&gt;            (7 ? ?  ? 2 ?  ? ? 6)&lt;br /&gt;&lt;br /&gt;            (? 6 ?  ? ? ?  2 8 ?)&lt;br /&gt;            (? ? ?  4 1 9  ? ? 5)&lt;br /&gt;            (? ? ?  ? 8 ?  ? 7 9)))&lt;br /&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;
You should get the following result if you entered the code correctly.
&lt;/p&gt;&lt;pre&gt;starting with: &lt;br /&gt;+-----------------+&lt;br /&gt;|5|3| | |7| | | | |&lt;br /&gt;|6| | |1|9|5| | | |&lt;br /&gt;| |9|8| | | | |6| |&lt;br /&gt;|8| | | |6| | | |3|&lt;br /&gt;|4| | |8| |3| | |1|&lt;br /&gt;|7| | | |2| | | |6|&lt;br /&gt;| |6| | | | |2|8| |&lt;br /&gt;| | | |4|1|9| | |5|&lt;br /&gt;| | | | |8| | |7|9|&lt;br /&gt;+-----------------+&lt;br /&gt;&lt;br /&gt;found solution:&lt;br /&gt;+-----------------+&lt;br /&gt;|5|3|4|6|7|8|9|1|2|&lt;br /&gt;|6|7|2|1|9|5|3|4|8|&lt;br /&gt;|1|9|8|3|4|2|5|6|7|&lt;br /&gt;|8|5|9|7|6|1|4|2|3|&lt;br /&gt;|4|2|6|8|5|3|7|9|1|&lt;br /&gt;|7|1|3|9|2|4|8|5|6|&lt;br /&gt;|9|6|1|5|3|7|2|8|4|&lt;br /&gt;|2|8|7|4|1|9|6|3|5|&lt;br /&gt;|3|4|5|2|8|6|1|7|9|&lt;br /&gt;+-----------------+&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;If you notice, this algorithm only finds one solution of the sudoku
puzzle.  In some cases there are multiple solutions, but this
algorithm won&amp;#39;t find them.  For example, the empty puzzle has lots of
solutions.
&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table&gt;
&lt;tr&gt;&lt;th&gt; Sudoku puzzle 4-2
&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;pre&gt;(SkuSolve &amp;#39;((? ? ? ? ? ? ? ? ?)&lt;br /&gt;            (? ? ? ? ? ? ? ? ?)&lt;br /&gt;            (? ? ? ? ? ? ? ? ?)&lt;br /&gt;&lt;br /&gt;            (? ? ? ? ? ? ? ? ?)&lt;br /&gt;            (? ? ? ? ? ? ? ? ?)&lt;br /&gt;            (? ? ? ? ? ? ? ? ?)&lt;br /&gt;&lt;br /&gt;            (? ? ? ? ? ? ? ? ?)&lt;br /&gt;            (? ? ? ? ? ? ? ? ?)&lt;br /&gt;            (? ? ? ? ? ? ? ? ?)))&lt;br /&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;starting with: &lt;br /&gt;+-----------------+&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;| | | | | | | | | |&lt;br /&gt;+-----------------+&lt;br /&gt;&lt;br /&gt;found solution:&lt;br /&gt;+-----------------+&lt;br /&gt;|9|7|8|5|3|1|6|4|2|&lt;br /&gt;|6|4|2|9|7|8|5|3|1|&lt;br /&gt;|5|3|1|6|4|2|9|7|8|&lt;br /&gt;|8|9|7|2|1|4|3|6|5|&lt;br /&gt;|3|6|5|8|9|7|2|1|4|&lt;br /&gt;|2|1|4|3|6|5|8|9|7|&lt;br /&gt;|7|8|9|1|2|3|4|5|6|&lt;br /&gt;|4|5|6|7|8|9|1|2|3|&lt;br /&gt;|1|2|3|4|5|6|7|8|9|&lt;br /&gt;+-----------------+&lt;br /&gt;&lt;/pre&gt;
&lt;b&gt;What if there is no solution?&lt;/b&gt;&lt;p&gt;

The &lt;code&gt;SkuSolve&lt;/code&gt; function is good at detecting that no
solution exists for a particular puzzle.
&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table&gt;
&lt;tr&gt;&lt;th&gt; Sudoku puzzle 4-3
&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;pre&gt;(SkuSolve &amp;#39;((5 3 4  6 7 8  9 1 2)&lt;br /&gt;            (6 7 2  1 9 5  3 4 8)&lt;br /&gt;            (1 9 8  3 4 2  5 6 7)&lt;br /&gt;&lt;br /&gt;            (8 5 9  7 6 1  4 2 3)&lt;br /&gt;            (4 2 6  8 5 3  7 9 1)&lt;br /&gt;            (7 1 3  9 2 4  8 5 6)&lt;br /&gt;&lt;br /&gt;            (9 6 ?  5 3 7  2 8 4)&lt;br /&gt;            (1 8 7  4 1 9  6 3 5)&lt;br /&gt;            (? ? 5  2 8 6  1 7 9)))&lt;br /&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;starting with: &lt;br /&gt;+-----+-----+-----+&lt;br /&gt;|5|3|4|6|7|8|9|1|2|&lt;br /&gt;|6|7|2|1|9|5|3|4|8|&lt;br /&gt;|1|9|8|3|4|2|5|6|7|&lt;br /&gt;|8|5|9|7|6|1|4|2|3|&lt;br /&gt;|4|2|6|8|5|3|7|9|1|&lt;br /&gt;|7|1|3|9|2|4|8|5|6|&lt;br /&gt;|9|6| |5|3|7|2|8|4|&lt;br /&gt;|1|8|7|4|1|9|6|3|5|&lt;br /&gt;| | |5|2|8|6|1|7|9|&lt;br /&gt;+-----+-----+-----+&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;no solution&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;b&gt;Summary&lt;/b&gt;&lt;p&gt;

In this posting, we have seen a fairly straightforward approach to
solving the sudoku puzzle.  The solution algorithm is pretty easy
because the data structures representing the structure of the board
make it easy to ask the questions we need to ask, such as:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Is there a conflict putting a digit into a cell?
&lt;/li&gt;&lt;li&gt;Which row, column, and 3x3 block is a given cell in?
&lt;/li&gt;&lt;li&gt;Is a given cell pending resolution?
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;
The particular implementation of &lt;code&gt;SkuFindSolution&lt;/code&gt; also
shows an example of how to use SKILL++ local functions.  This usage
avoids polluting the global function space.


&lt;/p&gt;&lt;b&gt;Preview&lt;/b&gt;&lt;p&gt; In the next posting of &lt;i&gt;SKILL for the Skilled&lt;/i&gt;
we&amp;#39;ll take a look at some shortcomings of this algorithm, particularly in regard to performance.

&lt;/p&gt;&lt;p&gt;Jim Newton &lt;/p&gt;</description><feedburner:origLink>http://www.cadence.com/Community/blogs/cic/archive/2011/11/14/under-construction-skill-for-the-skilled-introduction-to-classes-part-4.aspx</feedburner:origLink></item></channel></rss>
