Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

C/C++

The Power of LISP for C Programmers


List Procedures

Listing Three shows the push procedure we use to add an item to the head of a list. The item to be added is defined as a generic POINTER that points to void. push uses cons to allocate a new CONS and set its car and cdr cells. push also updates the LIST variable so that it now points to the correct CONS at the head of the list. The LIST variable is passed to push by reference -- a POINTER to the LIST variable is passed so push can update it. Finally, push returns a POINTER to the head of the list as a convenience to the caller.

cons returns a POINTER to a CONS, but where did it get the CONS? In a LISP implementation, CONS are managed as an allocated-memory resource. At initialization, they are collected together and put on a list called the "free list." Since LISP uses CONS liberally, they must be managed efficiently. In addition, CONS are frequently used to make temporary copies of lists that may or may not be used. As a result, a method or recovering unused CONS and storing them on the free list becomes necessary. We'll use malloc for the necessary memory to hold a CONS. We'll let the system clean up after us by restoring all dynamically allocated memory after exiting.

cons uses malloc and checks to see whether it granted our request. Since there is always a chance malloc cannot allocate memory, we must account for this possibility. Again, production code should have better diagnostics for such error conditions.

pop is the opposite of push: it removes an item from a list. pop removes the first CONS from the list, retrieving its car cell and then releasing the CONS. pop, like push, must be passed a POINTER to a list rather than the LIST variable itself. That's because pop needs to modify the LIST variable to point to the second item in the list. pop uses procedure cpop to retrieve the first CONS and modify the LIST variable. cpop is very useful for walking through a list without releasing the CONS structures that make up the list. We use cpop in several places in our program.

outputlist is a procedure that iteratively removes each item from the list and sends it to the output stream (stdout in our case). However, outputlist makes a copy of the LIST variable and leaves the original list intact. outputlist is not a general list procedure, as it makes assumptions about each item in the list (it assumes each item is a string). Generic functions in LISP will send the printed representation of an argument to the output stream regardless of the argument type.

These functions depend on a more elaborate strategy for data structure than we'll be using here. We'll have to accept the fact that our output function only works for lists of strings. outputlist uses the library procedure fputs, which outputs a string. outputlist takes a LIST as its first argument. We supply this argument by using the sort procedure, which returns a LIST. Syntactically, the fact that sort returns a POINTER to the sorted list is convenient for calling out putlist.

LISP functions always return something. We follow this convention here even in our outputlist procedure, allowing us to use constructs such as:

outputlist 
(sort(outputlist(item,&1st), compare))))

Here the innermost procedure, push, returns a list used by the next procedure, outputlist, which in turn returns a list used by sort, which returns a list used by the outermost outputlist. Now one can see why LISP stands for "Lots of Insidious Sets of Parentheses."


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.