If you like parentheses, Scheme may be the utility language you are looking for. Robert explains why.
C Version
main(int argc, char *argv[])
  int i = 0, j = 0, b;
  b = atoi(argv[1]);
  while (i++ < b) {
    i % 2 ? j++ : j-;
  printf("%d\n", j);
Scheme Idioms

Now that I've convinced you that Scheme isn't too expensive, I'd like to introduce you to programming in Scheme. The best reference for this is the “Revised Revised Revised Revised Report on Scheme” (R4RS), the great-great-grandson of the original Scheme language definition. The 1990 IEEE standard for Scheme is number 1178. However, I'll attempt to show the joy of Scheme programming with a few examples.

First, let me explain that Scheme departs from the esthetic norm for computer languages. Quite unlike a C or Fortran program—which is organized as a series of statements, usually one per line—a Scheme program consists of a series of parenthesized lists, “S-expressions” Each S-expression may define a new function or variable, invoke a function, or may simply be a literal data list. That's part of the genius of Scheme: program code and data are virtually indistinguishable. S-expressions can contain other S-expressions (which may contain other S-expressions, etc.). That means that Scheme's equivalent of statements may contain other statements, and that Scheme lists may contain other lists. To truly understand Scheme, you must be comfortable with recursive relationships like that.

Unlike most statement-oriented languages, Scheme has no operators. All actions are handled by functions or special forms, both of which exist superficially as S-expressions. C's “+” operator appears in Scheme as the “+” function. Functions are invoked by placing their names at the beginning of a code S-expression. For example, (+ 2 2) produces the number 4. The S-expression (display (+ 2 2)) prints the number 4 on the standard output. Some other S-expressions:

(define some-variable 12)
(define (some-function argument)
   (display argument))
(- some-variable 1)
(display (* some-variable 2))

Most people new to Scheme dislike the parentheses at first, but grow to enjoy them. Scheme's syntax is more regular than that of state-based languages, more conducive to language-sensitive editing, and easier to manipulate with macros. (Macros are beyond the scope of this article.)

Conditional Expressions

Scheme provides the familiar “if” expression for conditional execution of code. One difference between C's if statement and Scheme's if statement is that the Scheme “if” statement returns a value. In fact, all Scheme statements return a value. This property of Lisp, coupled with the purported inefficiency of Lisp systems, caused some wit to comment, “Lisp programmers know the value of everything and the cost of nothing.”

This function prints an “s” if the number passed to it is not 1.

(define (plural-print-s num)
  (display (if (eq? num 1) "" "s")))

Another conditional statement is the “cond” form; rather than a simple either-or choice, “cond” evaluates each of several tests and executes the corresponding expression of the first one to evaluate to true.

(define (print-type object)
  (cond ((number? object)
         (display "number"))
        ((string? object)
         (display "string"))
        ((list? object)
         (display "list"))
         (display "I don't know that type"))))
Recursion and Iteration

Most C programmers will be familiar with the “for” and “while” iterative loops for repetition. Recursion is a little less-known in the C world. Scheme provides several very powerful methods of repetition in both iterative and recursive forms.

This recursive function prints a list of numbers with each number incremented by one.

(define (print-list+1 arglist)
  (if (pair? arglist)
      (display (+ 1 (car arglist)))
      (print-list+1 (cdr arglist)))))

(car and cdr are functions that return the first element of a list and a list minus its first element, respectively.)

Recognizing that applying an operation to each element of a list is a common operation, Scheme provides the “map” function. Here is the same program written using “map”:

(define (print-list+1 arglist)
  (map (lambda (arg) (display (+ 1 arg)) (newline))

The “lambda” form is similar to a function definition but the resulting function has no name. Although this function may not be called by name, it may be passed to other functions that take functions as arguments (confused yet?). In this case, “map” takes as its first argument a function. It then applies that function to each element of its second argument, which must be a list.

Scheme also provides the “do” loop, which functions almost identically to C's “for” loop.


One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix