  Search    Advertiser Disclosure
 TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK Specialized Dev Zones Research Center eBook Library .NET Java C++ Web Dev Architecture Database Security Open Source Enterprise Mobile Special Reports 10-Minute Solutions DevXtra Blogs Slideshow       Author Feedback Print Article Comment on this Article # Using Gambit-C Scheme to Create Small, Efficient Native Applications : Page 2

## When you need to build small, native standalone applications, Gambit-C Scheme provides a high-level dynamic language with good runtime and memory performance, as well as good deployment options.

 by Mark Watson
 Sep 12, 2009
 Page 2 of 5 #### Lists and Vectors

The program examples for this article use both list and vector data structures. A list is optimized, so performing any of the following three operations is computationally inexpensive:
• Adding an element at the beginning of the list
• Deleting an element in the middle of a list
• Adding an element anywhere in a list

Internally, using linked lists makes these operations inexpensive as well. However, if you want to find the element number N of a list, you need to start at the beginning and then follow N-1 links. Alternatively, vectors are much more efficient than lists for accessing random elements in a sequence (A vector is like an array in other programming languages). However, vectors don't have a good property that makes it faster to insert and delete elements in a list.

Scheme has a special syntax for declaring list and vector literals. Here are some examples:

``````> (define list8 '(1 2 3 "cat" 'dog 6 7 8)) ; define a list
> (car list8)  ; car returns the first item in a list
1
> (cdr list8)  ; cdr returns all but the first element of a list
(2 3 "cat" 'dog 6 7 8)
> (list-ref list8 3) ; list-ref inefficiently finds a list element at the specified index
"cat"
> (define vector5 '#(1 2 3 "cat" 'dog)) ; define a vector
> (vector-ref vector5 2)  ; get the element at index 2 (note that indices are zero based)
3
> (vector-set! vector5 2 2222) ; change the value of the element at index 2
> vector5
#(1 2 2222 "cat" 'dog)
> (define vec (make-vector 10)) ; create another vector with 10 elements
> vec
#(0 0 0 0 0 0 0 0 0 0)
> (vector-set! vec 4 '(1 "a test" 2)) ; an element in a vector can be any Lisp value
> vec
#(0 0 0 0 (1 "a test" 2) 0 0 0 0 0)
>``````

#### Closures

Scheme supports closures. A closure captures the environment as it is when a function is defined. Consider this code example that references a "free variable":
``````>  (define (next-value)
(set! count (+ count 1))
count)
> (next-value)
*** ERROR IN next-value, (console)@84.22 -- Unbound variable: count
1>
> (define count 0)
> (next-value)
1
> (define count 0)
> (next-value)
1
> (next-value)
2
> (next-value)
3
>``````

In the definition of next-value, the variable count is a free variable. The first time I called (next-value) no value was available for count because it had not yet been defined.

#### Recursion

As with most modern programming languages, Scheme functions can call themselves recursively. Here is the famous factorial function that returns a value of 1 if its argument is less than 2. Otherwise, it returns the product of its argument times the value of calling itself with one fewer than its argument's value:
``````> (define (fact n)
(if (< n 2)
1
(* n (fact (- n 1)))))
> (fact 5)
120
>``````

It is normal to use recursion for looping/iteration in Scheme.

#### Macros for Iterating

Most Scheme implementations include macro definitions for two convenient ways to iterate:
1. Over a range of numbers
2. Over the elements in a list

Here is an example:

``````> (dotimes (i 4)
(display i)
(newline))
0
1
2
3
> (dolist (x '("cat" "dog" 3.14159))
(display x)
(newline))
cat
dog
3.14159
>``````

Gambit-C does not supply implementations of these macros, but the sample program proper-names.scm that I discuss later provides implementation examples for both. (This source file is included in the downloadable source code for this article.)

The topic of defining macros is outside the scope of this article.

#### Defining Anonymous Functions

The final lesson in this introduction is demonstrating how to define anonymous functions using lambda:
``````> (define myfunction (lambda (x) (+ x x x)))
> (myfunction 1)
3
> (myfunction 10)
30
> (define func2 myfunction) ; function values are "first class" and can be stored in variables
> (func2 2.5)
7.5
>``````

Scheme uses #t and #f to represent Boolean true and false values:

``````> (equal? 1 1)
#t
> (equal? 1 "cat")
#f
>`````` Author Feedback Email Article Print Article Comment on this Article  